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