]> git.vomp.tv Git - vompclient.git/blob - demuxerts.cc
10 CWFs
[vompclient.git] / demuxerts.cc
1 /*
2     Copyright 2006-2008 Mark Calderbank
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "demuxerts.h"
21 #include "log.h"
22 #include "video.h"
23 #include "vdr.h"
24 #include "audio.h"
25
26 #define PTS_JUMP_MARGIN   10000
27 #define PTS_ALLOWANCE 90000
28
29 // TODO: PTS class to handle wrapping arithmetic & comparisons?
30 static ULLONG PTSDistance(ULLONG pts1, ULLONG pts2)
31 {
32   // Assume pts1, pts2 < 2^33; calculate shortest distance between
33   ULLONG ret = (pts1 > pts2) ? pts1 - pts2 : pts2 - pts1;
34   if (ret > (1LL<<32)) ret = (1LL<<33) - ret;
35   return ret;
36 }
37
38 static ULLONG PTSDifference(ULLONG pts1, ULLONG pts2)
39 {
40   // Assume pts1, pts2 < 2^33; calculate pts1 - pts2
41   if (pts1 > pts2)
42     return pts1 - pts2;
43   else
44     return (1LL<<33) + pts1 - pts2;
45 }
46
47 DemuxerTS::DemuxerTS(int p_vID, int p_aID, int p_subID, int p_tID)
48 {
49   vID = p_vID; vActive = false;
50   aID = p_aID; aActive = false;
51   subID = p_subID; subActive = false;
52   atype = 0;
53   subLength = 0;
54   tID = p_tID;
55   havechannelinfo=false;
56   //doubledframerate=false;
57   framereserve=0;
58
59   pinfo.hassps=false;
60   pinfo.hasaccessunit=false;
61 }
62
63 void DemuxerTS::flush()
64 {
65   partPacket = 0;
66   parsed = false;
67   havechannelinfo=false;
68   Demuxer::flush();
69   vPacket.init(PESTYPE_VID0);
70   switch (atype)
71   {
72   case 1:
73     aPacket.init(PESTYPE_PRIVATE_1, PESTYPE_SUBSTREAM_AC30);
74     break;
75   default:
76   case 0:
77     aPacket.init(PESTYPE_AUD0);
78     break;
79   }
80   subPacket.init(PESTYPE_PRIVATE_1);
81 tPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_TELETEXTMAX);
82
83   vActive = false;
84   aActive = false;
85   subActive = false;
86   subLength = 0;
87   tActive = false;
88  // doubledframerate=false;
89   framereserve=0;
90   pinfo.hassps=false;
91   pinfo.hasaccessunit=false;
92 }
93
94 int DemuxerTS::scan(UCHAR* /*buf*/, int /*len*/)
95 {
96   switch (atype)
97   {
98   case 1:
99     return PESTYPE_PRIVATE_1;
100   default:
101   case 0:
102     return PESTYPE_AUD0;
103   }
104 }
105
106 void DemuxerTS::setVID(int p_vID)
107 {
108   vID = p_vID;
109   vPacket.init(PESTYPE_VID0);
110   vActive = false;
111 }
112
113 void DemuxerTS::setAID(int p_aID, int type, int streamtype, bool slivetv)
114 {
115   aID = p_aID;
116   atype = type;
117   astreamtype = streamtype;
118   livetv=slivetv;
119   switch (atype)
120   {
121   case 1:
122     aPacket.init(PESTYPE_PRIVATE_1, PESTYPE_SUBSTREAM_AC30);
123     setAudioStream(PESTYPE_SUBSTREAM_AC30);
124     break;
125   default:
126   case 0:
127     aPacket.init(PESTYPE_AUD0);
128     setAudioStream(PESTYPE_AUD0);
129     break;
130   }
131   aActive = false;
132 }
133
134 void DemuxerTS::setSubID(int p_subID)
135 {
136   subID = p_subID;
137   subPacket.init(PESTYPE_PRIVATE_1);
138   subActive = false;
139   subLength = 0;
140 }
141
142 void DemuxerTS::setTID(int p_tID)
143 {
144   tID = p_tID;
145   tPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_TELETEXTMAX);
146   tActive = false;
147
148 }
149
150
151
152
153 int DemuxerTS::findPTS(UCHAR* buf, int len, ULLONG* dest)
154 {
155   int scanaid=0;
156
157   while (len >= TS_SIZE)
158   {
159       if (*buf != TS_SIG) {buf++;len--; continue;} 
160
161     //Pattern scanning won't work for ts
162
163       
164       int datalen = TS_SIZE - 4;
165       int pid = ( (buf[1] & 0x1F) << 8 ) | buf[2];
166       UCHAR payload = buf[1] & 0x40;
167       
168       if (buf[3] & 0x20) // Adaptation field is present
169           datalen -= (buf[4] + 1);
170
171       UCHAR* curbuf =buf+ (TS_SIZE - datalen);
172      
173
174       if (payload) {
175           if (pid == 0x00) {//PAT, only take first program number, ignore the rest
176               int pmtpid = (*(curbuf+11)<< 8) | *(curbuf+12);
177               if ((pmtpid >> 13) != 0x07) 
178               {
179                   Log::getInstance()->log("findPTS", Log::DEBUG, "PMTPID=%02x %02x TRAILING 111 not set but %x", *(curbuf+11),*(curbuf+12), (pmtpid >> 13));
180               } 
181               else 
182               {
183                   pmtpid = pmtpid & 0x1FFF; //clear upper 3 bits
184                   PMTPID = pmtpid;
185               }
186           
187           } else if (pid == PMTPID) { //PMT
188               int sectionlength = ((*(curbuf+2) << 8) & 0x0F ) | *(buf+3);
189               //sectionlength += 4; //include header but subtract crc in the end...
190               int p = 13; //skip fixed part of pmt
191               while ( p < sectionlength) {
192                   int streamtype = *(curbuf+p);
193                   p++;
194                   int foundpid = (*(curbuf+p)<< 8) | *(curbuf+p+1);
195                   p += 2; //skip ES Pid
196                   int eslength = ((*(curbuf+p) << 8) & 0x0F ) | *(curbuf+p+1);
197                   p += 2; //skip ES length
198                   if ((foundpid >> 13) != 0x07)
199                   {
200                       Log::getInstance()->log("findPTS", Log::DEBUG, "FOUNDPID=%02x %02x TRAILING 111 not set but %x", *(buf+p),*(buf+p+1), (foundpid >> 13));
201                   }
202                   else 
203                   {
204                       foundpid = foundpid & 0x1FFF; //clear upper 3 bits
205                       //int pos=0; UNUSED?
206                       if (streamtype==3 || streamtype ==4) {
207                           scanaid=foundpid;
208                       }
209                   }
210                   p += eslength; //skip es descriptor
211               }
212           } else if (pid == scanaid) {     
213            //   UINT framelength = ((UINT)curbuf[4] << 8) | curbuf[5];  UNUSED?
214               
215               if ( curbuf[7] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
216               {
217                   *dest = ( (ULLONG)(curbuf[9] & 0x0E) << 29 ) |
218                   ( (ULLONG)(curbuf[10])        << 22 ) |
219                   ( (ULLONG)(curbuf[11] & 0xFE) << 14 ) |
220                   ( (ULLONG)(curbuf[12])        <<  7 ) |
221                   ( (ULLONG)(curbuf[13] & 0xFE) >>  1 );
222                   return 1;
223               }
224           }
225       }
226       len-=TS_SIZE;
227       buf+=TS_SIZE;
228   }
229   // No PTS found.
230   return 0;
231 }
232
233 void DemuxerTS::setFrameNum(ULONG frame)
234 {
235   frameCounting = true;
236   frameNumber = frame;
237   framereserve=0;
238   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "setFrameNum %d", frame);
239 }
240
241 void DemuxerTS::setPacketNum(ULONG npacket)
242 {
243   packetCounting = true;
244   packetNumber = npacket;
245   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "setPacketNum %d", npacket);
246 }
247
248 int DemuxerTS::put(UCHAR* buf, int len)
249 {
250   int ret = 0;    // return number of bytes consumed
251
252   bool misaligned_mess=false;
253   while (partPacket)
254   {
255     if (len >= TS_SIZE + 1 - partPacket)
256     { // Remainder of partial packet is available, plus one
257       memcpy(store+partPacket, buf, TS_SIZE - partPacket);
258       ret += TS_SIZE - partPacket;
259       buf += TS_SIZE - partPacket;
260       len -= TS_SIZE - partPacket;
261       partPacket = TS_SIZE;
262       if (*buf == TS_SIG)
263       { // Packet is properly terminated
264         int rc = processTS(store);
265         if (rc)
266           partPacket = 0; // Successfully processed
267         else
268           return ret;     // Try again later.
269       }
270       else
271       { // Packet not terminated. Find another candidate, and shift store
272         if (!misaligned_mess) {
273                 Log::getInstance()->log("TS Demuxer", Log::ERR, "TS Misaligned!A");
274                 misaligned_mess=true; // do not alarm more than once
275         }
276         int search = 1;
277         while (search < partPacket && store[search] != TS_SIG)
278           search++;
279         partPacket -= search;
280         if (partPacket) memcpy(store, store+search, partPacket);
281       }
282     }
283     else
284     { // Still don't have complete packet. Consume what we do have.
285       memcpy(store+partPacket, buf, len);
286       partPacket += len;
287       ret += len;
288       return ret;
289     }
290   }
291
292   // Position ourselves at a candidate TS packet
293   while (len > 0 && *buf != TS_SIG)
294   {
295           if (!misaligned_mess) {
296                   Log::getInstance()->log("TS Demuxer", Log::ERR, "TS Misaligned!B");
297               misaligned_mess=true; // do not alarm more than once
298            }
299     buf++; ret++; len--;
300   }
301
302   while (len)
303   {
304     if (len < TS_SIZE + 1)
305     { // Not enough data. Store what we have.
306       memcpy(store, buf, len);
307       partPacket = len;
308       ret += len;
309       return ret;
310     }
311
312     if (buf[TS_SIZE] != TS_SIG)
313     { // Not terminated correctly.
314       buf++; ret++; len--;
315       while (len > 0 && *buf != TS_SIG)
316       {
317         buf++; ret++; len--;
318       }
319     }
320     else
321     {
322       int rc = processTS(buf);
323       if (rc)
324       { // Successfully processed
325         buf += TS_SIZE; ret += TS_SIZE; len -= TS_SIZE;
326       }
327       else
328       { // Processing failed.
329         return ret;
330       }
331     }
332   }
333   return ret;
334 }
335
336
337 int DemuxerTS::processTS(UCHAR* buf)
338 {
339   int datalen = TS_SIZE - 4;
340
341   int pid = ( (buf[1] & 0x1F) << 8 ) | buf[2];
342   UCHAR payload = buf[1] & 0x40;
343
344
345   if (buf[3] & 0x20) // Adaptation field is present
346     datalen -= (buf[4] + 1);
347   if (datalen < 0) // Error in stream TODO log this
348     return 1;
349   if (datalen == 0) // Null packet
350     return 1;
351  // if (!(buf[3] &0x10)) return 1; // no payload
352   buf += (TS_SIZE - datalen);
353
354   if (payload)
355   {
356       int rc = 1;
357       if (pid == 0x00) {//PAT, only take first program number, ignore the rest
358           int pmtpid = (*(buf+11)<< 8) | *(buf+12);
359           if ((pmtpid >> 13) != 0x07) 
360           {
361               Log::getInstance()->log("ProcessTS", Log::DEBUG, "PMTPID=%02x %02x TRAILING 111 not set but %x", *(buf+11),*(buf+12), (pmtpid >> 13));
362           } 
363           else 
364           {
365               pmtpid = pmtpid & 0x1FFF; //clear upper 3 bits
366               PMTPID = pmtpid;
367           }
368             return 1;
369     }
370     if (pid == PMTPID) 
371     { //PMT
372         int sectionlength = ((*(buf+2) << 8) & 0x0F ) | *(buf+3);
373         //sectionlength += 4; //include header but subtract crc in the end...
374         int p = 13; //skip fixed part of pmt
375         Channel new_channelinfo;
376         new_channelinfo.numAPids=0;
377         new_channelinfo.numDPids=0;
378         new_channelinfo.numSPids=0;
379         new_channelinfo.number=0;
380         new_channelinfo.type=VDR::RADIO;
381         new_channelinfo.name=NULL;
382         new_channelinfo.tpid=0xFFFFF; //unused, check this
383         new_channelinfo.vpid=0xFFFFF; //unused, check this
384         new_channelinfo.index=0;
385
386         new_channelinfo.apids.clear();
387         new_channelinfo.dpids.clear();
388         new_channelinfo.spids.clear();
389         
390         while ( p < sectionlength) {
391             int streamtype = *(buf+p);
392             p++;
393             int foundpid = (*(buf+p)<< 8) | *(buf+p+1);
394             p += 2; //skip ES Pid
395             int eslength = ((*(buf+p) << 8) & 0x0F ) | *(buf+p+1);
396             p += 2; //skip ES length
397             if ((foundpid >> 13) != 0x07)
398             {
399               Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDPID=%02x %02x TRAILING 111 not set but %x", *(buf+p),*(buf+p+1), (foundpid >> 13));
400             }
401             else 
402             {
403                 foundpid = foundpid & 0x1FFF; //clear upper 3 bits
404                 bool notfound=false;
405                 bool nolang=true;
406                 int pos=0;
407            // Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDPID is %x %x", foundpid,streamtype);
408                 switch (streamtype)
409                 {
410                 case 0x1B: //MPEG 4 for future use
411                 case 1:
412                 case 2: { //video
413                     if (foundpid != getVID())   
414                         setVID(foundpid);
415                     new_channelinfo.type=VDR::VIDEO;
416                                         new_channelinfo.vstreamtype=streamtype;
417                     new_channelinfo.vpid=foundpid;
418                                         if (streamtype==0x1b) h264=true;
419                                         else h264=false;
420
421                 //  Log::getInstance()->log("ProcessTS", Log::DEBUG, "Set video PID to %x", foundpid);
422                         }break;
423                 case 0x0F: //AAC ADTS packaging
424                 case 0x11: // LATM packaging
425                 case 3:
426                 case 4: { //audio
427                     apid newapid;
428                     newapid.pid = foundpid;
429                     newapid.desc[0]=0;
430                     newapid.type=streamtype;
431                     pos=0;
432                     nolang=true;
433                     while (pos< eslength && nolang) {
434                         switch (buf[p+pos]) {
435                         case 0x0A: {
436                                 newapid.desc[0]=buf[p+pos+2];
437                                 newapid.desc[1]=buf[p+pos+3];
438                                 newapid.desc[2]=buf[p+pos+4];
439                                 newapid.desc[3]=0;
440                                 nolang=false;
441                     //          Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDLANG is %s", newapid.desc);
442                         } break;
443                         };
444
445                         pos+=2+buf[p+pos+1];
446                     }
447
448                     new_channelinfo.apids.push_back(newapid);
449                     new_channelinfo.numAPids++;
450
451                         } break;
452                 case 5:
453                 case 6: { //Private Data 
454                     apid newapid;
455                     newapid.pid = foundpid;
456                     newapid.desc[0]=0; //set it in player
457                     pos=0;
458                     notfound=true;
459                     nolang=true;
460                     int type=0;
461                   
462                     while (pos< eslength && (notfound || nolang)) {
463                         switch (buf[p+pos]) {
464                         case 0x7A: // Enhanced Ac3 Desriptor
465                         case 0x6A: {//Ac3 descriptor 
466                                 newapid.type=buf[p+pos];
467                                 type=1;
468
469                             notfound=false;
470                                    } break; 
471                        case 0x59: {//SubtitlingDescriptor
472                             type=2;
473                             newapid.type=buf[p+pos];
474                             newapid.desc[0]=buf[p+pos+2];
475                             newapid.desc[1]=buf[p+pos+3];
476                             newapid.desc[2]=buf[p+pos+4];
477                             newapid.desc[3]=0;
478                             newapid.data1=(buf[p+pos+5]<<8) |(buf[p+pos+6]);
479                             newapid.data2=(buf[p+pos+7]<<8) |(buf[p+pos+8]);
480                          //   Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDSUB is %s", newapid.desc);
481                             notfound=false;
482                             nolang=false;
483                                    } break;
484                        case 0x0A: {
485                            newapid.desc[0]=buf[p+pos+2];
486                            newapid.desc[1]=buf[p+pos+3];
487                            newapid.desc[2]=buf[p+pos+4];
488                            newapid.desc[3]=0;
489                            nolang=false;
490                          //  Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDLANG is %s", newapid.desc);
491                        } break;
492                        case 0x56: {
493                            type=3;
494                            new_channelinfo.tpid=foundpid;
495                            notfound=false;
496                                   } break;
497                         };
498                         pos+=2+buf[p+pos+1];
499                     }
500                     if (type==1) {
501                         new_channelinfo.dpids.push_back(newapid);
502                         new_channelinfo.numDPids++;
503                     } else if (type==2) {
504                         new_channelinfo.spids.push_back(newapid);
505                         new_channelinfo.numSPids++;
506                     }
507
508                         } break;
509                 default://TODO how about subtitles and second audio pids
510                     break;
511                 }
512                 }
513             
514                  p += eslength; //skip es descriptor
515         
516         
517             }
518
519         bool audioPIDpresent=false; //Check if pids chnages
520         ULONG i;
521         for (i=0;i<channelinfo.numAPids;i++) {
522             if (aID == (int)channelinfo.apids[i].pid) {
523                 audioPIDpresent=true;
524             }
525         }
526         for (i=0;i<channelinfo.numDPids && (! audioPIDpresent);i++) {
527             if (aID == (int)channelinfo.dpids[i].pid) {
528                 audioPIDpresent=true;
529             }
530         }
531         if (! audioPIDpresent || getAID() == 0) {
532
533             bool dolby=false;
534             int selected=-1;
535             int prefered=-1;
536             Command* command = Command::getInstance();
537
538             if (channelinfo.numDPids > 0 && Audio::getInstance()->maysupportAc3())
539             {
540                 ULONG j = 0;
541                 while (j < channelinfo.numDPids)
542                 {
543                         int newpref = command->getLangPref(false, channelinfo.dpids[j].desc);
544                         if (Audio::getInstance()->streamTypeSupported(channelinfo.dpids[j].type)
545                                         && (prefered < 0 || newpref < prefered))
546                         {
547                                 selected = j;
548                                 dolby=true;
549                                 prefered = newpref;
550                         }
551                         j++;
552                 }
553             }
554
555             if (channelinfo.numAPids > 0)
556             {
557                 ULONG j = 0;
558                 while (j < channelinfo.numAPids)
559                 {
560                         int newpref = command->getLangPref(false, channelinfo.apids[j].desc);
561                         if (Audio::getInstance()->streamTypeSupported(channelinfo.apids[j].type)
562                                         && (prefered < 0 || newpref < prefered))
563                         {
564                                 selected = j;
565                                 dolby=false;
566                                 prefered = newpref;
567                         }
568                         j++;
569                 }
570             }
571             if (selected >= 0) {
572                 if (dolby) {
573                         setAID(channelinfo.dpids[selected].pid,1,channelinfo.dpids[selected].type,false);
574                         Audio::getInstance()->setStreamType(Audio::MPEG2_PES);
575                 } else {
576                         setAID(channelinfo.apids[selected].pid,0,channelinfo.apids[selected].type,false);
577                         Audio::getInstance()->setStreamType(Audio::MPEG2_PES);
578                 }
579             }
580
581
582             selected = -1;
583             prefered=-1;
584             if (channelinfo.numSPids) {
585                 ULONG j = 0;
586                 while (j < channelinfo.numSPids)
587                 {
588                         int newpref = command->getLangPref(true, channelinfo.spids[j].desc);
589                         if ( (prefered < 0 || newpref < prefered))
590                         {
591                                 selected = j;
592                                 prefered = newpref;
593                         }
594                         j++;
595                 }
596             }
597
598             if (selected >= 0) {
599                 setSubID(channelinfo.spids[selected].pid);
600
601             }
602         }
603
604         channelinfo=new_channelinfo;
605
606
607         havechannelinfo=true;
608
609          return 1;
610     }
611     
612
613     
614
615     if (pid == vID)
616     {
617       if (vActive)
618       {
619         if (!parsed)
620         {
621           parseTSPacketDetails(vPacket);
622           parsed = true;
623         }
624         rc = submitPacket(vPacket);
625       }
626       vActive = true;
627     }
628     if (pid == aID)
629     {
630       if (aActive)
631       {
632         if (!parsed)
633         {
634           parseTSPacketDetails(aPacket);
635           parsed = true;
636         }
637         rc = submitPacket(aPacket);
638       }
639       aActive = true;
640     }
641     if (pid == subID)
642     {
643       if (subActive)
644       {
645         if (!parsed)
646         {
647           parseTSPacketDetails(subPacket);
648           parsed = true;
649         }
650         rc = submitPacket(subPacket);
651       }
652       subActive = true;
653     }
654     if (isteletextdecoded && pid == tID)
655     {
656       if (tActive)
657       {
658         if (!parsed)
659         {
660           parseTSPacketDetails(tPacket);
661           parsed = true;
662         }
663       rc = submitPacket(tPacket);
664       }
665       tActive = true;
666     }
667     if (rc == 0) return 0;
668
669     parsed = false;
670     if (pid == vID)
671     {
672       vPacket.init(PESTYPE_VID0);
673       buf += 6; datalen -= 6;
674     }
675     if (pid == aID)
676     {
677       switch (atype)
678       {
679       case 1:
680         aPacket.init(PESTYPE_PRIVATE_1, PESTYPE_SUBSTREAM_AC30);
681         break;
682       default:
683       case 0:
684         aPacket.init(PESTYPE_AUD0);
685         break;
686       }
687       buf += 6; datalen -= 6;
688     }
689     if (pid == subID)
690     {
691       subPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_DVBSUBTITLE0);
692       subLength = (buf[4] << 8) + buf[5];
693       buf += 6; datalen -= 6;
694     }
695     if (isteletextdecoded && pid == tID)
696     {
697         tPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_TELETEXTMAX);
698       buf += 6; datalen -= 6;
699     }
700   }
701
702   if ( (pid == vID && vActive) ||
703        (pid == aID && aActive) ||
704        (pid == tID && tActive) ||
705        (pid == subID && subActive) )
706   {
707     PESPacket* packet = NULL;
708     if (pid == vID) packet = &vPacket;
709     if (pid == aID) packet = &aPacket;
710     if (pid == subID) {
711       packet = &subPacket;
712     }
713     if (pid == tID) packet = &tPacket;
714     if (packet != NULL)
715     {
716       if (packet->write(buf, datalen) == 0)
717       { // Writing to packet failed. It has overflowed.
718         if (!parsed)
719         {
720           parseTSPacketDetails(*packet);
721           parsed = true;
722         }
723         if (submitPacket(*packet) == 0) return 0;
724         parsed = false;
725         packet->truncate();
726         packet->write((UCHAR*)"\200\000\000", 3);
727         packet->write(buf, datalen);
728       }
729     }
730   }
731
732   if (pid == subID && subActive && subPacket.getLength() == subLength)
733   {
734     parsePacketDetails(subPacket);
735 //Log::getInstance()->log("DEMUXERTS", Log::DEBUG, "SUBMITTING A SUBTITLE PACKET %d %x", subLength, subPacket.getSubstream());
736     submitPacket(subPacket);
737     subActive = false;
738   }
739
740   return 1;
741 }
742
743 ULONG DemuxerTS::getPacketNum()
744 {
745   return packetNumber;
746 }
747
748 ULONG DemuxerTS::getFrameNumFromPTS(ULLONG pts)
749 {
750   ULLONG difference = (1LL<<33);
751   ULONG ref_frame = 0;
752   int total = 0, actual = 0;
753   if (pts==0) return 0; //we are in startup
754   pts_map_mutex.lock();
755   PTSMap::iterator iter = pts_map.begin();
756   while (iter != pts_map.end())
757   {
758     ++total;
759     //Log::getInstance()->log("DemuxerTS", Log::DEBUG, "getFrameNumfromPTS pts1 %lld pts2 %lld", pts, iter->pts);
760     if (PTSDifference(iter->pts, pts) < PTS_ALLOWANCE)
761     {
762       difference = 0;
763       ref_frame = iter->frame;
764       actual = total;
765       break;
766     }
767     ULLONG newdiff = PTSDifference(pts, iter->pts);
768     if (newdiff < difference)
769     {
770       difference = newdiff;
771       ref_frame = iter->frame;
772       actual = total;
773     }
774     ++iter;
775   }
776   if (total > 1 && actual == 1) // We are using the most recent PTS ref.
777   {                             // Delete the rest.
778     iter = pts_map.begin(); iter++;
779     pts_map.erase(iter, pts_map.end());
780   }
781   pts_map_mutex.unlock();
782   
783  //Log::getInstance()->log("DemuxerTS", Log::DEBUG, "getFrameNumfromPTS pts %lld deleted %d difference %lld", pts, total,difference);
784
785   if (difference == (1LL<<33))
786     return 0; // We cannot make sense of the pts
787   else
788     return ref_frame + difference * fps / 90000;
789 }
790
791
792 void DemuxerTS::parseTSPacketDetails(PESPacket &packet) // Only important stuff for paket counting reminas
793 {
794     parsePacketDetails(packet);
795     if (packetCounting && packet.getPacketType() >= PESTYPE_AUD0 &&
796                         packet.getPacketType() <= PESTYPE_AUDMAX)
797     {
798         packetNumber++;
799     }
800     UINT pictsinpacket=packet.countPictureHeaders(h264,pinfo);
801     
802     UINT numpicts=0;
803   /*  if (!doubledframerate)
804     {*/
805         numpicts=pictsinpacket;
806   /*  }
807     else
808     {
809         numpicts=(pictsinpacket+framereserve)>>1;
810         framereserve=(pictsinpacket+framereserve)%2;
811     }*/
812
813
814   if (frameCounting && numpicts &&
815       packet.getPacketType() >= PESTYPE_VID0 &&
816       packet.getPacketType() <= PESTYPE_VIDMAX)
817   {
818     frameNumber+=numpicts;
819     ULONG frame_num = frameNumber;
820     if ((h264 || packet.findSeqHeader(h264) > 1) && packet.hasPTS())
821     {
822       PTSMapEntry me;
823       pts_map_mutex.lock();
824       if (pts_map.empty())
825       {
826         me.pts = packet.getPTS();
827         me.frame = frame_num;
828         pts_map_mutex.unlock();
829         pts_map_mutex.lock();
830         pts_map.push_front(me);
831       }
832       me = pts_map.front();
833       pts_map_mutex.unlock();
834
835       //UINT fps = Video::getInstance()->getFPS();
836       double tfps=fps;
837      // if (doubledframerate) tfps*=2.;
838       long long pts_expected = me.pts + 90000LL*((long long)(((double)(frame_num - me.frame)) / tfps));
839
840       while (pts_expected < 0) pts_expected += (1LL<<33);
841       while (pts_expected > (1LL<<33)) pts_expected -= (1LL<<33);
842
843       // this was a workaround for a vdr bug, now fixed, for older recordings deleter the index file
844
845       /*
846       if (!doubledframerate 
847           &&(abs((long long)PTSDistance(pts_expected, packet.getPTS())-1800) <= 1 
848           || abs((long long)PTSDistance(pts_expected, packet.getPTS())-1501) <= 1)) {
849               doubledframerate=true; //Detected  p50 or p60
850       }*/
851
852       if (PTSDistance(pts_expected, packet.getPTS()) > PTS_JUMP_MARGIN) // PTS jump!
853       {
854         me.pts = packet.getPTS();
855         me.frame = frame_num;
856         pts_map_mutex.lock();
857         pts_map.push_front(me);
858         pts_map_mutex.unlock();
859       }
860     }
861   }
862 }
863
864
865 bool DemuxerTS::scanForVideo(UCHAR* buf, UINT len, bool &ish264)
866 {
867     int pmtpidy=0;
868
869   while (len >= TS_SIZE)
870   {
871       if (*buf != TS_SIG) {buf++;len--; continue;} 
872
873     //Pattern scanning won't work for ts
874
875       
876       int datalen = TS_SIZE - 4;
877       int pid = ( (buf[1] & 0x1F) << 8 ) | buf[2];
878       UCHAR payload = buf[1] & 0x40;
879       
880       if (buf[3] & 0x20) // Adaptation field is present
881           datalen -= (buf[4] + 1);
882
883       UCHAR* curbuf =buf+ (TS_SIZE - datalen);
884      
885       if (payload) {
886           if (pid == 0x00) {//PAT, only take first program number, ignore the rest
887               int pmtpid = (*(curbuf+11)<< 8) | *(curbuf+12);
888               if ((pmtpid >> 13) != 0x07) 
889               {
890                   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "PMTPID=%02x %02x TRAILING 111 not set but %x", *(curbuf+11),*(curbuf+12), (pmtpid >> 13));
891               } 
892               else 
893               {
894                   pmtpid = pmtpid & 0x1FFF; //clear upper 3 bits
895                   pmtpidy = pmtpid;
896                                   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "PMT pid%02x",pmtpid );
897               }
898           
899           } else if (pid == pmtpidy) { //PMT
900               int sectionlength = ((*(curbuf+2) << 8) & 0x0F ) | *(buf+3);
901               //sectionlength += 4; //include header but subtract crc in the end...
902               int p = 13; //skip fixed part of pmt
903               while ( p < sectionlength) {
904                   int streamtype = *(curbuf+p);
905                   p++;
906                   int foundpid = (*(curbuf+p)<< 8) | *(curbuf+p+1);
907                   p += 2; //skip ES Pid
908                   int eslength = ((*(curbuf+p) << 8) & 0x0F ) | *(curbuf+p+1);
909                   p += 2; //skip ES length
910                   if ((foundpid >> 13) != 0x07)
911                   {
912                       Log::getInstance()->log("DemuxerTS", Log::DEBUG, "FOUNDPID=%02x %02x TRAILING 111 not set but %x", *(buf+p),*(buf+p+1), (foundpid >> 13));
913                   }
914                   else 
915                   {
916                       foundpid = foundpid & 0x1FFF; //clear upper 3 bits
917                    //   int pos=0; UNUSED?
918                                           Log::getInstance()->log("DemuxerTS", Log::DEBUG, "Pid found %02x type %02x",foundpid ,streamtype);
919                       if (streamtype==1 || streamtype ==2) {
920                                                   ish264=false;
921                                                   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "Found Mpeg2 Video");
922                           return true;
923                       }
924                                           if (streamtype==0x1b) {
925                                                   ish264=true;
926                                                   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "Found h264 Video");
927                                                   return true;
928                                           }
929                   }
930                   p += eslength; //skip es descriptor
931               }
932                           ish264=false;
933               return false;
934           } 
935       }
936       len-=TS_SIZE;
937       buf+=TS_SIZE;
938   }
939   ish264=false;
940   return false;
941 }
942
943 UINT DemuxerTS::stripAudio(UCHAR* buf, UINT len) //it has to be adapted
944
945     //This function strips all TS Headers and non video payload
946     UINT readpos=0;
947     UINT writepos=0;
948     PESPacket destpaket;
949     bool started=true;
950     while (readpos < len ) {
951         if (buf[readpos] != TS_SIG) {readpos++; continue;} 
952         UINT oldreadpos=readpos;
953
954         int datalen = TS_SIZE - 4;
955         int pid = ( (buf[readpos+1] & 0x1F) << 8 ) | buf[readpos+2];
956         UCHAR payload = buf[readpos+1] & 0x40;
957         if (buf[readpos+3] & 0x20) { // Adaptation field is present
958            datalen -= (buf[readpos+4] + 1);
959         }
960         if (datalen < 0) {// Error in stream TODO log this
961             return 0;
962         }
963         if (datalen == 0) {// Null packet
964              readpos=oldreadpos+TS_SIZE;
965             continue;
966         }
967         readpos += (TS_SIZE - datalen);
968         UINT towrite=min(datalen,len-readpos);
969         if (pid == vID) {
970             if (payload) {
971                 if (started) {
972                     parsePacketDetails(destpaket);
973                     memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
974                     writepos+=destpaket.getSize();
975                  }
976                  destpaket.init(PESTYPE_VID0);
977                  readpos += 6; towrite -= 6;
978                  started=true;
979             }
980
981             if (started) {
982                 if (!destpaket.write(buf+readpos,towrite)) {
983                     parsePacketDetails(destpaket);
984                     memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
985                     writepos+=destpaket.getSize();
986                     destpaket.truncate();
987                                         destpaket.write((UCHAR*)"\200\000\000", 3);
988                     destpaket.write(buf+readpos,towrite);
989
990                 }
991             }
992             
993        
994
995         }
996         readpos=oldreadpos+TS_SIZE;
997     }
998     parsePacketDetails(destpaket);
999     memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
1000     writepos+=destpaket.getSize();
1001  
1002     return writepos;
1003 }    
1004
1005
1006