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