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