2 Copyright 2005-2008 Mark Calderbank
3 Copyright 2007 Marten Richter (AC3 support)
5 This file is part of VOMP.
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.
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.
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.
25 #include "dvbsubtitles.h"
32 #define DEMUXER_SEQ_HEAD 0x000001B3
33 #define DEMUXER_PIC_HEAD 0x00000101
34 #define DEMUXER_SEQ_EXT_HEAD 0x000001B5
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
42 #define SEEK_THRESHOLD 150000 // About 1.5 seconds
45 const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
46 Demuxer* Demuxer::instance = NULL;
50 NALUUnit(const UCHAR* buf,UINT length_buf);
53 inline UINT getBits(UINT num_bits);
56 bool isEonalu() {return eonalu;};
57 int getPos(){return pos;};
69 NALUUnit::NALUUnit(const UCHAR *buf, UINT length_buf)
81 UINT pattern =(((UINT)buf[ 0] << 16) |
85 while (pattern != 0x000001)
87 if (++nalu_start >= length_buf) return;
88 pattern = ((pattern << 8) | buf[nalu_start])&0x00FFFFFF;
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;
94 while (pattern != 0x000001 && pattern != 0x000000)
96 if (++nalu_end >= length_buf) { nalu_end+=3;break;};
97 pattern = ((pattern << 8) | buf[nalu_end])&0x00FFFFFF;
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);
108 NALUUnit::~NALUUnit()
110 if (nalu_buf) free(nalu_buf);
113 inline UINT NALUUnit::getBits(UINT num_bits)
115 if (num_bits==0) return 0; //???
116 UINT remain_bits=num_bits;
118 //May be slow, but should work!
119 while (remain_bits>0) {
123 last_bytes=(last_bytes<<8) & nalu_buf[pos];
124 if ((last_bytes & 0x00FFFFFF) == 0x000003) pos++; //emulation prevention byte
127 working_byte=nalu_buf[pos];
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;
153 UINT NALUUnit::getUe()
157 for( bit = 0; !bit && !eonalu; leadbits++ )
159 if (eonalu) return true;
160 return ((1 << leadbits)-1)+getBits(leadbits);
163 int NALUUnit::getSe()
166 if (input==0) return 0;
167 int output=((input+1)>>1);
168 if (input & 0x1) output*=-1;
174 static const int PESPacket_initial_size = 2000;
177 PESPacket::PESPacket()
179 data_size = PESPacket_initial_size;
180 data = (UCHAR*)malloc(data_size);
187 PESPacket::PESPacket(const PESPacket& packet)
192 PESPacket& PESPacket::operator=(const PESPacket& packet)
196 if (data) free(data);
202 PESPacket::~PESPacket()
204 if (data) free(data);
207 void PESPacket::copyFrom(const PESPacket& packet)
209 length = packet.length;
211 packetType = packet.packetType;
212 substream = packet.substream;
213 seq_header = packet.seq_header;
215 data = (UCHAR*)malloc(data_size);
216 memcpy(data, packet.data, data_size);
219 void PESPacket::init(UCHAR type, UCHAR sub)
223 data[4] = data[5] = 0;
227 seq_header = 1; // Unknown seq_header status
231 void PESPacket::truncate()
233 init(packetType,substream);
238 int PESPacket::write(const UCHAR *buf, int len)
242 if (size + len > 0x10000) return 0;
243 if (size + len > data_size)
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);
250 memcpy(data + size, buf, 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'
260 ULLONG PESPacket::getPTS() const
262 if ( ( (packetType >= Demuxer::PESTYPE_AUD0 &&
263 packetType <= Demuxer::PESTYPE_AUDMAX)
265 (packetType >= Demuxer::PESTYPE_VID0 &&
266 packetType <= Demuxer::PESTYPE_VIDMAX)
268 packetType == Demuxer::PESTYPE_PRIVATE_1
270 && size >= 14 && data[7] & 0x80)
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 );
278 else return PTS_INVALID;
281 UCHAR PESPacket::operator[] (UINT index) const
289 UINT PESPacket::findPictureHeader(bool h264) const
291 if (size < 12) return 0;
292 UINT pattern = ( ((UINT)data[ 8] << 24) |
293 ((UINT)data[ 9] << 16) |
294 ((UINT)data[10] << 8) |
299 while (pattern != DEMUXER_H264_ACCESS_UNIT)
301 if (++pos >= size) return 0;
302 pattern = (pattern << 8) | data[pos];
306 while (pattern != DEMUXER_PIC_HEAD)
308 if (++pos >= size) return 0;
309 pattern = (pattern << 8) | data[pos];
315 UINT PESPacket::countPictureHeaders(bool h264, struct PictCountInfo& pinfo) const
317 if (size < 12) return 0;
318 UINT pattern = ( ((UINT)data[ 8] << 24) |
319 ((UINT)data[ 9] << 16) |
320 ((UINT)data[10] << 8) |
325 //inspired by vdr algorithm for frame couting by Klaus Schmidinger
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 ) {
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
341 pinfo.separate_color_plane_flag=0;
342 if (profile==100 || profile==110 || profile==122 || profile==144)
347 pinfo.separate_color_plane_flag=nalu.getBits(1);
349 nalu.getUe(); //bit depth lume
350 nalu.getUe(); //bit depth chrome
354 for (int i=0;i<8;i++){
361 for (int j=0;j<16;j++) {
363 UINT delta=nalu.getSe();
364 nextscale=(lastscale+delta+256)%256;
366 lastscale=(nextscale==0)?lastscale:nextscale;
373 for (int j=0;j<64;j++) {
375 UINT delta=nalu.getSe();
376 nextscale=(lastscale+delta+256)%256;
378 lastscale=(nextscale==0)?lastscale:nextscale;
386 pinfo.log2_max_frame_num=nalu.getUe()+4; //log2framenum
387 UINT temp=nalu.getUe();
388 if (temp==0) //pict order
394 UINT temp2=nalu.getUe();
395 for (int i=0;i<temp2;i++)
398 nalu.getUe(); //Num refframes
402 pinfo.frame_mbs_only_flag=nalu.getBits(1);
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) {
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
429 pinfo.hasaccessunit=false;
439 pattern = (pattern << 8) | data[pos];
440 if (pattern==DEMUXER_PIC_HEAD) count++;
446 UINT PESPacket::findSeqHeader(bool h264) const
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) |
456 while ((pattern & 0xFFFFFF1F) != DEMUXER_H264_SEQ_PARAMETER_SET)
463 pattern = (pattern << 8) | data[pos];
465 seq_header = pos - 3;
469 while (pattern != DEMUXER_SEQ_HEAD)
476 pattern = (pattern << 8) | data[pos];
478 seq_header = pos - 3;
483 UINT PESPacket::findSeqExtHeader(bool h264) const
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) |
493 while ((pattern & 0xFFFFFF1F) != DEMUXER_H264_SUB_ENHANCEMENT_INF)
500 pattern = (pattern << 8) | data[pos];
502 seq_header = pos - 3;
506 while (pattern != DEMUXER_SEQ_EXT_HEAD && (data[pos+1]&0xf0)!=0x10)
508 if (++pos >= (size-1))
513 pattern = (pattern << 8) | data[pos];
515 seq_header = pos - 3;
523 if (instance) return;
528 vid_seeking = aud_seeking = false;
529 video_pts = audio_pts = 0;
530 ispre_1_3_19 = false;
544 Demuxer* Demuxer::getInstance()
549 int Demuxer::init(Callback* tcallback, DrainTarget* audio, DrainTarget* video, DrainTarget* teletext,
550 ULONG demuxMemoryV, ULONG demuxMemoryA, ULONG demuxMemoryT,double infps, DVBSubtitles* tsubtitles)
554 if ( !videostream.init(video, demuxMemoryV) ||
555 !audiostream.init(audio, demuxMemoryA) ||
556 !teletextstream.init(teletext, demuxMemoryT))
558 Log::getInstance()->log("Demuxer", Log::CRIT,
559 "Failed to initialize demuxer");
565 isteletextdecoded = true;
567 isteletextdecoded = false;
572 subtitles = tsubtitles;
573 callback = tcallback;
577 void Demuxer::reset()
579 Log::getInstance()->log("Demuxer", Log::DEBUG, "Reset called");
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;
587 frame_rate = bit_rate = 0;
588 ispre_1_3_19 = false;
594 for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++)
596 avail_mpaudchan[i] = false;
598 for (int i = 0; i <= (PESTYPE_SUBSTREAM_AC3MAX - PESTYPE_SUBSTREAM_AC30); i++)
600 avail_ac3audchan[i] = false;
602 for (int i = 0; i <= (PESTYPE_SUBSTREAM_DVBSUBTITLEMAX - PESTYPE_SUBSTREAM_DVBSUBTITLE0); i++)
604 avail_dvbsubtitlechan[i] = false;
608 int Demuxer::shutdown()
610 videostream.shutdown();
611 audiostream.shutdown();
612 teletextstream.shutdown();
617 void Demuxer::flush()
619 Log::getInstance()->log("Demuxer", Log::DEBUG, "Flush called");
623 teletextstream.flush();
626 void Demuxer::flushAudio()
633 vid_seeking = aud_seeking = true;
634 video_pts = audio_pts = teletext_pts = 0;
637 void Demuxer::setAudioStream(int id)
642 void Demuxer::setVideoStream(int id)
647 void Demuxer::setTeletextStream(int id)
649 teletext_current = id;
652 void Demuxer::setDVBSubtitleStream(int id)
654 subtitle_current = id;
657 void Demuxer::setAspectRatio(enum AspectRatio ar, int taspectx, int taspecty)
659 if ((aspect_ratio != ar) || (parx != taspectx) || (pary != taspecty) )
661 Log::getInstance()->log("Demux", Log::DEBUG,
662 "Aspect ratio difference signalled");
663 if (++arcnt > 3) // avoid changing aspect ratio if glitch in signal
669 if (callback) callback->call(this);
676 bool Demuxer::writeAudio(bool * dataavail)
678 return audiostream.drain(dataavail);
681 bool Demuxer::writeVideo(bool * dataavail)
683 return videostream.drain(dataavail);
686 bool Demuxer::writeTeletext(bool * dataavail)
688 return teletextstream.drain(dataavail);
691 bool Demuxer::submitPacket(PESPacket& packet)
694 UCHAR packet_type = packet.getPacketType();
695 const UCHAR* packetdata = packet.getData();
696 if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX)
698 if (video_current == -1) video_current = packet_type;
699 if (video_current == packet_type && !vid_seeking)
701 sent = videostream.put(&packetdata[0], packet.getSize(), h264?MPTYPE_VIDEO_H264:MPTYPE_VIDEO_MPEG2,packetnum);
702 if (sent) packetnum++;
705 sent = packet.getSize();
707 else if (packet_type >= PESTYPE_AUD0 && packet_type <= PESTYPE_AUDMAX)
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)
714 UCHAR type=MPTYPE_MPEG_AUDIO;
719 type=MPTYPE_MPEG_AUDIO; break;
721 type=MPTYPE_AAC_LATM; break;
723 sent = audiostream.put(&packetdata[0], packet.getSize(), type,packetnum);
724 if (sent) packetnum++;
727 sent = packet.getSize();
729 else if (packet_type == PESTYPE_PRIVATE_1 &&
730 packet.getSubstream() >= PESTYPE_SUBSTREAM_AC30 &&
731 packet.getSubstream() <= PESTYPE_SUBSTREAM_AC3MAX)
733 avail_ac3audchan[packet.getSubstream() - PESTYPE_SUBSTREAM_AC30] = true;
734 if (packet.getSubstream() == audio_current)
736 sent = audiostream.put(&packetdata[0], packet.getSize(), (ispre_1_3_19 || livetv)? MPTYPE_AC3_PRE13 : MPTYPE_AC3,packetnum);
737 if (sent) packetnum++;
741 sent = packet.getSize();
744 else if (packet_type == PESTYPE_PRIVATE_1 &&
745 packet.getSubstream() >= PESTYPE_SUBSTREAM_DVBSUBTITLE0 &&
746 packet.getSubstream() <= PESTYPE_SUBSTREAM_DVBSUBTITLEMAX)
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)
752 subtitles->put(packet);
754 sent = packet.getSize();
756 else if (isteletextdecoded && packet_type == PESTYPE_PRIVATE_1 &&
757 packet.getSubstream() >= PESTYPE_SUBSTREAM_TELETEXT0 &&
758 packet.getSubstream() <= PESTYPE_SUBSTREAM_TELETEXTMAX)
761 if (teletext_current == -1) teletext_current = packet.getSubstream();
762 if (teletext_current == packet.getSubstream())
764 sent = teletextstream.put(&packetdata[0], packet.getSize(), MPTYPE_TELETEXT,packetnum);
768 sent = packet.getSize();
773 sent = packet.getSize();
776 if (sent < packet.getSize()) // Stream is full.
782 void Demuxer::parsePacketDetails(PESPacket& packet)
784 if (packet.getPacketType() >= PESTYPE_AUD0 &&
785 packet.getPacketType() <= PESTYPE_AUDMAX)
787 // Extract audio PTS if it exists
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)
798 (video_pts_seek < audio_pts &&
799 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
802 Log::getInstance()->log("Demuxer", Log::DEBUG,
803 "Leaving audio sync: Audio PTS = %llu", audio_pts);
807 else if (packet.getPacketType() == PESTYPE_PRIVATE_1) // Private stream
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
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;
824 substream_id = PESTYPE_PRIVATE_1;
825 substream_type = 0x80;
830 switch (substream_type)
834 packet.setSubstream(substream_id);
836 case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there?
838 case 0x80: //ac3, currently only one ac3 track per recording supported
839 packet.setSubstream(substream_type+substream_index);
841 // Extract audio PTS if it exists
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)
852 (video_pts_seek < audio_pts &&
853 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
856 Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving audio sync: Audio PTS = %llu", audio_pts);
860 case 0x10: //Teletext Is this correct?
861 packet.setSubstream(substream_id);
862 // Extract teletxt PTS if it exists
865 teletext_pts = packet.getPTS();
871 ispre_1_3_19=true; //switching to compat mode and live tv mode
872 goto pre_1_3_19_Recording;
876 packet.setSubstream(0);
882 else if (packet.getPacketType() >= PESTYPE_VID0 &&
883 packet.getPacketType() <= PESTYPE_VIDMAX)
885 // Extract video PTS if it exists
886 if (packet.hasPTS()) video_pts = packet.getPTS();
888 // If there is a sequence header, extract information
889 UINT pos = packet.findSeqHeader(h264);
894 if (pos+6 >= packet.getSize()) return;
895 horizontal_size = ((int)packet[pos] << 4) | ((int)packet[pos+1] >> 4);
897 vertical_size = (((int)packet[pos+1] & 0xf) << 8) | (int)packet[pos+2];
899 enum AspectRatio aspect=(enum AspectRatio)(packet[pos+3] >> 4);
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];
906 aspectx=aspectDARx*vertical_size;
907 aspecty=aspectDARy*horizontal_size;
911 // Log::getInstance()->log("Demuxer", Log::DEBUG, "PAR test1 %d %d %d %d ", aspectx,aspecty,commona,commonb);
917 commonb=commona%commonb;
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);
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];
930 bit_rate = ((int)packet[pos+4] << 10) |
931 ((int)packet[pos+5] << 2) |
932 ((int)packet[pos+6] >> 6);
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
944 if (profile==100 || profile==110 || profile==122 || profile==144)
951 nalu.getUe(); //bit depth lume
952 nalu.getUe(); //bit depth chrome
956 for (int i=0;i<8;i++){
963 for (int j=0;j<16;j++) {
965 UINT delta=nalu.getSe();
966 nextscale=(lastscale+delta+256)%256;
968 lastscale=(nextscale==0)?lastscale:nextscale;
975 for (int j=0;j<64;j++) {
977 UINT delta=nalu.getSe();
978 nextscale=(lastscale+delta+256)%256;
980 lastscale=(nextscale==0)?lastscale:nextscale;
991 chromunitx=chromunity=1; break;
993 chromunitx=chromunity=2; break;
995 chromunitx=2;chromunity=1; break;
997 chromunitx=chromunity=1; break;
1000 nalu.getUe(); //log2framenum
1001 UINT temp=nalu.getUe();
1002 if (temp==0) //pict order
1008 UINT temp2=nalu.getUe();
1009 for (int i=0;i<temp2;i++)
1012 nalu.getUe(); //Num refframes
1014 horizontal_size=(nalu.getUe()+1)*16;
1016 vertical_size=(nalu.getUe()+1)*16;
1017 int tinterlaced=nalu.getBits(1);
1018 vertical_size*=(2-tinterlaced);
1019 interlaced=!tinterlaced;
1021 if (!tinterlaced) nalu.getBits(1);
1023 if (nalu.getBits(1))
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;
1030 if (nalu.getBits(1))
1032 if (nalu.getBits(1))
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};
1043 float aspectratio=((float) horizontal_size)/((float) vertical_size);
1044 if (aspectratioidc<=16)
1047 aspectratio*=aspects[aspectratioidc];
1048 aspectx=aspectsx[aspectratioidc];
1049 aspecty=aspectsy[aspectratioidc];
1052 else if (aspectratioidc==255)
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)
1059 aspectratio*=((float)t_sar_width)/((float)t_sar_height);
1060 aspectx=t_sar_width;
1061 aspecty=t_sar_height;
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);
1075 UINT posext = packet.findSeqExtHeader(h264);
1078 interlaced=!(packet[pos+1] & 0x08); //really simple
1079 // if more than full hd is coming we need to add additional parsers here
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;
1089 unsigned int payloadsize=0;
1091 while (payloadadd==0xFF && !nalu.isEonalu()) {
1092 payloadadd=nalu.getBits(8);
1093 payloadsize+=payloadadd;
1095 switch (payloadtype) {
1096 case 1: { // picture timing SEI
1100 while (payloadsize) { // not handled skip
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);
1129 UINT Demuxer::stripAudio(UCHAR* buf, UINT len)
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)
1137 pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
1138 if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
1142 packet_length = ((buf[read_pos+4] << 8) | (buf[read_pos+5])) + 6;
1143 if (read_pos + packet_length > len)
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]);
1159 void Demuxer::changeTimes(UCHAR* buf, UINT len,UINT playtime)
1161 UINT pattern, packet_length;
1163 if (len < 4) return;
1164 pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
1165 while (read_pos + 7 <= len)
1167 pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
1168 if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
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 );
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 );
1191 read_pos += packet_length;
1192 pattern = (buf[read_pos] << 16) | (buf[read_pos+1] << 8)
1193 | (buf[read_pos+2]);
1199 bool Demuxer::scanForVideo(UCHAR* buf, UINT len, bool &ish264)
1204 if (len < 4) return false;
1205 pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
1208 pattern = ((pattern & 0xFFFFFF) << 8) | buf[pos++];
1209 if (pattern >= (0x100|PESTYPE_VID0) && pattern <= (0x100|PESTYPE_VIDMAX))
1215 bool* Demuxer::getmpAudioChannels()
1217 return avail_mpaudchan;
1220 bool* Demuxer::getac3AudioChannels()
1222 return avail_ac3audchan;
1225 bool* Demuxer::getSubtitleChannels()
1227 return avail_dvbsubtitlechan;
1230 int Demuxer::getselSubtitleChannel()
1232 return subtitle_current;
1235 int Demuxer::getselAudioChannel()
1237 return audio_current;