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