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