]> git.vomp.tv Git - vompclient-marten.git/blob - demuxer.cc
HDTV for Windows
[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
35 #define DEMUXER_H264_ACCESS_UNIT 0x00000109
36 #define DEMUXER_H264_SEQ_PARAMETER_SET 0x00000107
37
38
39 #define SEEK_THRESHOLD 150000 // About 1.5 seconds
40
41 // Statics
42 const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
43 Demuxer* Demuxer::instance = NULL;
44
45 class NALUUnit {
46 public:
47     NALUUnit(const UCHAR* buf,UINT length_buf);
48     ~NALUUnit();
49
50 inline    UINT getBits(UINT num_bits);
51     UINT getUe();
52     int getSe();
53     bool isEonalu() {return eonalu;};
54
55 protected:
56     UCHAR* nalu_buf;
57     UINT nalu_length;
58     UINT pos;
59     UCHAR bit_pos;
60     UCHAR working_byte;
61     UINT last_bytes;
62     bool eonalu;
63 };
64
65 NALUUnit::NALUUnit(const UCHAR *buf, UINT length_buf)
66 {
67     nalu_length=0;
68     nalu_buf=NULL;
69     pos=0;
70     bit_pos=0;
71     working_byte=0;
72     last_bytes=0;
73     eonalu=false;
74
75     UINT nalu_start=0;
76     UINT nalu_end=0;
77     UINT pattern =(((UINT)buf[ 0] << 16) |
78                    ((UINT)buf[1] <<  8) |
79                     (UINT)buf[2]  );
80     nalu_start=3;
81     while (pattern != 0x000001)
82     {
83         if (++nalu_start >= length_buf) return;
84         pattern = ((pattern << 8) | buf[nalu_start])&0x00FFFFFF;
85     }
86     nalu_end=nalu_start+1;
87     pattern = ((pattern << 8) | buf[nalu_end])&0x00FFFFFF;
88
89     while (pattern != 0x000001 && pattern != 0x000000)
90     {
91         if (++nalu_end >= length_buf) { nalu_end+=3;break;};
92         pattern = ((pattern << 8) | buf[nalu_end])&0x00FFFFFF;
93     }
94     nalu_end-=3;
95     nalu_end=min(length_buf-1,nalu_end);
96     nalu_length=nalu_end-nalu_start;
97     nalu_buf=(UCHAR*)malloc(nalu_length);
98     memcpy(nalu_buf,buf+nalu_start,nalu_length);
99     pos=1;
100 }
101
102 NALUUnit::~NALUUnit()
103 {
104     if (nalu_buf) free(nalu_buf);
105 }
106
107 inline UINT NALUUnit::getBits(UINT num_bits)
108 {
109     if (num_bits==0) return 0; //???
110     UINT remain_bits=num_bits;
111     UINT work=0;
112     //May be slow, but should work!
113     while (remain_bits>0) {
114         if (bit_pos==0) {
115             if (pos<nalu_length)
116             {
117                 last_bytes=(last_bytes<<8) & nalu_buf[pos];
118                 if ((last_bytes & 0x00FFFFFF) == 0x000003) pos++; //emulation prevention byte
119                  if (pos<nalu_length)
120                  {
121                      working_byte=nalu_buf[pos];
122                      pos++;
123                  } 
124                  else
125                  {
126                      working_byte=0;
127                      eonalu=true;
128                  }
129             } 
130             else
131             {
132                 working_byte=0;
133                 eonalu=true;
134             }
135
136         }
137         UINT fetch_bits=min(remain_bits,8-bit_pos);
138         work=work <<fetch_bits;
139         //work|=((working_byte>>bit_pos) & (0xFF>>(8-fetch_bits)));
140         work|=(working_byte &(0xFF>>(bit_pos)))>>(8-fetch_bits-bit_pos);
141         remain_bits-=fetch_bits;
142         bit_pos=(bit_pos+fetch_bits)%8;
143     }
144     return work;
145 }
146
147 UINT NALUUnit::getUe()
148 {
149     int leadbits=-1;
150     bool bit;
151     for( bit = 0; !bit && !eonalu; leadbits++ )
152         bit = getBits(1);
153     if (eonalu) return true;
154     return ((1 << leadbits)-1)+getBits(leadbits);
155 }
156
157 int NALUUnit::getSe()
158 {
159     UINT input=getUe();
160     if (input==0) return 0;
161     int output=((input+1)>>1);
162     if (input & 0x1) output*=-1;
163     return output;
164 }
165
166
167
168 static const int PESPacket_initial_size = 2000;
169
170 // PESPacket methods
171 PESPacket::PESPacket()
172 {
173   data_size = PESPacket_initial_size;
174   data = (UCHAR*)malloc(data_size);
175   data[0] = 0x00;
176   data[1] = 0x00;
177   data[2] = 0x01;
178   init(0);
179 }
180
181 PESPacket::PESPacket(const PESPacket& packet)
182 {
183   copyFrom(packet);
184 }
185
186 PESPacket& PESPacket::operator=(const PESPacket& packet)
187 {
188   if (this != &packet)
189   {
190     if (data) free(data);
191     copyFrom(packet);
192   }
193   return *this;
194 }
195
196 PESPacket::~PESPacket()
197 {
198   if (data) free(data);
199 }
200
201 void PESPacket::copyFrom(const PESPacket& packet)
202 {
203   length = packet.length;
204   size = packet.size;
205   packetType = packet.packetType;
206   substream = packet.substream;
207   seq_header = packet.seq_header;
208   data_size = size;
209   data = (UCHAR*)malloc(data_size);
210   memcpy(data, packet.data, data_size);
211 }
212
213 void PESPacket::init(UCHAR type, UCHAR sub)
214 {
215   length = 0; 
216   size = 6;
217   data[4] = data[5] = 0;
218   data[3] = type;
219   packetType = type;
220   substream = sub;
221   seq_header = 1; // Unknown seq_header status
222 }
223
224 void PESPacket::truncate()
225 {
226   init(packetType,substream);
227 }
228
229 int PESPacket::write(const UCHAR *buf, int len)
230 {
231   if (size + len > 0x10000) return 0;
232   if (size + len > data_size)
233   { // Reallocate
234     UINT new_data_size = max(data_size + data_size / 2, data_size + len);
235     if (new_data_size > 0x10000) new_data_size = 0x10000;
236     data_size = new_data_size;
237     data = (UCHAR*)realloc(data, data_size);
238   }
239   memcpy(data + size, buf, len);
240   length += len;
241   size += len;
242   data[4] = (length >> 8);
243   data[5] = (length & 0xFF);
244   // We have added data - reset seq_header indicator if necessary
245   if (seq_header == 0) seq_header = 1; // Reset to 'unknown'
246   return 1;
247 }
248
249 ULLONG PESPacket::getPTS() const
250 {
251   if ( ( (packetType >= Demuxer::PESTYPE_AUD0 &&
252           packetType <= Demuxer::PESTYPE_AUDMAX)
253          ||
254          (packetType >= Demuxer::PESTYPE_VID0 &&
255           packetType <= Demuxer::PESTYPE_VIDMAX)
256    ||
257           packetType == Demuxer::PESTYPE_PRIVATE_1
258        )
259        && size >= 14 && data[7] & 0x80)
260   {
261     return ( (ULLONG)(data[ 9] & 0x0E) << 29) |
262            ( (ULLONG)(data[10])        << 22 ) |
263            ( (ULLONG)(data[11] & 0xFE) << 14 ) |
264            ( (ULLONG)(data[12])        <<  7 ) |
265            ( (ULLONG)(data[13] & 0xFE) >>  1 );
266   }
267   else return PTS_INVALID;
268 }
269
270 UCHAR PESPacket::operator[] (UINT index) const
271 {
272   if (index >= size)
273     return 0;
274   else
275     return data[index];
276 }
277
278 UINT PESPacket::findPictureHeader(bool h264) const
279 {
280   if (size < 12) return 0;
281   UINT pattern = ( ((UINT)data[ 8] << 24) |
282                    ((UINT)data[ 9] << 16) |
283                    ((UINT)data[10] <<  8) |
284                     (UINT)data[11]  );
285   UINT pos = 11;
286   if (h264) {
287           
288           while (pattern != DEMUXER_H264_ACCESS_UNIT)
289           {
290                   if (++pos >= size) return 0;
291                   pattern = (pattern << 8) | data[pos];
292           }
293           return pos-3;
294   } else {
295           while (pattern != DEMUXER_PIC_HEAD)
296           {
297                   if (++pos >= size) return 0;
298                   pattern = (pattern << 8) | data[pos];
299           }
300           return pos-3;
301   }
302 }
303
304 UINT PESPacket::findSeqHeader(bool h264) const
305 {
306   if (seq_header != 1) return seq_header;
307   if (size < 12) return 0;
308   UINT pattern = ( ((UINT)data[ 8] << 24) |
309                    ((UINT)data[ 9] << 16) |
310                    ((UINT)data[10] <<  8) |
311                     (UINT)data[11]  );
312   UINT pos = 11;
313   if (h264) {
314       while ((pattern & 0xFFFFFF1F) != DEMUXER_H264_SEQ_PARAMETER_SET)
315           {
316                   if (++pos >= size)
317                   {
318                           seq_header = 0;
319                           return 0;
320                   }
321                   pattern = (pattern << 8) | data[pos];
322           }
323           seq_header = pos - 3;
324   } 
325   else 
326   {
327           while (pattern != DEMUXER_SEQ_HEAD)
328           {
329                   if (++pos >= size)
330                   {
331                           seq_header = 0;
332                           return 0;
333                   }
334                   pattern = (pattern << 8) | data[pos];
335           }
336           seq_header = pos - 3;
337   }
338   return seq_header;
339 }
340
341 // Demuxer methods
342 Demuxer::Demuxer()
343 {
344   if (instance) return;
345   instance = this;
346   initted = false;
347   callback = NULL;
348   arcnt = 0;
349   vid_seeking = aud_seeking = false;
350   video_pts = audio_pts = 0;
351   ispre_1_3_19 = false;
352   packetnum=0;
353   h264 = false;
354   fps = 25.0;
355 }
356
357 Demuxer::~Demuxer()
358 {
359   shutdown();
360   instance = NULL;
361 }
362
363 Demuxer* Demuxer::getInstance()
364 {
365   return instance;
366 }
367
368 int Demuxer::init(Callback* tcallback, DrainTarget* audio, DrainTarget* video, DrainTarget* teletext,
369                   ULONG demuxMemoryV, ULONG demuxMemoryA, ULONG demuxMemoryT,double infps, DVBSubtitles* tsubtitles)
370 {
371   if (!initted)
372   {
373     if ( !videostream.init(video, demuxMemoryV) ||
374          !audiostream.init(audio, demuxMemoryA) ||
375          !teletextstream.init(teletext, demuxMemoryT))
376     {
377       Log::getInstance()->log("Demuxer", Log::CRIT,
378                               "Failed to initialize demuxer");
379       shutdown();
380       return 0;
381     }
382   }
383   if (teletext) {
384       isteletextdecoded = true;
385   } else {
386       isteletextdecoded = false;
387   }
388   fps=infps;
389   reset();
390   initted = true;
391   subtitles = tsubtitles;
392   callback = tcallback;
393   return 1;
394 }
395
396 void Demuxer::reset()
397 {
398   Log::getInstance()->log("Demuxer", Log::DEBUG, "Reset called");
399   flush();
400   video_current = audio_current = teletext_current = subtitle_current = -1;
401   horizontal_size = vertical_size = 0;
402   aspect_ratio = (enum AspectRatio) 0;
403   frame_rate = bit_rate = 0;
404   ispre_1_3_19 = false;
405   h264 = false;
406   packetnum=0;
407
408   for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++)
409   {
410     avail_mpaudchan[i] = false;
411   }
412   for (int i = 0; i <= (PESTYPE_SUBSTREAM_AC3MAX - PESTYPE_SUBSTREAM_AC30); i++)
413   {
414     avail_ac3audchan[i] = false;
415   }
416   for (int i = 0; i <= (PESTYPE_SUBSTREAM_DVBSUBTITLEMAX - PESTYPE_SUBSTREAM_DVBSUBTITLE0); i++)
417   {
418     avail_dvbsubtitlechan[i] = false;
419   }
420 }
421
422 int Demuxer::shutdown()
423 {
424   videostream.shutdown();
425   audiostream.shutdown();
426   teletextstream.shutdown();
427   initted = false;
428   return 1;
429 }
430
431 void Demuxer::flush()
432 {
433   Log::getInstance()->log("Demuxer", Log::DEBUG, "Flush called");
434
435   videostream.flush();
436   audiostream.flush();
437   teletextstream.flush();
438 }
439
440 void Demuxer::flushAudio()
441 {
442   audiostream.flush();
443 }
444
445 void Demuxer::seek()
446 {
447   vid_seeking = aud_seeking = true;
448   video_pts = audio_pts = teletext_pts = 0;
449 }
450
451 void Demuxer::setAudioStream(int id)
452 {
453   audio_current = id;
454 }
455
456 void Demuxer::setVideoStream(int id)
457 {
458   video_current = id;
459 }
460
461 void Demuxer::setTeletextStream(int id)
462 {
463   teletext_current = id;
464 }
465
466 void Demuxer::setDVBSubtitleStream(int id)
467 {
468   subtitle_current = id;
469 }
470
471 void Demuxer::setAspectRatio(enum AspectRatio ar)
472 {
473   if (aspect_ratio != ar)
474   {
475     Log::getInstance()->log("Demux", Log::DEBUG,
476                             "Aspect ratio difference signalled");
477     if (++arcnt > 3) // avoid changing aspect ratio if glitch in signal
478     {
479       arcnt = 0;
480       aspect_ratio = ar;
481       if (callback) callback->call(this);
482     }
483   }
484   else
485     arcnt = 0;
486 }
487
488 bool Demuxer::writeAudio()
489 {
490   return audiostream.drain();
491 }
492
493 bool Demuxer::writeVideo()
494 {
495   return videostream.drain();
496 }
497
498 bool Demuxer::writeTeletext()
499 {
500    return teletextstream.drain();
501 }
502
503 bool Demuxer::submitPacket(PESPacket& packet)
504 {
505   UINT sent = 0;
506   UCHAR packet_type = packet.getPacketType();
507   const UCHAR* packetdata = packet.getData();
508   if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX)
509   {
510     if (video_current == -1) video_current = packet_type;
511     if (video_current == packet_type && !vid_seeking)
512         {
513         sent = videostream.put(&packetdata[0], packet.getSize(), h264?MPTYPE_VIDEO_H264:MPTYPE_VIDEO_MPEG2,packetnum);
514         if (sent) packetnum++;
515         }
516         else
517       sent = packet.getSize();
518   }
519   else if (packet_type >= PESTYPE_AUD0 && packet_type <= PESTYPE_AUDMAX)
520   {
521     if (audio_current == -1) audio_current = packet_type;
522     avail_mpaudchan[packet_type - PESTYPE_AUD0] = true;
523     if (audio_current == packet_type && !aud_seeking)
524         {
525       sent = audiostream.put(&packetdata[0], packet.getSize(), MPTYPE_MPEG_AUDIO,packetnum);
526           if (sent)  packetnum++;
527         }
528         else
529       sent = packet.getSize();
530   }
531   else if (packet_type == PESTYPE_PRIVATE_1 &&
532            packet.getSubstream() >= PESTYPE_SUBSTREAM_AC30 &&
533            packet.getSubstream() <= PESTYPE_SUBSTREAM_AC3MAX)
534   {
535     avail_ac3audchan[packet.getSubstream() - PESTYPE_SUBSTREAM_AC30] = true;
536     if (packet.getSubstream() == audio_current)
537     {
538       sent = audiostream.put(&packetdata[0], packet.getSize(), (ispre_1_3_19)? MPTYPE_AC3_PRE13 : MPTYPE_AC3,packetnum);
539           if (sent) packetnum++;
540     }
541     else
542     {
543       sent = packet.getSize();
544     }
545   }
546   else if (packet_type == PESTYPE_PRIVATE_1 &&
547            packet.getSubstream() >= PESTYPE_SUBSTREAM_DVBSUBTITLE0 &&
548            packet.getSubstream() <= PESTYPE_SUBSTREAM_DVBSUBTITLEMAX)
549   {
550     avail_dvbsubtitlechan[packet.getSubstream()-PESTYPE_SUBSTREAM_DVBSUBTITLE0]=true;
551     if (subtitle_current == -1) subtitle_current = packet.getSubstream();
552     if (subtitles && packet.getSubstream()==subtitle_current)
553     {
554          subtitles->put(packet);
555     }
556     sent = packet.getSize();
557   }
558   else if (isteletextdecoded  && packet_type == PESTYPE_PRIVATE_1 &&
559            packet.getSubstream() >= PESTYPE_SUBSTREAM_TELETEXT0 &&
560            packet.getSubstream() <= PESTYPE_SUBSTREAM_TELETEXTMAX)
561   {
562
563     if (teletext_current == -1) teletext_current = packet.getSubstream();
564     if (teletext_current == packet.getSubstream() )
565     {
566         sent = teletextstream.put(&packetdata[0], packet.getSize(), MPTYPE_TELETEXT,packetnum);
567     }
568     else 
569     {
570         sent = packet.getSize();
571     }
572   }
573   else
574   {
575     sent = packet.getSize();
576   }
577
578   if (sent < packet.getSize()) // Stream is full.
579     return false;
580   else
581     return true;
582 }
583
584 void Demuxer::parsePacketDetails(PESPacket& packet)
585 {
586     if (packet.getPacketType() >= PESTYPE_AUD0 &&
587         packet.getPacketType() <= PESTYPE_AUDMAX)
588     {
589         // Extract audio PTS if it exists
590         if (packet.hasPTS())
591         {
592             audio_pts = packet.getPTS();
593             // We continue to seek on the audio if the video PTS that we
594             // are trying to match is ahead of the audio PTS by at most
595             // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
596             if (aud_seeking && !vid_seeking &&
597                 !( (video_pts_seek > audio_pts &&
598                 video_pts_seek - audio_pts < SEEK_THRESHOLD)
599                 ||
600                 (video_pts_seek < audio_pts &&
601                 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
602             {
603                 aud_seeking = 0;
604                 Log::getInstance()->log("Demuxer", Log::DEBUG,
605                     "Leaving  audio sync: Audio PTS = %llu", audio_pts);
606             }
607         }
608     }
609     else if (packet.getPacketType() == PESTYPE_PRIVATE_1) // Private stream
610     {
611         //Inspired by vdr's device.c
612         int payload_begin = packet[8]+9;
613         unsigned char substream_id = packet[payload_begin];
614         unsigned char substream_type = substream_id & 0xF0;
615         unsigned char substream_index = substream_id & 0x1F;
616 pre_1_3_19_Recording: //This is for old recordings stuff and live TV
617         if (ispre_1_3_19)
618         {
619             substream_id = PESTYPE_PRIVATE_1;
620             substream_type = 0x80;
621             substream_index = 0;
622         }
623         switch (substream_type)
624         {
625         case 0x20://SPU
626         case 0x30://SPU
627             packet.setSubstream(substream_id);
628             break;
629         case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there?
630             break;
631         case 0x80: //ac3, currently only one ac3 track per recording supported
632             packet.setSubstream(substream_type+substream_index);
633
634             // Extract audio PTS if it exists
635             if (packet.hasPTS())
636             {
637                 audio_pts = packet.getPTS();
638                 // We continue to seek on the audio if the video PTS that we
639                 // are trying to match is ahead of the audio PTS by at most
640                 // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
641                 if (aud_seeking && !vid_seeking &&
642                     !( (video_pts_seek > audio_pts &&
643                     video_pts_seek - audio_pts < SEEK_THRESHOLD)
644                     ||
645                     (video_pts_seek < audio_pts &&
646                     video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
647                 {
648                     aud_seeking = 0;
649                     Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving  audio sync: Audio PTS = %llu", audio_pts);
650                 }
651             }
652             break;
653         case 0x10: //Teletext Is this correct?
654             packet.setSubstream(substream_id);
655             // Extract teletxt PTS if it exists
656             if (packet.hasPTS())
657             {
658                 teletext_pts = packet.getPTS();
659             }
660             break;
661         default:
662             if (!ispre_1_3_19)
663             {
664                 ispre_1_3_19=true; //switching to compat mode and live tv mode
665                 goto pre_1_3_19_Recording;
666             }
667             else
668             {
669                 packet.setSubstream(0);
670             }
671             break;
672         }
673     }
674     else if (packet.getPacketType() >= PESTYPE_VID0 &&
675         packet.getPacketType() <= PESTYPE_VIDMAX)
676     {
677         // Extract video PTS if it exists
678         if (packet.hasPTS()) video_pts = packet.getPTS();
679
680         // If there is a sequence header, extract information
681         UINT pos = packet.findSeqHeader(h264);
682         if (pos > 1)
683         {
684             if (!h264) {
685                 pos += 4;
686                 if (pos+6 >= packet.getSize()) return;
687                 horizontal_size = ((int)packet[pos] << 4) | ((int)packet[pos+1] >> 4);
688                 
689                 vertical_size = (((int)packet[pos+1] & 0xf) << 8) | (int)packet[pos+2];
690
691                 setAspectRatio((enum AspectRatio)(packet[pos+3] >> 4));
692                 frame_rate = packet[pos+3] & 0x0f;
693                 if (frame_rate >= 1 && frame_rate <= 8)
694                     frame_rate = FrameRates[frame_rate];
695                 else
696                     frame_rate = 0;
697                 bit_rate = ((int)packet[pos+4] << 10) |
698                     ((int)packet[pos+5] << 2) |
699                     ((int)packet[pos+6] >> 6);
700             } 
701             else
702             {
703                 /* Chris and Mark I know this is ugly, should we move this to a method  of PESPacket or to NALUUnit what would be better?
704                 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*/
705                 NALUUnit nalu(packet.getData()+pos,packet.getSize()-pos);
706                 profile=nalu.getBits(8);
707                 nalu.getBits(8); //constraints
708                 nalu.getBits(8); //level_idc
709                 nalu.getUe(); //seq_parameter_set_id
710                 if (profile==100 || profile==110 || profile==122 || profile==144)
711                 {
712                     if (nalu.getUe()==3)
713                     {
714                         nalu.getBits(1);
715                     }
716                     nalu.getUe(); //bit depth lume
717                     nalu.getUe(); //bit depth chrome
718                     nalu.getBits(1);
719                     if (nalu.getBits(1))
720                     {
721                         for (int i=0;i<8;i++){
722                             if (nalu.getBits(1))
723                             {
724                                 if (i<6)
725                                 {
726                                     UINT lastscale=8;
727                                     UINT nextscale=8;
728                                     for (int j=0;j<16;j++) {
729                                         if (nextscale!=0) {
730                                             UINT delta=nalu.getSe();
731                                             nextscale=(lastscale+delta+256)%256;
732                                         }
733                                         lastscale=(nextscale==0)?lastscale:nextscale;
734                                     }
735                                 }
736                                 else
737                                 {
738                                     UINT lastscale=8;
739                                     UINT nextscale=8;
740                                     for (int j=0;j<64;j++) {
741                                         if (nextscale!=0) {
742                                             UINT delta=nalu.getSe();
743                                             nextscale=(lastscale+delta+256)%256;
744                                         }
745                                         lastscale=(nextscale==0)?lastscale:nextscale;
746                                     }
747                                 }
748                             }
749                         }
750                     }
751                 }
752                 nalu.getUe(); //log2framenum
753                 UINT temp=nalu.getUe();
754                 if (temp==0) //pict order
755                     nalu.getUe();
756                 else if (temp==1) {
757                     nalu.getBits(1);
758                     nalu.getSe();
759                     nalu.getSe();
760                     UINT temp2=nalu.getUe();
761                     for (int i=0;i<temp2;i++)
762                         nalu.getSe();
763                 }
764                 nalu.getUe(); //Num refframes
765                 nalu.getBits(1);
766                 horizontal_size=(nalu.getUe()+1)*16;
767                 
768                 vertical_size=(nalu.getUe()+1)*16;
769                 int interlaced=nalu.getBits(1);
770                 vertical_size*=(2-interlaced);
771                 
772                 if (!interlaced) nalu.getBits(1);
773                 nalu.getBits(1);
774                 if (nalu.getBits(1))
775                 {
776                     nalu.getUe();
777                     nalu.getUe();
778                     nalu.getUe();
779                     nalu.getUe();
780                 }
781                 if (nalu.getBits(1))
782                 {
783                     if (nalu.getBits(1))
784                     {
785                         UINT aspectratioidc=nalu.getBits(8);
786                         bool hasaspect=false;
787                         const float aspects[]={1., 1./1.,12./11.,10./11.,16./11.,40./33.,
788                             24./11.,20./11.,32./11.,80./33.,18./11.,15./11.,64./33.,160./99.,4./3.,3./2.,2./1.};
789                       
790                         float aspectratio=((float) horizontal_size)/((float) vertical_size);
791                         if (aspectratioidc<=16) 
792                         {
793                             hasaspect=true;
794                             aspectratio*=aspects[aspectratioidc];
795                            
796                         }
797                         else if (aspectratioidc==255)
798                         {
799                             int t_sar_width=nalu.getBits(16);
800                             int t_sar_height=nalu.getBits(16);
801                             if (t_sar_width!=0 && t_sar_height!=0)
802                             {
803                                 hasaspect=true;
804                                 aspectratio*=((float)t_sar_width)/((float)t_sar_height);
805                             }
806                         }
807                         if (hasaspect)
808                         {
809                             if (fabs(aspectratio-16./9.)<0.1) setAspectRatio(ASPECT_16_9);
810                             else if (fabs(aspectratio-4./3.)<0.1) setAspectRatio(ASPECT_4_3);
811                         }
812                     }
813
814                 }
815
816             }
817            
818             if (vid_seeking)
819             {
820                 vid_seeking = 0;
821                 video_pts_seek = video_pts;
822                 Log::getInstance()->log("Demuxer", Log::DEBUG,
823                     "Entering audio sync: Video PTS = %llu", video_pts);
824                 Log::getInstance()->log("Demuxer", Log::DEBUG,
825                     "Entering audio sync: Audio PTS = %llu", audio_pts);
826             }
827             return;
828         } 
829     }
830 }
831
832 UINT Demuxer::stripAudio(UCHAR* buf, UINT len)
833 {
834   UINT read_pos = 0, write_pos = 0;
835   UINT pattern, packet_length;
836   if (len < 4) return 0;
837   pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
838   while (read_pos + 7 <= len)
839   {
840     pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
841     if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
842       read_pos++;
843     else
844     {
845       packet_length = ((buf[read_pos+4] << 8) | (buf[read_pos+5])) + 6;
846       if (read_pos + packet_length > len)
847         read_pos = len;
848       else
849       {
850         if (read_pos != write_pos)
851           memmove(buf+write_pos, buf+read_pos, packet_length);
852         read_pos += packet_length;
853         write_pos += packet_length;
854         pattern = (buf[read_pos] << 16) | (buf[read_pos+1] << 8)
855                                         | (buf[read_pos+2]);
856       }
857     }
858   }
859   return write_pos;
860 }
861
862 bool Demuxer::scanForVideo(UCHAR* buf, UINT len, bool &ish264)
863 {
864   UINT pos = 3;
865   UINT pattern;
866   ish264=false;
867   if (len < 4) return false;
868   pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
869   while (pos < len)
870   {
871     pattern = ((pattern & 0xFFFFFF) << 8) | buf[pos++];
872     if (pattern >= (0x100|PESTYPE_VID0) && pattern <= (0x100|PESTYPE_VIDMAX))
873       return true;
874   }
875   return false;
876 }
877
878 bool* Demuxer::getmpAudioChannels()
879 {
880   return avail_mpaudchan;
881 }
882
883 bool* Demuxer::getac3AudioChannels()
884 {
885   return avail_ac3audchan;
886 }
887
888 bool* Demuxer::getSubtitleChannels()
889 {
890   return avail_dvbsubtitlechan;
891 }
892
893 int Demuxer::getselSubtitleChannel()
894 {
895   return subtitle_current;
896 }
897
898 int Demuxer::getselAudioChannel()
899 {
900   return audio_current;
901 }
902
903