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