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