]> git.vomp.tv Git - vompclient-marten.git/blob - demuxerts.cc
Fix bug in demuxer widescreen signaling
[vompclient-marten.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                     if (getAID() == 0 && Audio::getInstance()->streamTypeSupported(streamtype)) { //set unset AID to first audio pid that reports itself
452                         setAID(foundpid,0,streamtype,false);
453                         Log::getInstance()->log("ProcessTS", Log::DEBUG, "Set audio PID to %x", foundpid);
454                     }
455                         } break;
456                 case 5:
457                 case 6: { //Private Data 
458                     apid newapid;
459                     newapid.pid = foundpid;
460                     newapid.desc[0]=0; //set it in player
461                     pos=0;
462                     notfound=true;
463                     nolang=true;
464                     int type=0;
465                   
466                     while (pos< eslength && (notfound || nolang)) {
467                         switch (buf[p+pos]) {
468                         case 0x7A: // Enhanced Ac3 Desriptor
469                         case 0x6A: {//Ac3 descriptor 
470                                 newapid.type=buf[p+pos];
471                                 type=1;
472
473                             notfound=false;
474                                    } break; 
475                        case 0x59: {//SubtitlingDescriptor
476                             type=2;
477                             newapid.type=buf[p+pos];
478                             newapid.desc[0]=buf[p+pos+2];
479                             newapid.desc[1]=buf[p+pos+3];
480                             newapid.desc[2]=buf[p+pos+4];
481                             newapid.desc[3]=0;
482                             newapid.data1=(buf[p+pos+5]<<8) |(buf[p+pos+6]);
483                             newapid.data2=(buf[p+pos+7]<<8) |(buf[p+pos+8]);
484                          //   Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDSUB is %s", newapid.desc);
485                             notfound=false;
486                             nolang=false;
487                                    } break;
488                        case 0x0A: {
489                            newapid.desc[0]=buf[p+pos+2];
490                            newapid.desc[1]=buf[p+pos+3];
491                            newapid.desc[2]=buf[p+pos+4];
492                            newapid.desc[3]=0;
493                            nolang=false;
494                          //  Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDLANG is %s", newapid.desc);
495                        } break;
496                        case 0x56: {
497                            type=3;
498                            new_channelinfo.tpid=foundpid;
499                            notfound=false;
500                                   } break;
501                         };
502                         pos+=2+buf[p+pos+1];
503                     }
504                     if (type==1) {
505                         new_channelinfo.dpids.push_back(newapid);
506                         new_channelinfo.numDPids++;
507                     } else if (type==2) {
508                         new_channelinfo.spids.push_back(newapid);
509                         new_channelinfo.numSPids++;
510                     }
511
512                         } break;
513                 default://TODO how about subtitles and second audio pids
514                     break;
515                 }
516                 }
517             
518                  p += eslength; //skip es descriptor
519         
520         
521             }
522         bool audioPIDpresent=false; //Check if pids chnages
523         ULONG i;
524         for (i=0;i<channelinfo.numAPids;i++) {
525             if (aID == (int)channelinfo.apids[i].pid) {
526                 audioPIDpresent=true;
527             }
528         }
529         for (i=0;i<channelinfo.numDPids && (! audioPIDpresent);i++) {
530             if (aID == (int)channelinfo.dpids[i].pid) {
531                 audioPIDpresent=true;
532             }
533         }
534         if (! audioPIDpresent) {
535                 bool found=false;
536             if (channelinfo.numAPids>0) {
537                 int j=0;
538                 while (j<channelinfo.numAPids && !found) {
539                         if (Audio::getInstance()->streamTypeSupported(channelinfo.apids[j].type)) {
540                                 found =true;
541                                 setAID(channelinfo.apids[j].pid,0,channelinfo.apids[j].type,false);
542                         }
543                         j++;
544                 }
545
546             }
547             if (channelinfo.numDPids>0 && !found) {
548                 int j=0;
549                 while (j<channelinfo.numDPids && !found) {
550                         if (Audio::getInstance()->streamTypeSupported(channelinfo.dpids[j].type)) {
551                                 found =true;
552                                 setAID(channelinfo.dpids[j].pid,1,channelinfo.dpids[j].type,false);
553                         }
554                         i++;
555                 }
556             }
557         }
558
559         channelinfo=new_channelinfo;
560
561
562         havechannelinfo=true;
563
564          return 1;
565     }
566     
567
568     
569
570     if (pid == vID)
571     {
572       if (vActive)
573       {
574         if (!parsed)
575         {
576           parseTSPacketDetails(vPacket);
577           parsed = true;
578         }
579         rc = submitPacket(vPacket);
580       }
581       vActive = true;
582     }
583     if (pid == aID)
584     {
585       if (aActive)
586       {
587         if (!parsed)
588         {
589           parseTSPacketDetails(aPacket);
590           parsed = true;
591         }
592         rc = submitPacket(aPacket);
593       }
594       aActive = true;
595     }
596     if (pid == subID)
597     {
598       if (subActive)
599       {
600         if (!parsed)
601         {
602           parseTSPacketDetails(subPacket);
603           parsed = true;
604         }
605         rc = submitPacket(subPacket);
606       }
607       subActive = true;
608     }
609     if (isteletextdecoded && pid == tID)
610     {
611       if (tActive)
612       {
613         if (!parsed)
614         {
615           parseTSPacketDetails(tPacket);
616           parsed = true;
617         }
618       rc = submitPacket(tPacket);
619       }
620       tActive = true;
621     }
622     if (rc == 0) return 0;
623
624     parsed = false;
625     if (pid == vID)
626     {
627       vPacket.init(PESTYPE_VID0);
628       buf += 6; datalen -= 6;
629     }
630     if (pid == aID)
631     {
632       switch (atype)
633       {
634       case 1:
635         aPacket.init(PESTYPE_PRIVATE_1, PESTYPE_SUBSTREAM_AC30);
636         break;
637       default:
638       case 0:
639         aPacket.init(PESTYPE_AUD0);
640         break;
641       }
642       buf += 6; datalen -= 6;
643     }
644     if (pid == subID)
645     {
646       subPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_DVBSUBTITLE0);
647       subLength = (buf[4] << 8) + buf[5];
648       buf += 6; datalen -= 6;
649     }
650     if (isteletextdecoded && pid == tID)
651     {
652         tPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_TELETEXTMAX);
653       buf += 6; datalen -= 6;
654     }
655   }
656
657   if ( (pid == vID && vActive) ||
658        (pid == aID && aActive) ||
659        (pid == tID && tActive) ||
660        (pid == subID && subActive) )
661   {
662     PESPacket* packet = NULL;
663     if (pid == vID) packet = &vPacket;
664     if (pid == aID) packet = &aPacket;
665     if (pid == subID) {
666       packet = &subPacket;
667     }
668     if (pid == tID) packet = &tPacket;
669     if (packet != NULL)
670     {
671       if (packet->write(buf, datalen) == 0)
672       { // Writing to packet failed. It has overflowed.
673         if (!parsed)
674         {
675           parseTSPacketDetails(*packet);
676           parsed = true;
677         }
678         if (submitPacket(*packet) == 0) return 0;
679         parsed = false;
680         packet->truncate();
681         packet->write((UCHAR*)"\200\000\000", 3);
682         packet->write(buf, datalen);
683       }
684     }
685   }
686
687   if (pid == subID && subActive && subPacket.getLength() == subLength)
688   {
689     parsePacketDetails(subPacket);
690 Log::getInstance()->log("DEMUXERTS", Log::DEBUG, "SUBMITTING A SUBTITLE PACKET %d %x", subLength, subPacket.getSubstream());
691     submitPacket(subPacket);
692     subActive = false;
693   }
694
695   return 1;
696 }
697
698 ULONG DemuxerTS::getPacketNum()
699 {
700   return packetNumber;
701 }
702
703 ULONG DemuxerTS::getFrameNumFromPTS(ULLONG pts)
704 {
705   ULLONG difference = (1LL<<33);
706   ULONG ref_frame = 0;
707   int total = 0, actual = 0;
708   if (pts==0) return 0; //we are in startup
709   pts_map_mutex.Lock();
710   PTSMap::iterator iter = pts_map.begin();
711   while (iter != pts_map.end())
712   {
713     ++total;
714     //Log::getInstance()->log("DemuxerTS", Log::DEBUG, "getFrameNumfromPTS pts1 %lld pts2 %lld", pts, iter->pts);
715     if (PTSDifference(iter->pts, pts) < PTS_ALLOWANCE)
716     {
717       difference = 0;
718       ref_frame = iter->frame;
719       actual = total;
720       break;
721     }
722     ULLONG newdiff = PTSDifference(pts, iter->pts);
723     if (newdiff < difference)
724     {
725       difference = newdiff;
726       ref_frame = iter->frame;
727       actual = total;
728     }
729     ++iter;
730   }
731   if (total > 1 && actual == 1) // We are using the most recent PTS ref.
732   {                             // Delete the rest.
733     iter = pts_map.begin(); iter++;
734     pts_map.erase(iter, pts_map.end());
735   }
736   pts_map_mutex.Unlock();
737   
738  //Log::getInstance()->log("DemuxerTS", Log::DEBUG, "getFrameNumfromPTS pts %lld deleted %d difference %lld", pts, total,difference);
739
740   if (difference == (1LL<<33))
741     return 0; // We cannot make sense of the pts
742   else
743     return ref_frame + difference * fps / 90000;
744 }
745
746
747 void DemuxerTS::parseTSPacketDetails(PESPacket &packet) // Only important stuff for paket counting reminas
748 {
749     parsePacketDetails(packet);
750     if (packetCounting && packet.getPacketType() >= PESTYPE_AUD0 &&
751                         packet.getPacketType() <= PESTYPE_AUDMAX)
752     {
753         packetNumber++;
754     }
755     UINT pictsinpacket=packet.countPictureHeaders(h264,pinfo);
756     
757     UINT numpicts=0;
758   /*  if (!doubledframerate)
759     {*/
760         numpicts=pictsinpacket;
761   /*  }
762     else
763     {
764         numpicts=(pictsinpacket+framereserve)>>1;
765         framereserve=(pictsinpacket+framereserve)%2;
766     }*/
767
768
769   if (frameCounting && numpicts &&
770       packet.getPacketType() >= PESTYPE_VID0 &&
771       packet.getPacketType() <= PESTYPE_VIDMAX)
772   {
773     frameNumber+=numpicts;
774     ULONG frame_num = frameNumber;
775     if ((h264 || packet.findSeqHeader(h264) > 1) && packet.hasPTS())
776     {
777       PTSMapEntry me;
778       pts_map_mutex.Lock();
779       if (pts_map.empty())
780       {
781         me.pts = packet.getPTS();
782         me.frame = frame_num;
783         pts_map_mutex.Unlock();
784         pts_map_mutex.Lock();
785         pts_map.push_front(me);
786       }
787       me = pts_map.front();
788       pts_map_mutex.Unlock();
789
790       //UINT fps = Video::getInstance()->getFPS();
791       double tfps=fps;
792      // if (doubledframerate) tfps*=2.;
793       long long pts_expected = me.pts + 90000LL*((long long)(((double)(frame_num - me.frame)) / tfps));
794
795       while (pts_expected < 0) pts_expected += (1LL<<33);
796       while (pts_expected > (1LL<<33)) pts_expected -= (1LL<<33);
797
798       // this was a workaround for a vdr bug, now fixed, for older recordings deleter the index file
799
800       /*
801       if (!doubledframerate 
802           &&(abs((long long)PTSDistance(pts_expected, packet.getPTS())-1800) <= 1 
803           || abs((long long)PTSDistance(pts_expected, packet.getPTS())-1501) <= 1)) {
804               doubledframerate=true; //Detected  p50 or p60
805       }*/
806
807       if (PTSDistance(pts_expected, packet.getPTS()) > PTS_JUMP_MARGIN) // PTS jump!
808       {
809         me.pts = packet.getPTS();
810         me.frame = frame_num;
811         pts_map_mutex.Lock();
812         pts_map.push_front(me);
813         pts_map_mutex.Unlock();
814       }
815     }
816   }
817 }
818
819
820 bool DemuxerTS::scanForVideo(UCHAR* buf, UINT len, bool &ish264)
821 {
822     int pmtpidy=0;
823
824   while (len >= TS_SIZE)
825   {
826       if (*buf != TS_SIG) {buf++;len--; continue;} 
827
828     //Pattern scanning won't work for ts
829
830       
831       int datalen = TS_SIZE - 4;
832       int pid = ( (buf[1] & 0x1F) << 8 ) | buf[2];
833       UCHAR payload = buf[1] & 0x40;
834       
835       if (buf[3] & 0x20) // Adaptation field is present
836           datalen -= (buf[4] + 1);
837
838       UCHAR* curbuf =buf+ (TS_SIZE - datalen);
839      
840       if (payload) {
841           if (pid == 0x00) {//PAT, only take first program number, ignore the rest
842               int pmtpid = (*(curbuf+11)<< 8) | *(curbuf+12);
843               if ((pmtpid >> 13) != 0x07) 
844               {
845                   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "PMTPID=%02x %02x TRAILING 111 not set but %x", *(curbuf+11),*(curbuf+12), (pmtpid >> 13));
846               } 
847               else 
848               {
849                   pmtpid = pmtpid & 0x1FFF; //clear upper 3 bits
850                   pmtpidy = pmtpid;
851                                   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "PMT pid%02x",pmtpid );
852               }
853           
854           } else if (pid == pmtpidy) { //PMT
855               int sectionlength = ((*(curbuf+2) << 8) & 0x0F ) | *(buf+3);
856               //sectionlength += 4; //include header but subtract crc in the end...
857               int p = 13; //skip fixed part of pmt
858               while ( p < sectionlength) {
859                   int streamtype = *(curbuf+p);
860                   p++;
861                   int foundpid = (*(curbuf+p)<< 8) | *(curbuf+p+1);
862                   p += 2; //skip ES Pid
863                   int eslength = ((*(curbuf+p) << 8) & 0x0F ) | *(curbuf+p+1);
864                   p += 2; //skip ES length
865                   if ((foundpid >> 13) != 0x07)
866                   {
867                       Log::getInstance()->log("DemuxerTS", Log::DEBUG, "FOUNDPID=%02x %02x TRAILING 111 not set but %x", *(buf+p),*(buf+p+1), (foundpid >> 13));
868                   }
869                   else 
870                   {
871                       foundpid = foundpid & 0x1FFF; //clear upper 3 bits
872                    //   int pos=0; UNUSED?
873                                           Log::getInstance()->log("DemuxerTS", Log::DEBUG, "Pid found %02x type %02x",foundpid ,streamtype);
874                       if (streamtype==1 || streamtype ==2) {
875                                                   ish264=false;
876                                                   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "Found Mpeg2 Video");
877                           return true;
878                       }
879                                           if (streamtype==0x1b) {
880                                                   ish264=true;
881                                                   Log::getInstance()->log("DemuxerTS", Log::DEBUG, "Found h264 Video");
882                                                   return true;
883                                           }
884                   }
885                   p += eslength; //skip es descriptor
886               }
887                           ish264=false;
888               return false;
889           } 
890       }
891       len-=TS_SIZE;
892       buf+=TS_SIZE;
893   }
894   ish264=false;
895   return false;
896 }
897
898 UINT DemuxerTS::stripAudio(UCHAR* buf, UINT len) //it has to be adapted
899
900     //This function strips all TS Headers and non video payload
901     UINT readpos=0;
902     UINT writepos=0;
903     PESPacket destpaket;
904     bool started=true;
905     while (readpos < len ) {
906         if (buf[readpos] != TS_SIG) {readpos++; continue;} 
907         UINT oldreadpos=readpos;
908
909         int datalen = TS_SIZE - 4;
910         int pid = ( (buf[readpos+1] & 0x1F) << 8 ) | buf[readpos+2];
911         UCHAR payload = buf[readpos+1] & 0x40;
912         if (buf[readpos+3] & 0x20) { // Adaptation field is present
913            datalen -= (buf[readpos+4] + 1);
914         }
915         if (datalen < 0) {// Error in stream TODO log this
916             return 0;
917         }
918         if (datalen == 0) {// Null packet
919              readpos=oldreadpos+TS_SIZE;
920             continue;
921         }
922         readpos += (TS_SIZE - datalen);
923         UINT towrite=min(datalen,len-readpos);
924         if (pid == vID) {
925             if (payload) {
926                 if (started) {
927                     parsePacketDetails(destpaket);
928                     memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
929                     writepos+=destpaket.getSize();
930                  }
931                  destpaket.init(PESTYPE_VID0);
932                  readpos += 6; towrite -= 6;
933                  started=true;
934             }
935
936             if (started) {
937                 if (!destpaket.write(buf+readpos,towrite)) {
938                     parsePacketDetails(destpaket);
939                     memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
940                     writepos+=destpaket.getSize();
941                     destpaket.truncate();
942                                         destpaket.write((UCHAR*)"\200\000\000", 3);
943                     destpaket.write(buf+readpos,towrite);
944
945                 }
946             }
947             
948        
949
950         }
951         readpos=oldreadpos+TS_SIZE;
952     }
953     parsePacketDetails(destpaket);
954     memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
955     writepos+=destpaket.getSize();
956  
957     return writepos;
958 }    
959
960
961