]> git.vomp.tv Git - vompclient.git/blob - src/demuxer.cc
Add some telemetry
[vompclient.git] / src / demuxer.cc
1 /*
2     Copyright 2005-2008 Mark Calderbank
3     Copyright 2007 Marten Richter (AC3 support)
4
5     This file is part of VOMP.
6
7     VOMP is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11
12     VOMP is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with VOMP; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21
22 #include "demuxer.h"
23
24 #include "callback.h"
25 #include "dvbsubtitles.h"
26 #include "log.h"
27 #include "telem.h"
28
29 #include <cstdlib>
30 #include <algorithm>
31
32 #include <math.h>
33
34 #define DEMUXER_SEQ_HEAD 0x000001B3
35 #define DEMUXER_PIC_HEAD 0x00000101
36 #define DEMUXER_SEQ_EXT_HEAD 0x000001B5
37
38 #define DEMUXER_H264_ACCESS_UNIT 0x00000109
39 #define DEMUXER_H264_SEQ_PARAMETER_SET 0x00000107
40 #define DEMUXER_H264_SUB_ENHANCEMENT_INF 0x00000106
41 #define DEMUXER_H264_CODED_SLICE_IDR 0x00000105
42 #define DEMUXER_H264_CODED_SLICE_NON_IDR 0x00000101
43
44 #define SEEK_THRESHOLD 150000 // About 1.5 seconds
45
46 static const char* TAG = "Demuxer";
47
48 // Statics
49 const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
50 Demuxer* Demuxer::instance = NULL;
51
52 class NALUUnit {
53 public:
54     NALUUnit(const u1* buf,u4 length_buf);
55     ~NALUUnit();
56
57 inline    u4 getBits(u4 num_bits);
58     u4 getUe();
59     int getSe();
60     bool isEonalu() {return eonalu;};
61     int getPos(){return pos;};
62
63 protected:
64     u1* nalu_buf;
65     u4 nalu_length;
66     u4 pos;
67     u1 bit_pos;
68     u1 working_byte;
69     u4 last_bytes;
70     bool eonalu;
71 };
72
73 NALUUnit::NALUUnit(const u1 *buf, u4 length_buf)
74 {
75     nalu_length=0;
76     nalu_buf=NULL;
77     pos=0;
78     bit_pos=0;
79     working_byte=0;
80     last_bytes=0;
81     eonalu=false;
82
83     u4 nalu_start=0;
84     u4 nalu_end=0;
85     u4 pattern =(((u4)buf[ 0] << 16) |
86                    ((u4)buf[1] <<  8) |
87                     (u4)buf[2]  );
88     nalu_start=3;
89     while (pattern != 0x000001)
90     {
91         if (++nalu_start >= length_buf) return;
92         pattern = ((pattern << 8) | buf[nalu_start])&0x00FFFFFF;
93     }
94     nalu_end=nalu_start+1;
95     if (nalu_end >= length_buf) return; // input buffer too small. corrupt data? ignore.
96     pattern = ((pattern << 8) | buf[nalu_end])&0x00FFFFFF;
97
98     while (pattern != 0x000001 && pattern != 0x000000)
99     {
100         if (++nalu_end >= length_buf) { nalu_end+=3;break;};
101         pattern = ((pattern << 8) | buf[nalu_end])&0x00FFFFFF;
102     }
103     nalu_end-=3;
104     nalu_end=std::min(length_buf-1,nalu_end);
105     if (nalu_end <= nalu_start) return; // input buffer too small. corrupt data? ignore.
106     nalu_length=nalu_end-nalu_start;
107     nalu_buf=(u1*)malloc(nalu_length);
108     memcpy(nalu_buf,buf+nalu_start,nalu_length);
109     pos=1;
110 }
111
112 NALUUnit::~NALUUnit()
113 {
114     if (nalu_buf) free(nalu_buf);
115 }
116
117 inline u4 NALUUnit::getBits(u4 num_bits)
118 {
119     if (num_bits==0) return 0; //???
120     u4 remain_bits=num_bits;
121     u4 work=0;
122     //May be slow, but should work!
123     while (remain_bits>0) {
124         if (bit_pos==0) {
125             if (pos<nalu_length)
126             {
127                 last_bytes=(last_bytes<<8) & nalu_buf[pos];
128                 if ((last_bytes & 0x00FFFFFF) == 0x000003) pos++; //emulation prevention byte
129                  if (pos<nalu_length)
130                  {
131                      working_byte=nalu_buf[pos];
132                      pos++;
133                  } 
134                  else
135                  {
136                      working_byte=0;
137                      eonalu=true;
138                  }
139             } 
140             else
141             {
142                 working_byte=0;
143                 eonalu=true;
144             }
145
146         }
147         u4 fetch_bits=std::min(remain_bits, static_cast<u4>(8-bit_pos));
148         work=work <<fetch_bits;
149         //work|=((working_byte>>bit_pos) & (0xFF>>(8-fetch_bits)));
150         work|=(working_byte &(0xFF>>(bit_pos)))>>(8-fetch_bits-bit_pos);
151         remain_bits-=fetch_bits;
152         bit_pos=(bit_pos+fetch_bits)%8;
153     }
154     return work;
155 }
156
157 u4 NALUUnit::getUe()
158 {
159     int leadbits=-1;
160     bool bit;
161     for( bit = 0; !bit && !eonalu; leadbits++ )
162         bit = getBits(1);
163     if (eonalu) return 0;
164     return ((1 << leadbits)-1)+getBits(leadbits);
165 }
166
167 int NALUUnit::getSe()
168 {
169     u4 input=getUe();
170     if (input==0) return 0;
171     int output=((input+1)>>1);
172     if (input & 0x1) output*=-1;
173     return output;
174 }
175
176
177
178 static const int PESPacket_initial_size = 2000;
179
180 // PESPacket methods
181 PESPacket::PESPacket()
182 {
183   data_size = PESPacket_initial_size;
184   data = (u1*)malloc(data_size);
185   data[0] = 0x00;
186   data[1] = 0x00;
187   data[2] = 0x01;
188   init(0);
189 }
190
191 PESPacket::PESPacket(const PESPacket& packet)
192 {
193   copyFrom(packet);
194 }
195
196 PESPacket& PESPacket::operator=(const PESPacket& packet)
197 {
198   if (this != &packet)
199   {
200     if (data) free(data);
201     copyFrom(packet);
202   }
203   return *this;
204 }
205
206 PESPacket::~PESPacket()
207 {
208   if (data) free(data);
209 }
210
211 void PESPacket::copyFrom(const PESPacket& packet)
212 {
213   length = packet.length;
214   size = packet.size;
215   packetType = packet.packetType;
216   substream = packet.substream;
217   seq_header = packet.seq_header;
218   data_size = size;
219   data = (u1*)malloc(data_size);
220   memcpy(data, packet.data, data_size);
221 }
222
223 void PESPacket::init(u1 type, u1 sub)
224 {
225   length = 0; 
226   size = 6;
227   data[4] = data[5] = 0;
228   data[3] = type;
229   packetType = type;
230   substream = sub;
231   seq_header = 1; // Unknown seq_header status
232
233 }
234
235 void PESPacket::truncate()
236 {
237   init(packetType,substream);
238 }
239
240
241
242 int PESPacket::write(const u1 *buf, int len)
243 {
244
245
246   if (size + len > 0x10000) return 0;
247   if (size + len > data_size)
248   { // Reallocate
249     u4 new_data_size = std::max(data_size + data_size / 2, data_size + len);
250     if (new_data_size > 0x10000) new_data_size = 0x10000;
251     data_size = new_data_size;
252     data = (u1*)realloc(data, data_size);
253   }
254   memcpy(data + size, buf, len);
255   length += len;
256   size += len;
257   data[4] = (length >> 8);
258   data[5] = (length & 0xFF);
259   // We have added data - reset seq_header indicator if necessary
260   if (seq_header == 0) seq_header = 1; // Reset to 'unknown'
261   return 1;
262 }
263
264 u8 PESPacket::getPTS() const
265 {
266   if ( ( (packetType >= Demuxer::PESTYPE_AUD0 &&
267           packetType <= Demuxer::PESTYPE_AUDMAX)
268          ||
269          (packetType >= Demuxer::PESTYPE_VID0 &&
270           packetType <= Demuxer::PESTYPE_VIDMAX)
271    ||
272           packetType == Demuxer::PESTYPE_PRIVATE_1
273        )
274        && size >= 14 && data[7] & 0x80)
275   {
276     return ( (u8)(data[ 9] & 0x0E) << 29) |
277            ( (u8)(data[10])        << 22 ) |
278            ( (u8)(data[11] & 0xFE) << 14 ) |
279            ( (u8)(data[12])        <<  7 ) |
280            ( (u8)(data[13] & 0xFE) >>  1 );
281   }
282   else return PTS_INVALID;
283 }
284
285 u1 PESPacket::operator[] (u4 index) const
286 {
287   if (index >= size)
288     return 0;
289   else
290     return data[index];
291 }
292
293 u4 PESPacket::findPictureHeader(bool h264) const
294 {
295   if (size < 12) return 0;
296   u4 pattern = ( ((u4)data[ 8] << 24) |
297                    ((u4)data[ 9] << 16) |
298                    ((u4)data[10] <<  8) |
299                     (u4)data[11]  );
300   u4 pos = 11;
301   if (h264) {
302           
303           while (pattern != DEMUXER_H264_ACCESS_UNIT)
304           {
305                   if (++pos >= size) return 0;
306                   pattern = (pattern << 8) | data[pos];
307           }
308           return pos-3;
309   } else {
310           while (pattern != DEMUXER_PIC_HEAD)
311           {
312                   if (++pos >= size) return 0;
313                   pattern = (pattern << 8) | data[pos];
314           }
315           return pos-3;
316   }
317 }
318
319 u4 PESPacket::countPictureHeaders(bool h264, struct PictCountInfo& pinfo) const
320 {
321   if (size < 12) return 0;
322   u4 pattern = ( ((u4)data[ 8] << 24) |
323                    ((u4)data[ 9] << 16) |
324                    ((u4)data[10] <<  8) |
325                     (u4)data[11]  );
326   u4 pos = 11;
327   u4 count=0;
328   if (h264) {
329           //inspired by vdr algorithm for frame couting by Klaus Schmidinger
330           while (pos<size)
331           {
332           pos++;
333                   pattern = (pattern << 8) | data[pos];
334                   if ((pattern &0xFFFFFF00)==0x00000100) {
335                           u4 testpattern=(pattern& 0xFFFFFF1f);
336                           if (testpattern==DEMUXER_H264_ACCESS_UNIT) pinfo.hasaccessunit=true;
337                           else if (testpattern==DEMUXER_H264_SEQ_PARAMETER_SET ) {
338                                   pinfo.hassps=true;
339                                   NALUUnit nalu(data+pos-3,getSize()-pos+3);
340                                   int profile=nalu.getBits(8);
341                                   nalu.getBits(8); //constraints
342                                   nalu.getBits(8); //level_idc
343                                   nalu.getUe(); //seq_parameter_set_id
344                                   int chroma=1;
345                               pinfo.separate_color_plane_flag=0;
346                                   if (profile==100 || profile==110 || profile==122 || profile==144)
347                                   {
348                                       chroma=nalu.getUe();
349                                       if (chroma==3)
350                                       {
351                                           pinfo.separate_color_plane_flag=nalu.getBits(1);
352                                       }
353                                       nalu.getUe(); //bit depth lume
354                                       nalu.getUe(); //bit depth chrome
355                                       nalu.getBits(1);
356                                       if (nalu.getBits(1))
357                                       {
358                                           for (int i=0;i<8;i++){
359                                                   if (nalu.getBits(1))
360                                                   {
361                                                           if (i<6)
362                                                           {
363                                                                   u4 lastscale=8;
364                                                                   u4 nextscale=8;
365                                                                   for (int j=0;j<16;j++) {
366                                                                           if (nextscale!=0) {
367                                                                                   u4 delta=nalu.getSe();
368                                                                                   nextscale=(lastscale+delta+256)%256;
369                                                                           }
370                                                                           lastscale=(nextscale==0)?lastscale:nextscale;
371                                                                   }
372                                                           }
373                                                           else
374                                                           {
375                                                                   u4 lastscale=8;
376                                                                   u4 nextscale=8;
377                                                                   for (int j=0;j<64;j++) {
378                                                                           if (nextscale!=0) {
379                                                                                   u4 delta=nalu.getSe();
380                                                                                   nextscale=(lastscale+delta+256)%256;
381                                                                           }
382                                                                           lastscale=(nextscale==0)?lastscale:nextscale;
383                                                                   }
384                                                           }
385                                                   }
386                                           }
387                                       }
388                                   }
389
390                                   u4 checkMaxFrameNum = nalu.getUe() + 4;  //log2framenum
391
392                                   if (checkMaxFrameNum < 13) {
393                                         pinfo.log2_max_frame_num = checkMaxFrameNum;
394                                   }
395                                   else {
396                                         pattern=0xFFFFFF;
397                                         pos+=nalu.getPos();
398                                         continue;
399                                   }
400
401                                   u4 temp=nalu.getUe();
402                                   if (temp==0) //pict order
403                                           nalu.getUe();
404                                   else if (temp==1) {
405                                           nalu.getBits(1);
406                                           nalu.getSe();
407                                           nalu.getSe();
408                                           u4 temp2=nalu.getUe();
409                                           for (u4 i=0;i<temp2;i++)
410                                                   nalu.getSe();
411                                   }
412                                   nalu.getUe(); //Num refframes
413                                   nalu.getBits(1);
414                                   nalu.getUe();
415                                   nalu.getUe();
416                                   pinfo.frame_mbs_only_flag=nalu.getBits(1);
417                                   pattern=0xFFFFFF;
418                                   pos+=nalu.getPos();
419
420                           } if (testpattern==DEMUXER_H264_CODED_SLICE_IDR || testpattern==DEMUXER_H264_CODED_SLICE_NON_IDR ) {
421                                 /*  LogNT::getInstance()->error(TAG,
422                                                                 "Has slice %d %d %d %d %d",pinfo.hasaccessunit, pinfo.hassps,pinfo.frame_mbs_only_flag,pinfo.separate_color_plane_flag,
423                                                                 pinfo.log2_max_frame_num);*/
424                                   if (pinfo.hasaccessunit && pinfo.hassps) {
425
426                                           NALUUnit nalu(data+pos-3,getSize()-pos+3);
427                                           nalu.getUe();// first_mb_in_slice
428                                           nalu.getUe();//sliectype
429                                           if (!pinfo.frame_mbs_only_flag) {
430                                                   nalu.getUe(); //pic_paramter_set_id
431                                                   if (pinfo.separate_color_plane_flag) nalu.getBits(2);
432                                                   nalu.getBits(pinfo.log2_max_frame_num);
433                                                   //if (!frame_mbs_only_flag)
434                                                   if (nalu.getBits(1)) { //field_picture
435                                                           if (!nalu.getBits(1)) { //bottom_field
436                                                                   count++;
437                                                           }
438                                                   } else count++;
439
440                                           } else count++;
441                                           pattern=0xFFFFFF;
442                                           pos+=nalu.getPos();
443                                           pinfo.hasaccessunit=false;
444                                   }
445                           }
446                   }
447           }
448           return count;
449   } else {
450       while (pos<size)
451           {
452           pos++;
453                   pattern = (pattern << 8) | data[pos];
454           if (pattern==DEMUXER_PIC_HEAD) count++;
455           }
456           return count;
457   }
458 }
459
460 u4 PESPacket::findSeqHeader(bool h264) const
461 {
462   if (seq_header != 1) return seq_header;
463   if (size < 12) return 0;
464   u4 pattern = ( ((u4)data[ 8] << 24) |
465                    ((u4)data[ 9] << 16) |
466                    ((u4)data[10] <<  8) |
467                     (u4)data[11]  );
468   u4 pos = 11;
469   if (h264) {
470       while ((pattern & 0xFFFFFF1F) != DEMUXER_H264_SEQ_PARAMETER_SET)
471           {
472                   if (++pos >= size)
473                   {
474                           seq_header = 0;
475                           return 0;
476                   }
477                   pattern = (pattern << 8) | data[pos];
478           }
479           seq_header = pos - 3;
480   } 
481   else 
482   {
483           while (pattern != DEMUXER_SEQ_HEAD)
484           {
485                   if (++pos >= size)
486                   {
487                           seq_header = 0;
488                           return 0;
489                   }
490                   pattern = (pattern << 8) | data[pos];
491           }
492           seq_header = pos - 3;
493   }
494   return seq_header;
495 }
496
497 u4 PESPacket::findSeqExtHeader(bool h264) const
498 {
499   if (seq_header != 1) return seq_header;
500   if (size < 12) return 0;
501   u4 pattern = ( ((u4)data[ 8] << 24) |
502                    ((u4)data[ 9] << 16) |
503                    ((u4)data[10] <<  8) |
504                     (u4)data[11]  );
505   u4 pos = 11;
506   if (h264) {
507       while ((pattern & 0xFFFFFF1F) != DEMUXER_H264_SUB_ENHANCEMENT_INF)
508           {
509                   if (++pos >= size)
510                   {
511                           seq_header = 0;
512                           return 0;
513                   }
514                   pattern = (pattern << 8) | data[pos];
515           }
516           seq_header = pos - 3;
517   }
518   else
519   {
520           while (pattern != DEMUXER_SEQ_EXT_HEAD && (data[pos+1]&0xf0)!=0x10)
521           {
522                   if (++pos >= (size-1))
523                   {
524                           seq_header = 0;
525                           return 0;
526                   }
527                   pattern = (pattern << 8) | data[pos];
528           }
529           seq_header = pos - 3;
530   }
531   return seq_header;
532 }
533
534 // Demuxer methods
535 Demuxer::Demuxer()
536 {
537   if (instance) return;
538   instance = this;
539   initted = false;
540   callback = NULL;
541   arcnt = 0;
542   vid_seeking = aud_seeking = false;
543   video_pts = audio_pts = 0;
544   ispre_1_3_19 = false;
545   packetnum=0;
546   h264 = false;
547   fps = 25.0;
548   astreamtype=4;
549   livetv=false;
550 }
551
552 Demuxer::~Demuxer()
553 {
554   shutdown();
555   instance = NULL;
556 }
557
558 Demuxer* Demuxer::getInstance()
559 {
560   return instance;
561 }
562
563 int Demuxer::init(Callback* tcallback, DrainTarget* audio, DrainTarget* video, DrainTarget* teletext,
564                   u4 demuxMemoryV, u4 demuxMemoryA, u4 demuxMemoryT,double infps, DVBSubtitles* tsubtitles)
565 {
566   if (!initted)
567   {
568     if ( !videostream.init(video, demuxMemoryV) ||
569          !audiostream.init(audio, demuxMemoryA) ||
570          !teletextstream.init(teletext, demuxMemoryT))
571     {
572       LogNT::getInstance()->crit(TAG, "Failed to initialize demuxer");
573       shutdown();
574       return 0;
575     }
576   }
577   if (teletext) {
578       isteletextdecoded = true;
579   } else {
580       isteletextdecoded = false;
581   }
582   fps=infps;
583   reset();
584   initted = true;
585   subtitles = tsubtitles;
586   callback = tcallback;
587   return 1;
588 }
589
590 void Demuxer::reset()
591 {
592   LogNT::getInstance()->debug(TAG, "Reset called");
593   flush();
594   video_current = audio_current = teletext_current = subtitle_current = -1;
595   horizontal_size = vertical_size = 0;
596   interlaced=true; // default is true
597   aspect_ratio = (enum AspectRatio) 0;
598   parx=1;
599   pary=1;
600   frame_rate = bit_rate = 0;
601   ispre_1_3_19 = false;
602   h264 = false;
603   packetnum=0;
604   astreamtype=4;
605   livetv=false;
606
607   for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++)
608   {
609     avail_mpaudchan[i] = false;
610   }
611   for (int i = 0; i <= (PESTYPE_SUBSTREAM_AC3MAX - PESTYPE_SUBSTREAM_AC30); i++)
612   {
613     avail_ac3audchan[i] = false;
614   }
615   for (int i = 0; i <= (PESTYPE_SUBSTREAM_DVBSUBTITLEMAX - PESTYPE_SUBSTREAM_DVBSUBTITLE0); i++)
616   {
617     avail_dvbsubtitlechan[i] = false;
618   }
619 }
620
621 int Demuxer::shutdown()
622 {
623   videostream.shutdown();
624   audiostream.shutdown();
625   teletextstream.shutdown();
626   initted = false;
627   return 1;
628 }
629
630 void Demuxer::flush()
631 {
632   LogNT::getInstance()->debug(TAG, "Flush called");
633
634   videostream.flush();
635   audiostream.flush();
636   teletextstream.flush();
637 }
638
639 void Demuxer::flushAudio()
640 {
641   audiostream.flush();
642 }
643
644 void Demuxer::seek()
645 {
646   vid_seeking = aud_seeking = true;
647   video_pts = audio_pts = teletext_pts = 0;
648 }
649
650 void Demuxer::setAudioStream(int id)
651 {
652   audio_current = id;
653 }
654
655 void Demuxer::setVideoStream(int id)
656 {
657   video_current = id;
658 }
659
660 void Demuxer::setTeletextStream(int id)
661 {
662   teletext_current = id;
663 }
664
665 void Demuxer::setDVBSubtitleStream(int id)
666 {
667   subtitle_current = id;
668 }
669
670 void Demuxer::setAspectRatio(enum AspectRatio ar, int taspectx, int taspecty)
671 {
672   if ((aspect_ratio != ar) || (parx !=  taspectx) || (pary != taspecty) )
673   {
674     LogNT::getInstance()->debug(TAG, "Aspect ratio difference signalled");
675     if (++arcnt > 3) // avoid changing aspect ratio if glitch in signal
676     {
677       arcnt = 0;
678       aspect_ratio = ar;
679       parx=taspectx;
680       pary=taspecty;
681       if (callback) callback->call(this);
682     }
683   }
684   else
685     arcnt = 0;
686 }
687
688 bool Demuxer::writeAudio(bool * dataavail)
689 {
690   return audiostream.drain(dataavail);
691 }
692
693 bool Demuxer::writeVideo(bool * dataavail)
694 {
695   return videostream.drain(dataavail);
696 }
697
698 bool Demuxer::writeTeletext(bool * dataavail)
699 {
700    return teletextstream.drain(dataavail);
701 }
702
703 bool Demuxer::submitPacket(PESPacket& packet)
704 {
705   TELEM(2, packet.getPacketType());
706   TELEM(3, packet.getPTS());
707
708   u4 sent = 0;
709   u1 packet_type = packet.getPacketType();
710   const u1* packetdata = packet.getData();
711   if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX)
712   {
713     if (video_current == -1) video_current = packet_type;
714     if (video_current == packet_type && !vid_seeking)
715         {
716         sent = videostream.put(&packetdata[0], packet.getSize(), h264?MPTYPE_VIDEO_H264:MPTYPE_VIDEO_MPEG2,packetnum);
717         if (sent) packetnum++;
718         }
719         else
720       sent = packet.getSize();
721   }
722   else if (packet_type >= PESTYPE_AUD0 && packet_type <= PESTYPE_AUDMAX)
723   {
724
725     if (audio_current == -1) audio_current = packet_type;
726     avail_mpaudchan[packet_type - PESTYPE_AUD0] = true;
727     if (audio_current == packet_type && !aud_seeking)
728         {
729       u1 type=MPTYPE_MPEG_AUDIO;
730       switch (astreamtype)
731       {
732       case 3:
733       case 4:
734           type=MPTYPE_MPEG_AUDIO; break;
735       case 0x11:
736           type=MPTYPE_AAC_LATM; break;
737       };
738       sent = audiostream.put(&packetdata[0], packet.getSize(), type,packetnum);
739           if (sent)  packetnum++;
740         }
741         else
742       sent = packet.getSize();
743   }
744   else if (packet_type == PESTYPE_PRIVATE_1 &&
745            packet.getSubstream() >= PESTYPE_SUBSTREAM_AC30 &&
746            packet.getSubstream() <= PESTYPE_SUBSTREAM_AC3MAX)
747   {
748     avail_ac3audchan[packet.getSubstream() - PESTYPE_SUBSTREAM_AC30] = true;
749     if (packet.getSubstream() == audio_current)
750     {
751       sent = audiostream.put(&packetdata[0], packet.getSize(), (ispre_1_3_19 || livetv)? MPTYPE_AC3_PRE13 : MPTYPE_AC3,packetnum);
752           if (sent) packetnum++;
753     }
754     else
755     {
756       sent = packet.getSize();
757     }
758   }
759   else if (packet_type == PESTYPE_PRIVATE_1 &&
760            packet.getSubstream() >= PESTYPE_SUBSTREAM_DVBSUBTITLE0 &&
761            packet.getSubstream() <= PESTYPE_SUBSTREAM_DVBSUBTITLEMAX)
762   {
763     avail_dvbsubtitlechan[packet.getSubstream()-PESTYPE_SUBSTREAM_DVBSUBTITLE0]=true;
764     if (subtitle_current == -1) subtitle_current = packet.getSubstream();
765     if (subtitles && packet.getSubstream()==subtitle_current)
766     {
767          subtitles->put(packet);
768     }
769     sent = packet.getSize();
770   }
771   else if (isteletextdecoded  && packet_type == PESTYPE_PRIVATE_1 &&
772            packet.getSubstream() >= PESTYPE_SUBSTREAM_TELETEXT0 &&
773            packet.getSubstream() <= PESTYPE_SUBSTREAM_TELETEXTMAX)
774   {
775
776     if (teletext_current == -1) teletext_current = packet.getSubstream();
777     if (teletext_current == packet.getSubstream())
778     {
779         sent = teletextstream.put(&packetdata[0], packet.getSize(), MPTYPE_TELETEXT,packetnum);
780     }
781     else 
782     {
783         sent = packet.getSize();
784     }
785   }
786   else
787   {
788     sent = packet.getSize();
789   }
790
791   if (sent < packet.getSize()) // Stream is full.
792     return false;
793   else
794     return true;
795 }
796
797 void Demuxer::parsePacketDetails(PESPacket& packet)
798 {
799     if (packet.getPacketType() >= PESTYPE_AUD0 &&
800         packet.getPacketType() <= PESTYPE_AUDMAX)
801     {
802         // Extract audio PTS if it exists
803         if (packet.hasPTS())
804         {
805             audio_pts = packet.getPTS();
806             // We continue to seek on the audio if the video PTS that we
807             // are trying to match is ahead of the audio PTS by at most
808             // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
809             if (aud_seeking && !vid_seeking &&
810                 !( (video_pts_seek > audio_pts &&
811                 video_pts_seek - audio_pts < SEEK_THRESHOLD)
812                 ||
813                 (video_pts_seek < audio_pts &&
814                 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
815             {
816                 aud_seeking = 0;
817                 LogNT::getInstance()->debug(TAG, "Leaving  audio sync: Audio PTS = {}", audio_pts);
818             }
819         }
820     }
821     else if (packet.getPacketType() == PESTYPE_PRIVATE_1) // Private stream
822     {
823         if (!livetv) {
824                 //Inspired by vdr's device.c
825                 int payload_begin = packet[8]+9;
826                 unsigned char substream_id = packet[payload_begin];
827                 unsigned char substream_type = substream_id & 0xF0;
828                 unsigned char substream_index = substream_id & 0x1F;
829                 pre_1_3_19_Recording: //This is for old recordings stuff and live TV
830                 if (ispre_1_3_19)
831                 {
832                         int old_substream=packet.getSubstream();
833                         if (old_substream){ //someone else already set it, this is live tv
834                                 substream_id = old_substream;
835                                 substream_type = substream_id & 0xF0;
836                                 substream_index = substream_id & 0x1F;
837                         } else {
838                                 substream_id = PESTYPE_PRIVATE_1;
839                                 substream_type = 0x80;
840                                 substream_index = 0;
841                         }
842
843                 }
844                 switch (substream_type)
845                 {
846                 case 0x20://SPU
847                 case 0x30://SPU
848                         packet.setSubstream(substream_id);
849                         break;
850                 case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there?
851                         break;
852                 case 0x80: //ac3, currently only one ac3 track per recording supported
853                         packet.setSubstream(substream_type+substream_index);
854
855                         // Extract audio PTS if it exists
856                         if (packet.hasPTS())
857                         {
858                                 audio_pts = packet.getPTS();
859                                 // We continue to seek on the audio if the video PTS that we
860                                 // are trying to match is ahead of the audio PTS by at most
861                                 // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
862                                 if (aud_seeking && !vid_seeking &&
863                                                 !( (video_pts_seek > audio_pts &&
864                                                                 video_pts_seek - audio_pts < SEEK_THRESHOLD)
865                                                                 ||
866                                                                 (video_pts_seek < audio_pts &&
867                                                                                 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
868                                 {
869                                         aud_seeking = 0;
870                                         LogNT::getInstance()->debug(TAG, "Leaving  audio sync: Audio PTS = {}", audio_pts);
871                                 }
872                         }
873                         break;
874                 case 0x10: //Teletext Is this correct?
875                         packet.setSubstream(substream_id);
876                         // Extract teletxt PTS if it exists
877                         if (packet.hasPTS())
878                         {
879                                 teletext_pts = packet.getPTS();
880                         }
881                         break;
882                 default:
883                         if (!ispre_1_3_19)
884                         {
885                                 ispre_1_3_19=true; //switching to compat mode and live tv mode
886                                 goto pre_1_3_19_Recording;
887                         }
888                         else
889                         {
890                                 packet.setSubstream(0);
891                         }
892                         break;
893                 }
894         }
895     }
896     else if (packet.getPacketType() >= PESTYPE_VID0 &&
897         packet.getPacketType() <= PESTYPE_VIDMAX)
898     {
899         // Extract video PTS if it exists
900         if (packet.hasPTS()) video_pts = packet.getPTS();
901
902         // If there is a sequence header, extract information
903         u4 pos = packet.findSeqHeader(h264);
904         if (pos > 1)
905         {
906             if (!h264) {
907                 pos += 4;
908                 if (pos+6 >= packet.getSize()) return;
909                 horizontal_size = ((int)packet[pos] << 4) | ((int)packet[pos+1] >> 4);
910                 
911                 vertical_size = (((int)packet[pos+1] & 0xf) << 8) | (int)packet[pos+2];
912
913                 enum AspectRatio aspect=(enum AspectRatio)(packet[pos+3] >> 4);
914                 int aspectx=1;
915                 int aspecty=1;
916                 const int aspectDAR[]={0,1,1,1,4,3,16,9,221,100};
917                 int aspectDARx=aspectDAR[aspect*2];
918                 int aspectDARy=aspectDAR[aspect*2+1];
919
920                 aspectx=aspectDARx*vertical_size;
921                 aspecty=aspectDARy*horizontal_size;
922
923                 int commona;
924                 int commonb;
925                // LogNT::getInstance()->debug(TAG, "PAR test1 {} {} {} {}", aspectx, aspecty, commona, commonb);
926                 commona=aspectx;
927                 commonb=aspecty;
928
929                 while (commonb) {
930                         int temp=commonb;
931                         commonb=commona%commonb;
932                         commona=temp;
933                 }
934                 aspectx=aspectx/commona;
935                 aspecty=aspecty/commona;
936                 //LogNT::getInstance()->debug(TAG, "PAR test2 {} {} {} {} {} {} {}", aspectx,aspecty,aspectDARx,aspectDARy,horizontal_size,vertical_size,commona);
937
938                 setAspectRatio(aspect,aspectx,aspecty);
939                 frame_rate = packet[pos+3] & 0x0f;
940                 if (frame_rate >= 1 && frame_rate <= 8)
941                     frame_rate = FrameRates[frame_rate];
942                 else
943                     frame_rate = 0;
944                 bit_rate = ((int)packet[pos+4] << 10) |
945                     ((int)packet[pos+5] << 2) |
946                     ((int)packet[pos+6] >> 6);
947             } 
948             else
949             {
950                 /* Chris and Mark I know this is ugly, should we move this to a method  of PESPacket or to NALUUnit what would be better?
951                 This looks so ugly since the header includes variable length parts and I have to parse through the whole header to get the wanted information*/
952                 NALUUnit nalu(packet.getData()+pos,packet.getSize()-pos);
953                 profile=nalu.getBits(8);
954                 nalu.getBits(8); //constraints
955                 nalu.getBits(8); //level_idc
956                 nalu.getUe(); //seq_parameter_set_id
957                 int chroma=1;
958                 if (profile==100 || profile==110 || profile==122 || profile==144)
959                 {
960                     chroma=nalu.getUe();
961                     if (chroma==3)
962                     {
963                         nalu.getBits(1);
964                     }
965                     nalu.getUe(); //bit depth lume
966                     nalu.getUe(); //bit depth chrome
967                     nalu.getBits(1);
968                     if (nalu.getBits(1))
969                     {
970                         for (int i=0;i<8;i++){
971                             if (nalu.getBits(1))
972                             {
973                                 if (i<6)
974                                 {
975                                     u4 lastscale=8;
976                                     u4 nextscale=8;
977                                     for (int j=0;j<16;j++) {
978                                         if (nextscale!=0) {
979                                             u4 delta=nalu.getSe();
980                                             nextscale=(lastscale+delta+256)%256;
981                                         }
982                                         lastscale=(nextscale==0)?lastscale:nextscale;
983                                     }
984                                 }
985                                 else
986                                 {
987                                     u4 lastscale=8;
988                                     u4 nextscale=8;
989                                     for (int j=0;j<64;j++) {
990                                         if (nextscale!=0) {
991                                             u4 delta=nalu.getSe();
992                                             nextscale=(lastscale+delta+256)%256;
993                                         }
994                                         lastscale=(nextscale==0)?lastscale:nextscale;
995                                     }
996                                 }
997                             }
998                         }
999                     }
1000                 }
1001                 int chromunitx=1;
1002                 int chromunity=1;
1003                 switch (chroma) {
1004                 case 0:
1005                     chromunitx=chromunity=1; break;
1006                 case 1:
1007                     chromunitx=chromunity=2; break;
1008                 case 2:
1009                     chromunitx=2;chromunity=1; break;
1010                 case 3:
1011                     chromunitx=chromunity=1; break;
1012                 };
1013
1014                 nalu.getUe(); //log2framenum
1015                 u4 temp=nalu.getUe();
1016                 if (temp==0) //pict order
1017                     nalu.getUe();
1018                 else if (temp==1) {
1019                     nalu.getBits(1);
1020                     nalu.getSe();
1021                     nalu.getSe();
1022                     u4 temp2=nalu.getUe();
1023                     for (u4 i=0;i<temp2;i++)
1024                         nalu.getSe();
1025                 }
1026                 nalu.getUe(); //Num refframes
1027                 nalu.getBits(1);
1028                 horizontal_size=(nalu.getUe()+1)*16;
1029                 
1030                 vertical_size=(nalu.getUe()+1)*16;
1031                 int tinterlaced=nalu.getBits(1);
1032                 vertical_size*=(2-tinterlaced);
1033                 interlaced=!tinterlaced;
1034                 
1035                 if (!tinterlaced) nalu.getBits(1);
1036                 nalu.getBits(1);
1037                 if (nalu.getBits(1))
1038                 {
1039                     horizontal_size-=nalu.getUe()*chromunitx;
1040                     horizontal_size-=nalu.getUe()*chromunitx;
1041                     vertical_size-=nalu.getUe()*(2-tinterlaced)*chromunity;
1042                     vertical_size-=nalu.getUe()*(2-tinterlaced)*chromunity;
1043                 }
1044                 if (nalu.getBits(1))
1045                 {
1046                     if (nalu.getBits(1))
1047                     {
1048                         u4 aspectratioidc=nalu.getBits(8);
1049                         bool hasaspect=false;
1050                         int aspectx,aspecty;
1051                         const float aspects[]={1., 1./1.,12./11.,10./11.,16./11.,40./33.,
1052                             24./11.,20./11.,32./11.,80./33.,18./11.,15./11.,64./33.,160./99.,4./3.,3./2.,2./1.};
1053                         const int aspectsx[]={1, 1,12,10,16,40,
1054                                                     24,20,32,80,18,15,64,160,4,3,2};
1055                         const int aspectsy[]={1, 1,11,11,11,33,11,11,11,33,11,11,33,99,3,2,1};
1056                       
1057                         float aspectratio=((float) horizontal_size)/((float) vertical_size);
1058                         if (aspectratioidc<=16) 
1059                         {
1060                             hasaspect=true;
1061                             aspectratio*=aspects[aspectratioidc];
1062                             aspectx=aspectsx[aspectratioidc];
1063                             aspecty=aspectsy[aspectratioidc];
1064                            
1065                         }
1066                         else if (aspectratioidc==255)
1067                         {
1068                             int t_sar_width=nalu.getBits(16);
1069                             int t_sar_height=nalu.getBits(16);
1070                             if (t_sar_width!=0 && t_sar_height!=0)
1071                             {
1072                                 hasaspect=true;
1073                                 aspectratio*=((float)t_sar_width)/((float)t_sar_height);
1074                                 aspectx=t_sar_width;
1075                                 aspecty=t_sar_height;
1076                             }
1077                         }
1078                         if (hasaspect)
1079                         {
1080                             if (fabs(aspectratio-16./9.)<0.1) setAspectRatio(ASPECT_16_9,aspectx,aspecty);
1081                             else if (fabs(aspectratio-4./3.)<0.1) setAspectRatio(ASPECT_4_3,aspectx,aspecty);
1082                             else  setAspectRatio(ASPECT_1_1,aspectx,aspecty);
1083                         }
1084                     }
1085
1086                 }
1087
1088             }
1089             u4 posext = packet.findSeqExtHeader(h264);
1090             if (posext>1) {
1091                 if (!h264) {
1092                         interlaced=!(packet[pos+1] & 0x08); //really simple
1093                         // if more than full hd is coming we need to add additional parsers here
1094                 } else {
1095                 /*      NALUUnit nalu(packet.getData()+posext,packet.getSize()-posext);
1096                         while (!nalu.isEonalu()) {
1097                                 unsigned int payloadtype=0;
1098                                 unsigned int payloadadd=0xFF;
1099                                 while (payloadadd==0xFF && !nalu.isEonalu()) {
1100                                         payloadadd=nalu.getBits(8);
1101                                         payloadtype+=payloadadd;
1102                                 }
1103                                 unsigned int payloadsize=0;
1104                                 payloadadd=0xff;
1105                                 while (payloadadd==0xFF && !nalu.isEonalu()) {
1106                                        payloadadd=nalu.getBits(8);
1107                                        payloadsize+=payloadadd;
1108                             }
1109                                 switch (payloadtype) {
1110                                 case 1: { // picture timing SEI
1111
1112                                 } break;
1113                                 default: {
1114                                         while (payloadsize) { // not handled skip
1115                                                 nalu.getBits(8);
1116                                                 payloadsize--;
1117                                         }
1118                                 } break;
1119                                 }
1120
1121
1122
1123                         }*/
1124
1125
1126                 }
1127             }
1128            
1129             if (vid_seeking)
1130             {
1131                 vid_seeking = 0;
1132                 video_pts_seek = video_pts;
1133                 LogNT::getInstance()->debug(TAG, "Entering audio sync: Video PTS = {}", video_pts);
1134                 LogNT::getInstance()->debug(TAG, "Entering audio sync: Audio PTS = {}", audio_pts);
1135             }
1136             return;
1137         } 
1138     }
1139 }
1140
1141 u4 Demuxer::stripAudio(u1* buf, u4 len)
1142 {
1143   u4 read_pos = 0, write_pos = 0;
1144   u4 pattern, packet_length;
1145   if (len < 4) return 0;
1146   pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
1147   while (read_pos + 7 <= len)
1148   {
1149     pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
1150     if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
1151       read_pos++;
1152     else
1153     {
1154       packet_length = ((buf[read_pos+4] << 8) | (buf[read_pos+5])) + 6;
1155       if (read_pos + packet_length > len)
1156         read_pos = len;
1157       else
1158       {
1159         if (read_pos != write_pos)
1160           memmove(buf+write_pos, buf+read_pos, packet_length);
1161         read_pos += packet_length;
1162         write_pos += packet_length;
1163         pattern = (buf[read_pos] << 16) | (buf[read_pos+1] << 8)
1164                                         | (buf[read_pos+2]);
1165       }
1166     }
1167   }
1168   return write_pos;
1169 }
1170
1171 void Demuxer::changeTimes(u1* buf, u4 len,u4 playtime)
1172 {
1173         u4 pattern, packet_length;
1174         u4 read_pos = 0;
1175         if (len < 4) return;
1176         pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
1177         while (read_pos + 7 <= len)
1178         {
1179            pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
1180            if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
1181               read_pos++;
1182            else
1183            {
1184               packet_length = ((buf[read_pos+4] << 8) | (buf[read_pos+5])) + 6;
1185               // ok we have a packet figure out if pts and dts are present and replace them
1186               if (read_pos + 19 > len) return;
1187               u8 new_ts=playtime*90; //play time is on ms so multiply it by 90
1188               if (buf[read_pos+7] & 0x80) { // pts is here, replace it
1189                   buf[read_pos+9]=0x21 | (( new_ts>>29)& 0xde );
1190                   buf[read_pos+10]=0x00 |(( new_ts>>22)& 0xff );
1191                   buf[read_pos+11]=0x01 | (( new_ts>>14)& 0xfe );
1192                   buf[read_pos+12]=0x00 | (( new_ts>>7)& 0xff );
1193                   buf[read_pos+13]=0x01 | (( new_ts<<1)& 0xfe );
1194               }
1195
1196               if (buf[read_pos+7] & 0x40) { // pts is here, replace it
1197                    buf[read_pos+14]=0x21 | (( new_ts>>29)& 0xde );
1198                    buf[read_pos+15]=0x00 | (( new_ts>>22)& 0xff );
1199                    buf[read_pos+16]=0x01 | (( new_ts>>14)& 0xfe );
1200                    buf[read_pos+17]=0x00 | (( new_ts>>7)& 0xff );
1201                    buf[read_pos+18]=0x01 | (( new_ts<<1)& 0xfe );
1202               }
1203               read_pos += packet_length;
1204               pattern = (buf[read_pos] << 16) | (buf[read_pos+1] << 8)
1205                                                 | (buf[read_pos+2]);
1206               }
1207           }
1208
1209 }
1210
1211 bool Demuxer::scanForVideo(u1* buf, u4 len, bool &ish264)
1212 {
1213   u4 pos = 3;
1214   u4 pattern;
1215   ish264=false;
1216   if (len < 4) return false;
1217   pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
1218   while (pos < len)
1219   {
1220     pattern = ((pattern & 0xFFFFFF) << 8) | buf[pos++];
1221     if (pattern >= (0x100|PESTYPE_VID0) && pattern <= (0x100|PESTYPE_VIDMAX))
1222       return true;
1223   }
1224   return false;
1225 }
1226
1227 bool* Demuxer::getmpAudioChannels()
1228 {
1229   return avail_mpaudchan;
1230 }
1231
1232 bool* Demuxer::getac3AudioChannels()
1233 {
1234   return avail_ac3audchan;
1235 }
1236
1237 bool* Demuxer::getSubtitleChannels()
1238 {
1239   return avail_dvbsubtitlechan;
1240 }
1241
1242 int Demuxer::getselSubtitleChannel()
1243 {
1244   return subtitle_current;
1245 }
1246
1247 int Demuxer::getselAudioChannel()
1248 {
1249   return audio_current;
1250 }
1251
1252