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"
34 #define DEMUXER_SEQ_HEAD 0x000001B3
35 #define DEMUXER_PIC_HEAD 0x00000101
36 #define DEMUXER_SEQ_EXT_HEAD 0x000001B5
38 #define DEMUXER_H264_ACCESS_UNIT 0x00000109
39 #define DEMUXER_H264_SEQ_PARAMETER_SET 0x00000107
40 #define DEMUXER_H264_SUB_ENHANCEMENT_INF 0x00000106
41 #define DEMUXER_H264_CODED_SLICE_IDR 0x00000105
42 #define DEMUXER_H264_CODED_SLICE_NON_IDR 0x00000101
44 #define SEEK_THRESHOLD 150000 // About 1.5 seconds
46 static const char* TAG = "Demuxer";
49 const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
50 Demuxer* Demuxer::instance = NULL;
54 NALUUnit(const u1* buf,u4 length_buf);
57 inline u4 getBits(u4 num_bits);
60 bool isEonalu() {return eonalu;};
61 int getPos(){return pos;};
73 NALUUnit::NALUUnit(const u1 *buf, u4 length_buf)
85 u4 pattern =(((u4)buf[ 0] << 16) |
89 while (pattern != 0x000001)
91 if (++nalu_start >= length_buf) return;
92 pattern = ((pattern << 8) | buf[nalu_start])&0x00FFFFFF;
94 nalu_end=nalu_start+1;
95 if (nalu_end >= length_buf) return; // input buffer too small. corrupt data? ignore.
96 pattern = ((pattern << 8) | buf[nalu_end])&0x00FFFFFF;
98 while (pattern != 0x000001 && pattern != 0x000000)
100 if (++nalu_end >= length_buf) { nalu_end+=3;break;};
101 pattern = ((pattern << 8) | buf[nalu_end])&0x00FFFFFF;
104 nalu_end=std::min(length_buf-1,nalu_end);
105 if (nalu_end <= nalu_start) return; // input buffer too small. corrupt data? ignore.
106 nalu_length=nalu_end-nalu_start;
107 nalu_buf=(u1*)malloc(nalu_length);
108 memcpy(nalu_buf,buf+nalu_start,nalu_length);
112 NALUUnit::~NALUUnit()
114 if (nalu_buf) free(nalu_buf);
117 inline u4 NALUUnit::getBits(u4 num_bits)
119 if (num_bits==0) return 0; //???
120 u4 remain_bits=num_bits;
122 //May be slow, but should work!
123 while (remain_bits>0) {
127 last_bytes=(last_bytes<<8) & nalu_buf[pos];
128 if ((last_bytes & 0x00FFFFFF) == 0x000003) pos++; //emulation prevention byte
131 working_byte=nalu_buf[pos];
147 u4 fetch_bits=std::min(remain_bits, static_cast<u4>(8-bit_pos));
148 work=work <<fetch_bits;
149 //work|=((working_byte>>bit_pos) & (0xFF>>(8-fetch_bits)));
150 work|=(working_byte &(0xFF>>(bit_pos)))>>(8-fetch_bits-bit_pos);
151 remain_bits-=fetch_bits;
152 bit_pos=(bit_pos+fetch_bits)%8;
161 for( bit = 0; !bit && !eonalu; leadbits++ )
163 if (eonalu) return 0;
164 return ((1 << leadbits)-1)+getBits(leadbits);
167 int NALUUnit::getSe()
170 if (input==0) return 0;
171 int output=((input+1)>>1);
172 if (input & 0x1) output*=-1;
178 static const int PESPacket_initial_size = 2000;
181 PESPacket::PESPacket()
183 data_size = PESPacket_initial_size;
184 data = (u1*)malloc(data_size);
191 PESPacket::PESPacket(const PESPacket& packet)
196 PESPacket& PESPacket::operator=(const PESPacket& packet)
200 if (data) free(data);
206 PESPacket::~PESPacket()
208 if (data) free(data);
211 void PESPacket::copyFrom(const PESPacket& packet)
213 length = packet.length;
215 packetType = packet.packetType;
216 substream = packet.substream;
217 seq_header = packet.seq_header;
219 data = (u1*)malloc(data_size);
220 memcpy(data, packet.data, data_size);
223 void PESPacket::init(u1 type, u1 sub)
227 data[4] = data[5] = 0;
231 seq_header = 1; // Unknown seq_header status
235 void PESPacket::truncate()
237 init(packetType,substream);
242 int PESPacket::write(const u1 *buf, int len)
246 if (size + len > 0x10000) return 0;
247 if (size + len > data_size)
249 u4 new_data_size = std::max(data_size + data_size / 2, data_size + len);
250 if (new_data_size > 0x10000) new_data_size = 0x10000;
251 data_size = new_data_size;
252 data = (u1*)realloc(data, data_size);
254 memcpy(data + size, buf, len);
257 data[4] = (length >> 8);
258 data[5] = (length & 0xFF);
259 // We have added data - reset seq_header indicator if necessary
260 if (seq_header == 0) seq_header = 1; // Reset to 'unknown'
264 u8 PESPacket::getPTS() const
266 if ( ( (packetType >= Demuxer::PESTYPE_AUD0 &&
267 packetType <= Demuxer::PESTYPE_AUDMAX)
269 (packetType >= Demuxer::PESTYPE_VID0 &&
270 packetType <= Demuxer::PESTYPE_VIDMAX)
272 packetType == Demuxer::PESTYPE_PRIVATE_1
274 && size >= 14 && data[7] & 0x80)
276 return ( (u8)(data[ 9] & 0x0E) << 29) |
277 ( (u8)(data[10]) << 22 ) |
278 ( (u8)(data[11] & 0xFE) << 14 ) |
279 ( (u8)(data[12]) << 7 ) |
280 ( (u8)(data[13] & 0xFE) >> 1 );
282 else return PTS_INVALID;
285 u1 PESPacket::operator[] (u4 index) const
293 u4 PESPacket::findPictureHeader(bool h264) const
295 if (size < 12) return 0;
296 u4 pattern = ( ((u4)data[ 8] << 24) |
297 ((u4)data[ 9] << 16) |
298 ((u4)data[10] << 8) |
303 while (pattern != DEMUXER_H264_ACCESS_UNIT)
305 if (++pos >= size) return 0;
306 pattern = (pattern << 8) | data[pos];
310 while (pattern != DEMUXER_PIC_HEAD)
312 if (++pos >= size) return 0;
313 pattern = (pattern << 8) | data[pos];
319 u4 PESPacket::countPictureHeaders(bool h264, struct PictCountInfo& pinfo) const
321 if (size < 12) return 0;
322 u4 pattern = ( ((u4)data[ 8] << 24) |
323 ((u4)data[ 9] << 16) |
324 ((u4)data[10] << 8) |
329 //inspired by vdr algorithm for frame couting by Klaus Schmidinger
333 pattern = (pattern << 8) | data[pos];
334 if ((pattern &0xFFFFFF00)==0x00000100) {
335 u4 testpattern=(pattern& 0xFFFFFF1f);
336 if (testpattern==DEMUXER_H264_ACCESS_UNIT) pinfo.hasaccessunit=true;
337 else if (testpattern==DEMUXER_H264_SEQ_PARAMETER_SET ) {
339 NALUUnit nalu(data+pos-3,getSize()-pos+3);
340 int profile=nalu.getBits(8);
341 nalu.getBits(8); //constraints
342 nalu.getBits(8); //level_idc
343 nalu.getUe(); //seq_parameter_set_id
345 pinfo.separate_color_plane_flag=0;
346 if (profile==100 || profile==110 || profile==122 || profile==144)
351 pinfo.separate_color_plane_flag=nalu.getBits(1);
353 nalu.getUe(); //bit depth lume
354 nalu.getUe(); //bit depth chrome
358 for (int i=0;i<8;i++){
365 for (int j=0;j<16;j++) {
367 u4 delta=nalu.getSe();
368 nextscale=(lastscale+delta+256)%256;
370 lastscale=(nextscale==0)?lastscale:nextscale;
377 for (int j=0;j<64;j++) {
379 u4 delta=nalu.getSe();
380 nextscale=(lastscale+delta+256)%256;
382 lastscale=(nextscale==0)?lastscale:nextscale;
390 u4 checkMaxFrameNum = nalu.getUe() + 4; //log2framenum
392 if (checkMaxFrameNum < 13) {
393 pinfo.log2_max_frame_num = checkMaxFrameNum;
401 u4 temp=nalu.getUe();
402 if (temp==0) //pict order
408 u4 temp2=nalu.getUe();
409 for (u4 i=0;i<temp2;i++)
412 nalu.getUe(); //Num refframes
416 pinfo.frame_mbs_only_flag=nalu.getBits(1);
420 } if (testpattern==DEMUXER_H264_CODED_SLICE_IDR || testpattern==DEMUXER_H264_CODED_SLICE_NON_IDR ) {
421 /* LogNT::getInstance()->error(TAG,
422 "Has slice %d %d %d %d %d",pinfo.hasaccessunit, pinfo.hassps,pinfo.frame_mbs_only_flag,pinfo.separate_color_plane_flag,
423 pinfo.log2_max_frame_num);*/
424 if (pinfo.hasaccessunit && pinfo.hassps) {
426 NALUUnit nalu(data+pos-3,getSize()-pos+3);
427 nalu.getUe();// first_mb_in_slice
428 nalu.getUe();//sliectype
429 if (!pinfo.frame_mbs_only_flag) {
430 nalu.getUe(); //pic_paramter_set_id
431 if (pinfo.separate_color_plane_flag) nalu.getBits(2);
432 nalu.getBits(pinfo.log2_max_frame_num);
433 //if (!frame_mbs_only_flag)
434 if (nalu.getBits(1)) { //field_picture
435 if (!nalu.getBits(1)) { //bottom_field
443 pinfo.hasaccessunit=false;
453 pattern = (pattern << 8) | data[pos];
454 if (pattern==DEMUXER_PIC_HEAD) count++;
460 u4 PESPacket::findSeqHeader(bool h264) const
462 if (seq_header != 1) return seq_header;
463 if (size < 12) return 0;
464 u4 pattern = ( ((u4)data[ 8] << 24) |
465 ((u4)data[ 9] << 16) |
466 ((u4)data[10] << 8) |
470 while ((pattern & 0xFFFFFF1F) != DEMUXER_H264_SEQ_PARAMETER_SET)
477 pattern = (pattern << 8) | data[pos];
479 seq_header = pos - 3;
483 while (pattern != DEMUXER_SEQ_HEAD)
490 pattern = (pattern << 8) | data[pos];
492 seq_header = pos - 3;
497 u4 PESPacket::findSeqExtHeader(bool h264) const
499 if (seq_header != 1) return seq_header;
500 if (size < 12) return 0;
501 u4 pattern = ( ((u4)data[ 8] << 24) |
502 ((u4)data[ 9] << 16) |
503 ((u4)data[10] << 8) |
507 while ((pattern & 0xFFFFFF1F) != DEMUXER_H264_SUB_ENHANCEMENT_INF)
514 pattern = (pattern << 8) | data[pos];
516 seq_header = pos - 3;
520 while (pattern != DEMUXER_SEQ_EXT_HEAD && (data[pos+1]&0xf0)!=0x10)
522 if (++pos >= (size-1))
527 pattern = (pattern << 8) | data[pos];
529 seq_header = pos - 3;
537 if (instance) return;
542 vid_seeking = aud_seeking = false;
543 video_pts = audio_pts = 0;
544 ispre_1_3_19 = false;
558 Demuxer* Demuxer::getInstance()
563 int Demuxer::init(Callback* tcallback, DrainTarget* audio, DrainTarget* video, DrainTarget* teletext,
564 u4 demuxMemoryV, u4 demuxMemoryA, u4 demuxMemoryT,double infps, DVBSubtitles* tsubtitles)
568 if ( !videostream.init(video, demuxMemoryV) ||
569 !audiostream.init(audio, demuxMemoryA) ||
570 !teletextstream.init(teletext, demuxMemoryT))
572 LogNT::getInstance()->crit(TAG, "Failed to initialize demuxer");
578 isteletextdecoded = true;
580 isteletextdecoded = false;
585 subtitles = tsubtitles;
586 callback = tcallback;
590 void Demuxer::reset()
592 LogNT::getInstance()->debug(TAG, "Reset called");
594 video_current = audio_current = teletext_current = subtitle_current = -1;
595 horizontal_size = vertical_size = 0;
596 interlaced=true; // default is true
597 aspect_ratio = (enum AspectRatio) 0;
600 frame_rate = bit_rate = 0;
601 ispre_1_3_19 = false;
607 for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++)
609 avail_mpaudchan[i] = false;
611 for (int i = 0; i <= (PESTYPE_SUBSTREAM_AC3MAX - PESTYPE_SUBSTREAM_AC30); i++)
613 avail_ac3audchan[i] = false;
615 for (int i = 0; i <= (PESTYPE_SUBSTREAM_DVBSUBTITLEMAX - PESTYPE_SUBSTREAM_DVBSUBTITLE0); i++)
617 avail_dvbsubtitlechan[i] = false;
621 int Demuxer::shutdown()
623 videostream.shutdown();
624 audiostream.shutdown();
625 teletextstream.shutdown();
630 void Demuxer::flush()
632 LogNT::getInstance()->debug(TAG, "Flush called");
636 teletextstream.flush();
639 void Demuxer::flushAudio()
646 vid_seeking = aud_seeking = true;
647 video_pts = audio_pts = teletext_pts = 0;
650 void Demuxer::setAudioStream(int id)
655 void Demuxer::setVideoStream(int id)
660 void Demuxer::setTeletextStream(int id)
662 teletext_current = id;
665 void Demuxer::setDVBSubtitleStream(int id)
667 subtitle_current = id;
670 void Demuxer::setAspectRatio(enum AspectRatio ar, int taspectx, int taspecty)
672 if ((aspect_ratio != ar) || (parx != taspectx) || (pary != taspecty) )
674 LogNT::getInstance()->debug(TAG, "Aspect ratio difference signalled");
675 if (++arcnt > 3) // avoid changing aspect ratio if glitch in signal
681 if (callback) callback->call(this);
688 bool Demuxer::writeAudio(bool * dataavail)
690 return audiostream.drain(dataavail);
693 bool Demuxer::writeVideo(bool * dataavail)
695 return videostream.drain(dataavail);
698 bool Demuxer::writeTeletext(bool * dataavail)
700 return teletextstream.drain(dataavail);
703 bool Demuxer::submitPacket(PESPacket& packet)
705 TELEM(2, packet.getPacketType());
706 TELEM(3, packet.getPTS());
709 u1 packet_type = packet.getPacketType();
710 const u1* packetdata = packet.getData();
711 if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX)
713 if (video_current == -1) video_current = packet_type;
714 if (video_current == packet_type && !vid_seeking)
716 sent = videostream.put(&packetdata[0], packet.getSize(), h264?MPTYPE_VIDEO_H264:MPTYPE_VIDEO_MPEG2,packetnum);
717 if (sent) packetnum++;
720 sent = packet.getSize();
722 else if (packet_type >= PESTYPE_AUD0 && packet_type <= PESTYPE_AUDMAX)
725 if (audio_current == -1) audio_current = packet_type;
726 avail_mpaudchan[packet_type - PESTYPE_AUD0] = true;
727 if (audio_current == packet_type && !aud_seeking)
729 u1 type=MPTYPE_MPEG_AUDIO;
734 type=MPTYPE_MPEG_AUDIO; break;
736 type=MPTYPE_AAC_LATM; break;
738 sent = audiostream.put(&packetdata[0], packet.getSize(), type,packetnum);
739 if (sent) packetnum++;
742 sent = packet.getSize();
744 else if (packet_type == PESTYPE_PRIVATE_1 &&
745 packet.getSubstream() >= PESTYPE_SUBSTREAM_AC30 &&
746 packet.getSubstream() <= PESTYPE_SUBSTREAM_AC3MAX)
748 avail_ac3audchan[packet.getSubstream() - PESTYPE_SUBSTREAM_AC30] = true;
749 if (packet.getSubstream() == audio_current)
751 sent = audiostream.put(&packetdata[0], packet.getSize(), (ispre_1_3_19 || livetv)? MPTYPE_AC3_PRE13 : MPTYPE_AC3,packetnum);
752 if (sent) packetnum++;
756 sent = packet.getSize();
759 else if (packet_type == PESTYPE_PRIVATE_1 &&
760 packet.getSubstream() >= PESTYPE_SUBSTREAM_DVBSUBTITLE0 &&
761 packet.getSubstream() <= PESTYPE_SUBSTREAM_DVBSUBTITLEMAX)
763 avail_dvbsubtitlechan[packet.getSubstream()-PESTYPE_SUBSTREAM_DVBSUBTITLE0]=true;
764 if (subtitle_current == -1) subtitle_current = packet.getSubstream();
765 if (subtitles && packet.getSubstream()==subtitle_current)
767 subtitles->put(packet);
769 sent = packet.getSize();
771 else if (isteletextdecoded && packet_type == PESTYPE_PRIVATE_1 &&
772 packet.getSubstream() >= PESTYPE_SUBSTREAM_TELETEXT0 &&
773 packet.getSubstream() <= PESTYPE_SUBSTREAM_TELETEXTMAX)
776 if (teletext_current == -1) teletext_current = packet.getSubstream();
777 if (teletext_current == packet.getSubstream())
779 sent = teletextstream.put(&packetdata[0], packet.getSize(), MPTYPE_TELETEXT,packetnum);
783 sent = packet.getSize();
788 sent = packet.getSize();
791 if (sent < packet.getSize()) // Stream is full.
797 void Demuxer::parsePacketDetails(PESPacket& packet)
799 if (packet.getPacketType() >= PESTYPE_AUD0 &&
800 packet.getPacketType() <= PESTYPE_AUDMAX)
802 // Extract audio PTS if it exists
805 audio_pts = packet.getPTS();
806 // We continue to seek on the audio if the video PTS that we
807 // are trying to match is ahead of the audio PTS by at most
808 // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
809 if (aud_seeking && !vid_seeking &&
810 !( (video_pts_seek > audio_pts &&
811 video_pts_seek - audio_pts < SEEK_THRESHOLD)
813 (video_pts_seek < audio_pts &&
814 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
817 LogNT::getInstance()->debug(TAG, "Leaving audio sync: Audio PTS = {}", audio_pts);
821 else if (packet.getPacketType() == PESTYPE_PRIVATE_1) // Private stream
824 //Inspired by vdr's device.c
825 int payload_begin = packet[8]+9;
826 unsigned char substream_id = packet[payload_begin];
827 unsigned char substream_type = substream_id & 0xF0;
828 unsigned char substream_index = substream_id & 0x1F;
829 pre_1_3_19_Recording: //This is for old recordings stuff and live TV
832 int old_substream=packet.getSubstream();
833 if (old_substream){ //someone else already set it, this is live tv
834 substream_id = old_substream;
835 substream_type = substream_id & 0xF0;
836 substream_index = substream_id & 0x1F;
838 substream_id = PESTYPE_PRIVATE_1;
839 substream_type = 0x80;
844 switch (substream_type)
848 packet.setSubstream(substream_id);
850 case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there?
852 case 0x80: //ac3, currently only one ac3 track per recording supported
853 packet.setSubstream(substream_type+substream_index);
855 // Extract audio PTS if it exists
858 audio_pts = packet.getPTS();
859 // We continue to seek on the audio if the video PTS that we
860 // are trying to match is ahead of the audio PTS by at most
861 // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
862 if (aud_seeking && !vid_seeking &&
863 !( (video_pts_seek > audio_pts &&
864 video_pts_seek - audio_pts < SEEK_THRESHOLD)
866 (video_pts_seek < audio_pts &&
867 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
870 LogNT::getInstance()->debug(TAG, "Leaving audio sync: Audio PTS = {}", audio_pts);
874 case 0x10: //Teletext Is this correct?
875 packet.setSubstream(substream_id);
876 // Extract teletxt PTS if it exists
879 teletext_pts = packet.getPTS();
885 ispre_1_3_19=true; //switching to compat mode and live tv mode
886 goto pre_1_3_19_Recording;
890 packet.setSubstream(0);
896 else if (packet.getPacketType() >= PESTYPE_VID0 &&
897 packet.getPacketType() <= PESTYPE_VIDMAX)
899 // Extract video PTS if it exists
900 if (packet.hasPTS()) video_pts = packet.getPTS();
902 // If there is a sequence header, extract information
903 u4 pos = packet.findSeqHeader(h264);
908 if (pos+6 >= packet.getSize()) return;
909 horizontal_size = ((int)packet[pos] << 4) | ((int)packet[pos+1] >> 4);
911 vertical_size = (((int)packet[pos+1] & 0xf) << 8) | (int)packet[pos+2];
913 enum AspectRatio aspect=(enum AspectRatio)(packet[pos+3] >> 4);
916 const int aspectDAR[]={0,1,1,1,4,3,16,9,221,100};
917 int aspectDARx=aspectDAR[aspect*2];
918 int aspectDARy=aspectDAR[aspect*2+1];
920 aspectx=aspectDARx*vertical_size;
921 aspecty=aspectDARy*horizontal_size;
925 // LogNT::getInstance()->debug(TAG, "PAR test1 {} {} {} {}", aspectx, aspecty, commona, commonb);
931 commonb=commona%commonb;
934 aspectx=aspectx/commona;
935 aspecty=aspecty/commona;
936 //LogNT::getInstance()->debug(TAG, "PAR test2 {} {} {} {} {} {} {}", aspectx,aspecty,aspectDARx,aspectDARy,horizontal_size,vertical_size,commona);
938 setAspectRatio(aspect,aspectx,aspecty);
939 frame_rate = packet[pos+3] & 0x0f;
940 if (frame_rate >= 1 && frame_rate <= 8)
941 frame_rate = FrameRates[frame_rate];
944 bit_rate = ((int)packet[pos+4] << 10) |
945 ((int)packet[pos+5] << 2) |
946 ((int)packet[pos+6] >> 6);
950 /* Chris and Mark I know this is ugly, should we move this to a method of PESPacket or to NALUUnit what would be better?
951 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*/
952 NALUUnit nalu(packet.getData()+pos,packet.getSize()-pos);
953 profile=nalu.getBits(8);
954 nalu.getBits(8); //constraints
955 nalu.getBits(8); //level_idc
956 nalu.getUe(); //seq_parameter_set_id
958 if (profile==100 || profile==110 || profile==122 || profile==144)
965 nalu.getUe(); //bit depth lume
966 nalu.getUe(); //bit depth chrome
970 for (int i=0;i<8;i++){
977 for (int j=0;j<16;j++) {
979 u4 delta=nalu.getSe();
980 nextscale=(lastscale+delta+256)%256;
982 lastscale=(nextscale==0)?lastscale:nextscale;
989 for (int j=0;j<64;j++) {
991 u4 delta=nalu.getSe();
992 nextscale=(lastscale+delta+256)%256;
994 lastscale=(nextscale==0)?lastscale:nextscale;
1005 chromunitx=chromunity=1; break;
1007 chromunitx=chromunity=2; break;
1009 chromunitx=2;chromunity=1; break;
1011 chromunitx=chromunity=1; break;
1014 nalu.getUe(); //log2framenum
1015 u4 temp=nalu.getUe();
1016 if (temp==0) //pict order
1022 u4 temp2=nalu.getUe();
1023 for (u4 i=0;i<temp2;i++)
1026 nalu.getUe(); //Num refframes
1028 horizontal_size=(nalu.getUe()+1)*16;
1030 vertical_size=(nalu.getUe()+1)*16;
1031 int tinterlaced=nalu.getBits(1);
1032 vertical_size*=(2-tinterlaced);
1033 interlaced=!tinterlaced;
1035 if (!tinterlaced) nalu.getBits(1);
1037 if (nalu.getBits(1))
1039 horizontal_size-=nalu.getUe()*chromunitx;
1040 horizontal_size-=nalu.getUe()*chromunitx;
1041 vertical_size-=nalu.getUe()*(2-tinterlaced)*chromunity;
1042 vertical_size-=nalu.getUe()*(2-tinterlaced)*chromunity;
1044 if (nalu.getBits(1))
1046 if (nalu.getBits(1))
1048 u4 aspectratioidc=nalu.getBits(8);
1049 bool hasaspect=false;
1050 int aspectx,aspecty;
1051 const float aspects[]={1., 1./1.,12./11.,10./11.,16./11.,40./33.,
1052 24./11.,20./11.,32./11.,80./33.,18./11.,15./11.,64./33.,160./99.,4./3.,3./2.,2./1.};
1053 const int aspectsx[]={1, 1,12,10,16,40,
1054 24,20,32,80,18,15,64,160,4,3,2};
1055 const int aspectsy[]={1, 1,11,11,11,33,11,11,11,33,11,11,33,99,3,2,1};
1057 float aspectratio=((float) horizontal_size)/((float) vertical_size);
1058 if (aspectratioidc<=16)
1061 aspectratio*=aspects[aspectratioidc];
1062 aspectx=aspectsx[aspectratioidc];
1063 aspecty=aspectsy[aspectratioidc];
1066 else if (aspectratioidc==255)
1068 int t_sar_width=nalu.getBits(16);
1069 int t_sar_height=nalu.getBits(16);
1070 if (t_sar_width!=0 && t_sar_height!=0)
1073 aspectratio*=((float)t_sar_width)/((float)t_sar_height);
1074 aspectx=t_sar_width;
1075 aspecty=t_sar_height;
1080 if (fabs(aspectratio-16./9.)<0.1) setAspectRatio(ASPECT_16_9,aspectx,aspecty);
1081 else if (fabs(aspectratio-4./3.)<0.1) setAspectRatio(ASPECT_4_3,aspectx,aspecty);
1082 else setAspectRatio(ASPECT_1_1,aspectx,aspecty);
1089 u4 posext = packet.findSeqExtHeader(h264);
1092 interlaced=!(packet[pos+1] & 0x08); //really simple
1093 // if more than full hd is coming we need to add additional parsers here
1095 /* NALUUnit nalu(packet.getData()+posext,packet.getSize()-posext);
1096 while (!nalu.isEonalu()) {
1097 unsigned int payloadtype=0;
1098 unsigned int payloadadd=0xFF;
1099 while (payloadadd==0xFF && !nalu.isEonalu()) {
1100 payloadadd=nalu.getBits(8);
1101 payloadtype+=payloadadd;
1103 unsigned int payloadsize=0;
1105 while (payloadadd==0xFF && !nalu.isEonalu()) {
1106 payloadadd=nalu.getBits(8);
1107 payloadsize+=payloadadd;
1109 switch (payloadtype) {
1110 case 1: { // picture timing SEI
1114 while (payloadsize) { // not handled skip
1132 video_pts_seek = video_pts;
1133 LogNT::getInstance()->debug(TAG, "Entering audio sync: Video PTS = {}", video_pts);
1134 LogNT::getInstance()->debug(TAG, "Entering audio sync: Audio PTS = {}", audio_pts);
1141 u4 Demuxer::stripAudio(u1* buf, u4 len)
1143 u4 read_pos = 0, write_pos = 0;
1144 u4 pattern, packet_length;
1145 if (len < 4) return 0;
1146 pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
1147 while (read_pos + 7 <= len)
1149 pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
1150 if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
1154 packet_length = ((buf[read_pos+4] << 8) | (buf[read_pos+5])) + 6;
1155 if (read_pos + packet_length > len)
1159 if (read_pos != write_pos)
1160 memmove(buf+write_pos, buf+read_pos, packet_length);
1161 read_pos += packet_length;
1162 write_pos += packet_length;
1163 pattern = (buf[read_pos] << 16) | (buf[read_pos+1] << 8)
1164 | (buf[read_pos+2]);
1171 void Demuxer::changeTimes(u1* buf, u4 len,u4 playtime)
1173 u4 pattern, packet_length;
1175 if (len < 4) return;
1176 pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
1177 while (read_pos + 7 <= len)
1179 pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
1180 if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
1184 packet_length = ((buf[read_pos+4] << 8) | (buf[read_pos+5])) + 6;
1185 // ok we have a packet figure out if pts and dts are present and replace them
1186 if (read_pos + 19 > len) return;
1187 u8 new_ts=playtime*90; //play time is on ms so multiply it by 90
1188 if (buf[read_pos+7] & 0x80) { // pts is here, replace it
1189 buf[read_pos+9]=0x21 | (( new_ts>>29)& 0xde );
1190 buf[read_pos+10]=0x00 |(( new_ts>>22)& 0xff );
1191 buf[read_pos+11]=0x01 | (( new_ts>>14)& 0xfe );
1192 buf[read_pos+12]=0x00 | (( new_ts>>7)& 0xff );
1193 buf[read_pos+13]=0x01 | (( new_ts<<1)& 0xfe );
1196 if (buf[read_pos+7] & 0x40) { // pts is here, replace it
1197 buf[read_pos+14]=0x21 | (( new_ts>>29)& 0xde );
1198 buf[read_pos+15]=0x00 | (( new_ts>>22)& 0xff );
1199 buf[read_pos+16]=0x01 | (( new_ts>>14)& 0xfe );
1200 buf[read_pos+17]=0x00 | (( new_ts>>7)& 0xff );
1201 buf[read_pos+18]=0x01 | (( new_ts<<1)& 0xfe );
1203 read_pos += packet_length;
1204 pattern = (buf[read_pos] << 16) | (buf[read_pos+1] << 8)
1205 | (buf[read_pos+2]);
1211 bool Demuxer::scanForVideo(u1* buf, u4 len, bool &ish264)
1216 if (len < 4) return false;
1217 pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
1220 pattern = ((pattern & 0xFFFFFF) << 8) | buf[pos++];
1221 if (pattern >= (0x100|PESTYPE_VID0) && pattern <= (0x100|PESTYPE_VIDMAX))
1227 bool* Demuxer::getmpAudioChannels()
1229 return avail_mpaudchan;
1232 bool* Demuxer::getac3AudioChannels()
1234 return avail_ac3audchan;
1237 bool* Demuxer::getSubtitleChannels()
1239 return avail_dvbsubtitlechan;
1242 int Demuxer::getselSubtitleChannel()
1244 return subtitle_current;
1247 int Demuxer::getselAudioChannel()
1249 return audio_current;