store and use previous selected audio pid
[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 #include <lib/dvb_ci/dvbci.h>
7 #include <dvbsi++/ca_program_map_section.h>
8 #include <dvbsi++/descriptor_tag.h>
9 #include <dvbsi++/iso639_language_descriptor.h>
10 #include <dvbsi++/stream_identifier_descriptor.h>
11
12 eDVBServicePMTHandler::eDVBServicePMTHandler(int record)
13         :m_ca_servicePtr(0)
14 {
15         m_record = record;
16         eDVBResourceManager::getInstance(m_resourceManager);
17         CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
18         CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
19         eDebug("new PMT handler record: %d", m_record);
20 }
21
22 eDVBServicePMTHandler::~eDVBServicePMTHandler()
23 {
24         eDebug("delete PMT handler record: %d", m_record);
25         if (m_ca_servicePtr)
26         {
27                 eDebug("unregister caservice");
28                 uint8_t demux_num;
29                 m_demux->getCADemuxID(demux_num);
30                 ePtr<eTable<ProgramMapSection> > ptr;
31                 m_PMT.getCurrent(ptr);
32                 eDVBCAService::unregister_service(m_reference, demux_num, ptr);
33                 eDVBCIInterfaces::getInstance()->removePMTHandler(this);
34         }
35 }
36
37 void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
38 {
39         int state;
40         channel->getState(state);
41         
42         if ((m_last_channel_state != iDVBChannel::state_ok)
43                 && (state == iDVBChannel::state_ok) && (!m_demux))
44         {
45                 if (m_channel)
46                         if (m_channel->getDemux(m_demux, m_record ? 0 : iDVBChannel::capDecode))
47                                 eDebug("Allocating a demux for now tuned-in channel failed.");
48                 
49                 serviceEvent(eventTuned);
50                 
51                 if (m_demux)
52                 {
53                         eDebug("ok ... now we start!!");
54
55                         m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
56
57                         if ( m_service && !m_service->cacheEmpty() )
58                                 serviceEvent(eventNewProgramInfo);
59                 }
60         } else if ((m_last_channel_state != iDVBChannel::state_failed) && 
61                         (state == iDVBChannel::state_failed))
62         {
63                 eDebug("tune failed.");
64                 serviceEvent(eventTuneFailed);
65         }
66 }
67
68 void eDVBServicePMTHandler::PMTready(int error)
69 {
70         if (error)
71                 serviceEvent(eventNoPMT);
72         else
73         {
74                 serviceEvent(eventNewProgramInfo);
75                 if (!m_pvr_channel)
76                 {
77                         if(!m_ca_servicePtr)   // don't send campmt to camd.socket for playbacked services
78                         {
79                                 uint8_t demux_num;
80                                 m_demux->getCADemuxID(demux_num);
81                                 eDVBCAService::register_service(m_reference, demux_num, m_ca_servicePtr);
82                                 eDVBCIInterfaces::getInstance()->addPMTHandler(this);
83                         }
84                         eDVBCIInterfaces::getInstance()->gotPMT(this);
85                 }
86                 if (m_ca_servicePtr)
87                 {
88                         ePtr<eTable<ProgramMapSection> > ptr;
89                         if (!m_PMT.getCurrent(ptr))
90                                 m_ca_servicePtr->buildCAPMT(ptr);
91                         else
92                                 eDebug("eDVBServicePMTHandler cannot call buildCAPMT");
93                 }
94         }
95 }
96
97 void eDVBServicePMTHandler::PATready(int)
98 {
99         eDebug("got PAT");
100         ePtr<eTable<ProgramAssociationSection> > ptr;
101         if (!m_PAT.getCurrent(ptr))
102         {
103                 int pmtpid = -1;
104                 std::vector<ProgramAssociationSection*>::const_iterator i;
105                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
106                 {
107                         const ProgramAssociationSection &pat = **i;
108                         ProgramAssociationConstIterator program;
109                         for (program = pat.getPrograms()->begin(); program != pat.getPrograms()->end(); ++program)
110                                 if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
111                                         pmtpid = (*program)->getProgramMapPid();
112                 }
113                 if (pmtpid == -1)
114                         serviceEvent(eventNoPATEntry);
115                 else
116                         m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux);
117         } else
118                 serviceEvent(eventNoPAT);
119 }
120
121 int eDVBServicePMTHandler::getProgramInfo(struct program &program)
122 {
123         ePtr<eTable<ProgramMapSection> > ptr;
124
125         program.videoStreams.clear();
126         program.audioStreams.clear();
127         program.pcrPid = -1;
128         program.isCrypted = false;
129
130         if (!m_PMT.getCurrent(ptr))
131         {
132                 int cached_apid_ac3 = -1;
133                 int cached_apid_mpeg = -1;
134                 int cached_vpid = -1;
135                 if ( m_service && !m_service->cacheEmpty() )
136                 {
137                         cached_vpid = m_service->getCachePID(eDVBService::cVPID);
138                         cached_apid_mpeg = m_service->getCachePID(eDVBService::cAC3PID);
139                         cached_apid_ac3 = m_service->getCachePID(eDVBService::cAPID);
140                 }
141                 eDVBTableSpec table_spec;
142                 ptr->getSpec(table_spec);
143                 program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1;
144                 std::vector<ProgramMapSection*>::const_iterator i;
145                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
146                 {
147                         const ProgramMapSection &pmt = **i;
148                         program.pcrPid = pmt.getPcrPid();
149                         
150                         ElementaryStreamInfoConstIterator es;
151                         for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
152                         {
153                                 int isaudio = 0, isvideo = 0, cadescriptors = 0;
154                                 videoStream video;
155                                 audioStream audio;
156                                 audio.component_tag=-1;
157                                 video.component_tag=-1;
158
159                                 video.pid = (*es)->getPid();
160                                 audio.pid = (*es)->getPid();
161
162                                 switch ((*es)->getType())
163                                 {
164                                 case 0x01: // MPEG 1 video
165                                 case 0x02: // MPEG 2 video
166                                         isvideo = 1;
167                                         //break; fall through !!!
168                                 case 0x03: // MPEG 1 audio
169                                 case 0x04: // MPEG 2 audio:
170                                         if (!isvideo)
171                                         {
172                                                 isaudio = 1;
173                                                 audio.type = audioStream::atMPEG;
174                                         }
175                                         //break; fall through !!!
176                                 case 0x06: // PES Private
177                                                 /* PES private can contain AC-3, DTS or lots of other stuff.
178                                                    check descriptors to get the exact type. */
179                                         for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
180                                                         desc != (*es)->getDescriptors()->end(); ++desc)
181                                         {
182                                                 switch ((*desc)->getTag())
183                                                 {
184                                                 case AC3_DESCRIPTOR:
185                                                         if (!isvideo)
186                                                         {
187                                                                 isaudio = 1;
188                                                                 audio.type = audioStream::atAC3;
189                                                         }
190                                                         break;
191                                                 case ISO_639_LANGUAGE_DESCRIPTOR:
192                                                         if (!isvideo)
193                                                         {
194                                                                 const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages();
195                                                                         /* use last language code */
196                                                                 for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i)
197                                                                         audio.language_code = (*i)->getIso639LanguageCode();
198                                                         }
199                                                         break;
200                                                 case STREAM_IDENTIFIER_DESCRIPTOR:
201                                                         audio.component_tag =
202                                                                 video.component_tag =
203                                                                         ((StreamIdentifierDescriptor*)*desc)->getComponentTag();
204                                                         break;
205                                                 case CA_DESCRIPTOR:
206                                                         ++cadescriptors;
207                                                         break;
208                                                 }
209                                         }
210                                         break;
211                                 }
212                                 if (isaudio)
213                                 {
214                                         if ( !program.audioStreams.empty() &&
215                                                 ( audio.pid == cached_apid_ac3 || audio.pid == cached_apid_mpeg) )
216                                         {
217                                                 program.audioStreams.push_back(program.audioStreams[0]);
218                                                 program.audioStreams[0] = audio;
219                                         }
220                                         else
221                                                 program.audioStreams.push_back(audio);
222                                 }
223                                 else if (isvideo)
224                                 {
225                                         if ( !program.videoStreams.empty() && video.pid == cached_vpid )
226                                         {
227                                                 program.videoStreams.push_back(program.videoStreams[0]);
228                                                 program.videoStreams[0] = video;
229                                         }
230                                         else
231                                                 program.videoStreams.push_back(video);
232                                 }
233                                 else
234                                         continue;
235                                 if ( cadescriptors > 0 )
236                                         program.isCrypted=true;
237                         }
238                         if ( !program.isCrypted )
239                         {
240                                 for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
241                                         desc != pmt.getDescriptors()->end(); ++desc)
242                                 {
243                                         switch ((*desc)->getTag())
244                                         {
245                                         case CA_DESCRIPTOR:
246                                                 program.isCrypted=true;
247                                                 break;
248                                         }
249                                 }
250                                 break;
251                         }
252                 }
253                 return 0;
254         }
255         else if ( m_service && !m_service->cacheEmpty() )
256         {
257                 int vpid = m_service->getCachePID(eDVBService::cVPID),
258                         apid_ac3 = m_service->getCachePID(eDVBService::cAC3PID),
259                         apid_mpeg = m_service->getCachePID(eDVBService::cAPID),
260                         pcrpid = m_service->getCachePID(eDVBService::cPCRPID),
261                         cnt=0;
262                 if ( vpid != -1 )
263                 {
264                         videoStream s;
265                         s.pid = vpid;
266                         program.videoStreams.push_back(s);
267                         ++cnt;
268                 }
269                 if ( apid_ac3 != -1 )
270                 {
271                         audioStream s;
272                         s.type = audioStream::atAC3;
273                         s.pid = apid_ac3;
274                         program.audioStreams.push_back(s);
275                         ++cnt;
276                 }
277                 if ( apid_mpeg != -1 )
278                 {
279                         audioStream s;
280                         s.type = audioStream::atMPEG;
281                         s.pid = apid_mpeg;
282                         program.audioStreams.push_back(s);
283                         ++cnt;
284                 }
285                 if ( pcrpid != -1 )
286                 {
287                         ++cnt;
288                         program.pcrPid = pcrpid;
289                 }
290                 if ( cnt )
291                         return 0;
292         }
293         return -1;
294 }
295
296 int eDVBServicePMTHandler::getChannel(eUsePtr<iDVBChannel> &channel)
297 {
298         channel = m_channel;
299         if (channel)
300                 return 0;
301         else
302                 return -1;
303 }
304
305 int eDVBServicePMTHandler::getDemux(ePtr<iDVBDemux> &demux)
306 {
307         demux = m_demux;
308         if (demux)
309                 return 0;
310         else
311                 return -1;
312 }
313
314 int eDVBServicePMTHandler::getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel)
315 {
316         pvr_channel = m_pvr_channel;
317         if (pvr_channel)
318                 return 0;
319         else
320                 return -1;
321 }
322
323 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref)
324 {
325         RESULT res;
326         m_reference = ref;
327         
328                 /* is this a normal (non PVR) channel? */
329         if (ref.path.empty())
330         {
331                 eDVBChannelID chid;
332                 ref.getChannelID(chid);
333                 res = m_resourceManager->allocateChannel(chid, m_channel);
334                 eDebug("allocate Channel: res %d", res);
335         } else
336         {
337                 eDVBMetaParser parser;
338                 
339                 if (parser.parseFile(ref.path))
340                         eWarning("no .meta file found, trying original service ref.");
341                 else
342                         m_reference = parser.m_ref;
343                 
344                 eDebug("alloc PVR");
345                         /* allocate PVR */
346                 res = m_resourceManager->allocatePVRChannel(m_pvr_channel);
347                 if (res)
348                         eDebug("allocatePVRChannel failed!\n");
349                 m_channel = m_pvr_channel;
350         }
351         
352         if (m_channel)
353         {
354                 m_channel->connectStateChange(
355                         slot(*this, &eDVBServicePMTHandler::channelStateChanged), 
356                         m_channelStateChanged_connection);
357                 m_last_channel_state = -1;
358                 channelStateChanged(m_channel);
359         } else
360         {
361                 serviceEvent(eventTuneFailed);
362                 return res;
363         }
364
365         if (m_pvr_channel)
366                 m_pvr_channel->playFile(ref.path.c_str());
367
368         ePtr<iDVBChannelList> db;
369         if (!m_resourceManager->getChannelList(db))
370                 db->getService((eServiceReferenceDVB&)m_reference, m_service);
371
372         return res;
373 }
374
375 std::map<eServiceReferenceDVB, eDVBCAService*> eDVBCAService::exist;
376
377 eDVBCAService::eDVBCAService()
378         :m_prev_build_hash(0), m_sendstate(0), m_retryTimer(eApp)
379 {
380         memset(m_used_demux, 0xFF, sizeof(m_used_demux));
381         CONNECT(m_retryTimer.timeout, eDVBCAService::sendCAPMT);
382         Connect();
383 }
384
385 eDVBCAService::~eDVBCAService()
386 {
387         eDebug("[eDVBCAService] free service %s", m_service.toString().c_str());
388         ::close(m_sock);
389 }
390
391 RESULT eDVBCAService::register_service( const eServiceReferenceDVB &ref, int demux_num, eDVBCAService *&caservice )
392 {
393         CAServiceMap::iterator it = exist.find(ref);
394         if ( it != exist.end() )
395                 caservice = it->second;
396         else
397         {
398                 caservice = (exist[ref]=new eDVBCAService());
399                 caservice->m_service = ref;
400                 eDebug("[eDVBCAService] new service %s", ref.toString().c_str() );
401         }
402 // search free demux entry
403         int iter=0, max_demux_slots = sizeof(caservice->m_used_demux);
404
405         while ( iter < max_demux_slots && caservice->m_used_demux[iter] != 0xFF )
406                 ++iter;
407
408         if ( iter < max_demux_slots )
409         {
410                 caservice->m_used_demux[iter] = demux_num & 0xFF;
411                 eDebug("[eDVBCAService] add demux %d to slot %d service %s", demux_num, iter, ref.toString().c_str());
412         }
413         else
414         {
415                 eDebug("[eDVBCAService] no more demux slots free for service %s!!", ref.toString().c_str());
416                 return -1;
417         }
418         return 0;
419 }
420
421 RESULT eDVBCAService::unregister_service( const eServiceReferenceDVB &ref, int demux_num, eTable<ProgramMapSection> *ptr )
422 {
423         CAServiceMap::iterator it = exist.find(ref);
424         if ( it == exist.end() )
425         {
426                 eDebug("[eDVBCAService] try to unregister non registered %s", ref.toString().c_str());
427                 return -1;
428         }
429         else
430         {
431                 eDVBCAService *caservice = it->second;
432                 bool freed = false;
433                 int iter = 0,
434                         used_demux_slots = 0,
435                         max_demux_slots = sizeof(caservice->m_used_demux)/sizeof(int);
436                 while ( iter < max_demux_slots )
437                 {
438                         if ( caservice->m_used_demux[iter] != 0xFF )
439                         {
440                                 if ( !freed && caservice->m_used_demux[iter] == demux_num )
441                                 {
442                                         eDebug("[eDVBCAService] free slot %d demux %d for service %s", iter, caservice->m_used_demux[iter], caservice->m_service.toString().c_str() );
443                                         caservice->m_used_demux[iter] = 0xFF;
444                                         freed=true;
445                                 }
446                                 else
447                                         ++used_demux_slots;
448                         }
449                         ++iter;
450                 }
451                 if (!freed)
452                 {
453                         eDebug("[eDVBCAService] couldn't free demux slot for demux %d", demux_num);
454                         return -1;
455                 }
456                 if (!used_demux_slots)  // no more used.. so we remove it
457                 {
458                         delete it->second;
459                         exist.erase(it);
460                 }
461                 else
462                 {
463                         if (ptr)
464                                 it->second->buildCAPMT(ptr);
465                         else
466                                 eDebug("[eDVBCAService] can not send updated demux info");
467                 }
468         }
469         return 0;
470 }
471
472 void eDVBCAService::Connect()
473 {
474         memset(&m_servaddr, 0, sizeof(struct sockaddr_un));
475         m_servaddr.sun_family = AF_UNIX;
476         strcpy(m_servaddr.sun_path, "/tmp/camd.socket");
477         m_clilen = sizeof(m_servaddr.sun_family) + strlen(m_servaddr.sun_path);
478         m_sock = socket(PF_UNIX, SOCK_STREAM, 0);
479         connect(m_sock, (struct sockaddr *) &m_servaddr, m_clilen);
480         fcntl(m_sock, F_SETFL, O_NONBLOCK);
481         int val=1;
482         setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &val, 4);
483 }
484
485 void eDVBCAService::buildCAPMT(eTable<ProgramMapSection> *ptr)
486 {
487         if (!ptr)
488                 return;
489
490         eDVBTableSpec table_spec;
491         ptr->getSpec(table_spec);
492
493         int pmtpid = table_spec.pid,
494                 pmt_version = table_spec.version;
495
496         uint8_t demux_mask = 0;
497         uint8_t first_demux_num = 0xFF;
498
499 #if 1
500         int iter=0, max_demux_slots = sizeof(m_used_demux);
501         while ( iter < max_demux_slots )
502         {
503                 if ( m_used_demux[iter] != 0xFF )
504                 {
505                         if ( first_demux_num == 0xFF )
506                                 first_demux_num = m_used_demux[iter];
507                         demux_mask |= (1 << m_used_demux[iter]);
508                 }
509                 ++iter;
510         }
511 #else
512         demux_mask = 3;
513         first_demux_num = 0;
514 #endif
515
516         if ( first_demux_num == 0xFF )
517         {
518                 eDebug("[eDVBCAService] no demux found for service %s", m_service.toString().c_str() );
519                 return;
520         }
521
522         eDebug("demux %d mask %02x prevhash %08x", first_demux_num, demux_mask, m_prev_build_hash);
523
524         unsigned int build_hash = (pmtpid << 16);
525         build_hash |= (demux_mask << 8);
526         build_hash |= (pmt_version&0xFF);
527
528         if ( build_hash == m_prev_build_hash )
529         {
530                 eDebug("[eDVBCAService] don't build/send the same CA PMT twice");
531                 return;
532         }
533
534         std::vector<ProgramMapSection*>::const_iterator i=ptr->getSections().begin();
535         if ( i != ptr->getSections().end() )
536         {
537                 CaProgramMapSection capmt(*i++, m_prev_build_hash ? 0x05 /*update*/ : 0x03 /*only*/, 0x01 );
538
539                 while( i != ptr->getSections().end() )
540                 {
541 //                      eDebug("append");
542                         capmt.append(*i++);
543                 }
544
545                 // add our private descriptors to capmt
546                 uint8_t tmp[10];
547
548                 tmp[0]=0x84;  // pmt pid
549                 tmp[1]=0x02;
550                 tmp[2]=pmtpid>>8;
551                 tmp[3]=pmtpid&0xFF;
552                 capmt.injectDescriptor(tmp, false);
553
554                 tmp[0] = 0x82; // demux
555                 tmp[1] = 0x02;
556                 tmp[2] = demux_mask;    // descramble bitmask
557                 tmp[3] = first_demux_num; // read section data from demux number
558                 capmt.injectDescriptor(tmp, false);
559
560                 tmp[0] = 0x81; // dvbnamespace
561                 tmp[1] = 0x08;
562                 tmp[2] = m_service.getDVBNamespace().get()>>24;
563                 tmp[3]=(m_service.getDVBNamespace().get()>>16)&0xFF;
564                 tmp[4]=(m_service.getDVBNamespace().get()>>8)&0xFF;
565                 tmp[5]=m_service.getDVBNamespace().get()&0xFF;
566                 tmp[6]=m_service.getTransportStreamID().get()>>8;
567                 tmp[7]=m_service.getTransportStreamID().get()&0xFF;
568                 tmp[8]=m_service.getOriginalNetworkID().get()>>8;
569                 tmp[9]=m_service.getOriginalNetworkID().get()&0xFF;
570                 capmt.injectDescriptor(tmp, false);
571
572                 capmt.writeToBuffer(m_capmt);
573         }
574
575         m_prev_build_hash = build_hash;
576
577         if ( m_sendstate != 0xFFFFFFFF )
578                 m_sendstate=0;
579         sendCAPMT();
580 }
581
582 void eDVBCAService::sendCAPMT()
583 {
584         if ( m_sendstate && m_sendstate != 0xFFFFFFFF ) // broken pipe retry
585         {
586                 ::close(m_sock);
587                 Connect();
588         }
589
590         int wp=0;
591         if ( m_capmt[3] & 0x80 )
592         {
593                 int i=0;
594                 int lenbytes = m_capmt[3] & ~0x80;
595                 while(i < lenbytes)
596                         wp = (wp << 8) | m_capmt[4 + i++];
597                 wp+=4;
598                 wp+=lenbytes;
599         }
600         else
601         {
602                 wp = m_capmt[3];
603                 wp+=4;
604         }
605
606         if ( write(m_sock, m_capmt, wp) == wp )
607         {
608                 m_sendstate=0xFFFFFFFF;
609                 eDebug("[eDVBCAService] send %d bytes",wp);
610 #if 1
611                 for(int i=0;i<wp;i++)
612                         eDebugNoNewLine("%02x ", m_capmt[i]);
613                 eDebug("");
614 #endif
615         }
616         else
617         {
618                 switch(m_sendstate)
619                 {
620                         case 0xFFFFFFFF:
621                                 ++m_sendstate;
622                                 m_retryTimer.start(0,true);
623 //                              eDebug("[eDVBCAService] send failed .. immediate retry");
624                                 break;
625                         default:
626                                 m_retryTimer.start(5000,true);
627 //                              eDebug("[eDVBCAService] send failed .. retry in 5 sec");
628                                 break;
629                 }
630                 ++m_sendstate;
631         }
632 }