no crc in tdt
[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 #include <lib/dvb/metaparser.h>
6
7 eDVBServicePMTHandler::eDVBServicePMTHandler()
8 {
9         ePtr<eDVBResourceManager> mgr;
10         eDVBResourceManager::getInstance(mgr);
11         m_resourceManager = mgr;
12         CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
13         CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
14 }
15
16 void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
17 {
18         int state;
19         channel->getState(state);
20         
21         if ((m_last_channel_state != iDVBChannel::state_ok)
22                 && (state == iDVBChannel::state_ok) && (!m_demux))
23         {
24                 if (m_channel)
25                         if (m_channel->getDemux(m_demux))
26                                 eDebug("shit it failed.. again.");
27                 
28                 serviceEvent(eventTuned);
29                 
30                 if (m_demux)
31                 {
32                         eDebug("ok ... now we start!!");
33
34                         /* emit */ m_resourceManager->m_channelRunning(channel);
35
36                         m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
37                 }
38         }
39 }
40
41 void eDVBServicePMTHandler::PMTready(int error)
42 {
43         if (error)
44                 serviceEvent(eventNoPMT);
45         else
46                 serviceEvent(eventNewProgramInfo);
47 }
48
49 void eDVBServicePMTHandler::PATready(int)
50 {
51         eDebug("got PAT");
52         ePtr<eTable<ProgramAssociationTable> > ptr;
53         if (!m_PAT.getCurrent(ptr))
54         {
55                 int pmtpid = -1;
56                 ProgramAssociationTableConstIterator i;
57                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
58                 {
59                         const ProgramAssociationTable &pat = **i;
60                         ProgramAssociationConstIterator program;
61                         for (program = pat.getPrograms()->begin(); program != pat.getPrograms()->end(); ++program)
62                                 if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
63                                         pmtpid = (*program)->getProgramMapPid();
64                 }
65                 if (pmtpid == -1)
66                         serviceEvent(eventNoPATEntry);
67                 else
68                         m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux);
69         } else
70                 serviceEvent(eventNoPAT);
71 }
72
73 int eDVBServicePMTHandler::getProgramInfo(struct program &program)
74 {
75         eDebug("got PMT");
76         ePtr<eTable<ProgramMapTable> > ptr;
77         
78         program.videoStreams.clear();
79         program.audioStreams.clear();
80         program.pcrPid = -1;
81         
82         if (!m_PMT.getCurrent(ptr))
83         {
84                 ProgramMapTableConstIterator i;
85                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
86                 {
87                         const ProgramMapTable &pmt = **i;
88                         program.pcrPid = pmt.getPcrPid();
89                         
90                         ElementaryStreamInfoConstIterator es;
91                         for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
92                         {
93                                 int isaudio = 0, isvideo = 0;
94                                 videoStream video;
95                                 audioStream audio;
96                                 
97                                 video.pid = (*es)->getPid();
98                                 audio.pid = (*es)->getPid();
99                                 
100                                 switch ((*es)->getType())
101                                 {
102                                 case 0x01: // MPEG 1 video
103                                 case 0x02: // MPEG 2 video
104                                         isvideo = 1;
105                                         break;
106                                 case 0x03: // MPEG 1 audio
107                                 case 0x04: // MPEG 2 audio:
108                                         isaudio = 1;
109                                         audio.type = audioStream::atMPEG;
110                                         break;
111                                 }
112                                 if (isaudio)
113                                         program.audioStreams.push_back(audio);
114                                 if (isvideo)
115                                         program.videoStreams.push_back(video);
116                         }
117                 }
118                 return 0;
119         } else
120                 return -1;
121 }
122
123 int eDVBServicePMTHandler::getDemux(ePtr<iDVBDemux> &demux)
124 {
125         demux = m_demux;
126         if (demux)
127                 return 0;
128         else
129                 return -1;
130 }
131
132 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref)
133 {
134         RESULT res;
135         m_reference = ref;
136         
137 //      ref.path = "/viva.ts"; // hrhr.
138         
139                 /* is this a normal (non PVR) channel? */
140         if (ref.path.empty())
141         {
142                 eDVBChannelID chid;
143                 ref.getChannelID(chid);
144                 res = m_resourceManager->allocateChannel(chid, m_channel);
145         } else
146         {
147                 eDVBMetaParser parser;
148                 
149                 if (parser.parseFile(ref.path))
150                         eWarning("no .meta file found, trying original service ref.");
151                 else
152                         m_reference = parser.m_ref;
153                 
154                 eDebug("alloc PVR");
155                         /* allocate PVR */
156                 res = m_resourceManager->allocatePVRChannel(m_pvr_channel);
157                 if (res)
158                         eDebug("allocatePVRChannel failed!\n");
159                 m_channel = m_pvr_channel;
160         }
161         
162         if (m_channel)
163         {
164                 m_channel->connectStateChange(
165                         slot(*this, &eDVBServicePMTHandler::channelStateChanged), 
166                         m_channelStateChanged_connection);
167                 m_last_channel_state = -1;
168                 channelStateChanged(m_channel);
169         }
170         
171         if (m_pvr_channel)
172                 m_pvr_channel->playFile(ref.path.c_str());
173         
174         return res;
175 }