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