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