- add more python stuff
[enigma2.git] / lib / dvb / pmt.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/dvb/pmt.h>
3 #include <lib/dvb/specs.h>
4 #include <lib/dvb/dvb.h>
5
6 eDVBServicePMTHandler::eDVBServicePMTHandler()
7 {
8         ePtr<eDVBResourceManager> mgr;
9         eDVBResourceManager::getInstance(mgr);
10         m_resourceManager = mgr;
11         CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
12         CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
13 }
14
15 void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
16 {
17         int state;
18         channel->getState(state);
19         
20         if ((m_last_channel_state != iDVBChannel::state_ok)
21                 && (state == iDVBChannel::state_ok) && (!m_demux))
22         {
23                 if (m_channel)
24                         if (m_channel->getDemux(m_demux))
25                                 eDebug("shit it failed.. again.");
26                 
27                 if (m_demux)
28                 {       
29                         eDebug("ok ... now we start!!");
30                         m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
31                 }
32         }
33 }
34
35 void eDVBServicePMTHandler::PMTready(int error)
36 {
37         if (error)
38                 serviceEvent(eventNoPMT);
39         else
40                 serviceEvent(eventNewProgramInfo);
41 }
42
43 void eDVBServicePMTHandler::PATready(int)
44 {
45         ePtr<eTable<ProgramAssociationTable> > ptr;
46         if (!m_PAT.getCurrent(ptr))
47         {
48                 int pmtpid = -1;
49                 ProgramAssociationTableConstIterator i;
50                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
51                 {
52                         const ProgramAssociationTable &pat = **i;
53                         ProgramAssociationConstIterator program;
54                         for (program = pat.getPrograms()->begin(); program != pat.getPrograms()->end(); ++program)
55                                 if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
56                                         pmtpid = (*program)->getProgramMapPid();
57                 }
58                 if (pmtpid == -1)
59                         serviceEvent(eventNoPATEntry);
60                 else
61                         m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux);
62         } else
63                 serviceEvent(eventNoPAT);
64 }
65
66 int eDVBServicePMTHandler::getProgramInfo(struct program &program)
67 {
68         ePtr<eTable<ProgramMapTable> > ptr;
69         
70         program.videoStreams.clear();
71         program.audioStreams.clear();
72         program.pcrPid = -1;
73         
74         if (!m_PMT.getCurrent(ptr))
75         {
76                 ProgramMapTableConstIterator i;
77                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
78                 {
79                         const ProgramMapTable &pmt = **i;
80                         program.pcrPid = pmt.getPcrPid();
81                         
82                         ElementaryStreamInfoConstIterator es;
83                         for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
84                         {
85                                 int isaudio = 0, isvideo = 0;
86                                 videoStream video;
87                                 audioStream audio;
88                                 
89                                 video.pid = (*es)->getPid();
90                                 audio.pid = (*es)->getPid();
91                                 
92                                 switch ((*es)->getType())
93                                 {
94                                 case 0x01: // MPEG 1 video
95                                 case 0x02: // MPEG 2 video
96                                         isvideo = 1;
97                                         break;
98                                 case 0x03: // MPEG 1 audio
99                                 case 0x04: // MPEG 2 audio:
100                                         isaudio = 1;
101                                         audio.type = audioStream::atMPEG;
102                                         break;
103                                 }
104                                 if (isaudio)
105                                         program.audioStreams.push_back(audio);
106                                 if (isvideo)
107                                         program.videoStreams.push_back(video);
108                         }
109                 }
110                 return 0;
111         } else
112                 return -1;
113 }
114
115 int eDVBServicePMTHandler::getDemux(ePtr<iDVBDemux> &demux)
116 {
117         demux = m_demux;
118         if (demux)
119                 return 0;
120         else
121                 return -1;
122 }
123
124 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref)
125 {
126         RESULT res;
127         m_channel = 0;
128         m_channelStateChanged_connection = 0;
129         m_reference = ref;
130         eDVBChannelID chid;
131         ref.getChannelID(chid);
132         res = m_resourceManager->allocateChannel(chid, m_channel);
133         eDebug("eDVBServicePMTHandler: tune %d", res);
134         if (m_channel)
135         {
136                 m_channel->connectStateChange(
137                         slot(*this, &eDVBServicePMTHandler::channelStateChanged), 
138                         m_channelStateChanged_connection);
139                 m_last_channel_state = -1;
140                 channelStateChanged(m_channel);
141         }
142         return res;
143 }