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