Projects
Multimedia
bento4
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 14
View file
bento4.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Tue Nov 12 12:10:33 UTC 2019 - Luigi Baldoni <aloisio@gmx.com> + +- Update to version 1.5.1-629 + +------------------------------------------------------------------- Sun Jan 13 09:15:40 UTC 2019 - aloisio@gmx.com - Update to version 1.5.1-628
View file
bento4.spec
Changed
@@ -16,10 +16,10 @@ # -%define _over 1.5.1-628 -%define _libver 1_5_1r628 +%define _over 1.5.1-629 +%define _libver 1_5_1r629 Name: bento4 -Version: 1.5.1r628 +Version: 1.5.1r629 Release: 0 Summary: C++ toolkit for all your MP4 and MPEG DASH media format needs License: GPL-2.0-or-later
View file
bento4-1.5.1r628.tar.gz/Build/Makefiles/TopLevel.mak -> bento4-1.5.1r629.tar.gz/Build/Makefiles/TopLevel.mak
Changed
@@ -47,9 +47,9 @@ .PHONY: Setup Setup: mkdir $(OUTPUT_DIR) - + # ------- Apps ----------- -ALL_APPS = mp4dump mp4info mp42aac mp42ts aac2mp4 mp4decrypt mp4encrypt mp4edit mp4extract mp4rtphintinfo mp4tag mp4dcfpackager mp4fragment mp4compact mp4split mp4mux avcinfo hevcinfo mp42hevc mp42hls +ALL_APPS = mp4dump mp4info mp42aac mp42ts aac2mp4 mp4decrypt mp4encrypt mp4edit mp4extract mp4rtphintinfo mp4tag mp4dcfpackager mp4fragment mp4compact mp4split mp4mux avcinfo hevcinfo mp42hevc mp42hls mp4iframeindex export ALL_APPS ################################################################## @@ -72,7 +72,7 @@ sdk: lib apps $(TITLE) @$(INVOKE_SUBMAKE) -f $(BUILD_ROOT)/Makefiles/SDK.mak - + mp4dump: lib $(TITLE) @$(INVOKE_SUBMAKE) -f $(BUILD_ROOT)/Makefiles/Mp4Dump.mak @@ -132,7 +132,7 @@ mp4compact: lib $(TITLE) @$(INVOKE_SUBMAKE) -f $(BUILD_ROOT)/Makefiles/Mp4Compact.mak - + mp4mux: lib $(TITLE) @$(INVOKE_SUBMAKE) -f $(BUILD_ROOT)/Makefiles/Mp4Mux.mak
View file
bento4-1.5.1r628.tar.gz/Source/C++/Apps/Mp42Hls/Mp42Hls.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Apps/Mp42Hls/Mp42Hls.cpp
Changed
@@ -562,7 +562,7 @@ PreventStartCodeEmulation(nalu+nalu_length_size, nalu_length, escaped_nalu); // the size may have changed - // FIXME: this could overflow if nalu_length_size is too small + // TODO: this could overflow if nalu_length_size is too small switch (nalu_length_size) { case 1: nalu[0] = (AP4_UI08)(escaped_nalu.GetDataSize()&0xFF); @@ -2108,6 +2108,12 @@ if (Stats.segments_total_duration != 0.0) { average_iframe_bitrate = 8.0*(double)Stats.iframes_total_size/Stats.segments_total_duration; } + + double frame_rate = 0.0; + if (Stats.segments_total_duration != 0.0) { + frame_rate = (double)video_track->GetSampleCount()/((double)video_track->GetMediaDuration()/(double)video_track->GetMediaTimeScale()); + } + printf( "{\n" ); @@ -2117,13 +2123,15 @@ " \"avg_segment_bitrate\": %f,\n" " \"max_segment_bitrate\": %f,\n" " \"avg_iframe_bitrate\": %f,\n" - " \"max_iframe_bitrate\": %f\n" + " \"max_iframe_bitrate\": %f,\n" + " \"frame_rate\": %f\n" " }", (double)movie->GetDurationMs()/1000.0, average_segment_bitrate, Stats.max_segment_bitrate, average_iframe_bitrate, - Stats.max_iframe_bitrate + Stats.max_iframe_bitrate, + frame_rate ); if (audio_track) { AP4_String codec;
View file
bento4-1.5.1r628.tar.gz/Source/C++/Apps/Mp4Fragment/Mp4Fragment.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Apps/Mp4Fragment/Mp4Fragment.cpp
Changed
@@ -2,7 +2,7 @@ | | AP4 - MP4 Fragmenter | -| Copyright 2002-2015 Axiomatic Systems, LLC +| Copyright 2002-2019 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -37,9 +37,9 @@ /*---------------------------------------------------------------------- | constants +---------------------------------------------------------------------*/ -#define BANNER "MP4 Fragmenter - Version 1.6.0\n"\ +#define BANNER "MP4 Fragmenter - Version 1.6.1\n"\ "(Bento4 Version " AP4_VERSION_STRING ")\n"\ - "(c) 2002-2015 Axiomatic Systems, LLC" + "(c) 2002-2019 Axiomatic Systems, LLC" /*---------------------------------------------------------------------- | constants @@ -86,8 +86,8 @@ " --index (re)create the segment index\n" " --trim trim excess media in longer tracks\n" " --no-tfdt don't add 'tfdt' boxes in the fragments (may be needed for legacy Smooth Streaming clients)\n" - " --tfdt-start <start> Value of the first tfdt timestamp, expressed either as a floating point number in seconds)\n" - " --sequence-number-start <start> Value of the first segment sequence number (default: 1)\n" + " --tfdt-start <start> value of the first tfdt timestamp, expressed as a floating point number in seconds\n" + " --sequence-number-start <start> value of the first segment sequence number (default: 1)\n" " --force-i-frame-sync <auto|all> treat all I-frames as sync samples (for open-gop sequences)\n" " 'auto' only forces the flag if an open-gop source is detected, 'all' forces the flag in all cases\n" " --copy-udta copy the moov/udta atom from input to output\n" @@ -644,7 +644,7 @@ AP4_Array<AP4_TrunAtom::Entry> trun_entries; fragment->m_MdatSize = AP4_ATOM_HEADER_SIZE; AP4_UI32 constant_sample_duration = 0; - bool all_segment_durations_equal = true; + bool all_sample_durations_equal = true; for (;;) { // if we have one non-zero CTS delta, we'll need to express it if (cursor->m_Sample.GetCtsDelta()) { @@ -674,12 +674,12 @@ fragment->m_Duration += trun_entry.sample_duration; // check if the durations are all the same - if (all_segment_durations_equal) { + if (all_sample_durations_equal) { if (constant_sample_duration == 0) { constant_sample_duration = trun_entry.sample_duration; } else { if (constant_sample_duration != trun_entry.sample_duration) { - all_segment_durations_equal = false; + all_sample_durations_equal = false; } } } @@ -705,11 +705,11 @@ } if (Options.verbosity > 2) { printf(" %d samples\n", sample_count); - printf(" constant sample duration: %s\n", all_segment_durations_equal?"yes":"no"); + printf(" constant sample duration: %s\n", all_sample_durations_equal?"yes":"no"); } // update the 'trun' flags if needed - if (all_segment_durations_equal) { + if (all_sample_durations_equal) { tfhd->SetDefaultSampleDuration(constant_sample_duration); tfhd->UpdateFlags(tfhd->GetFlags() | AP4_TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT); } else { @@ -771,9 +771,11 @@ AP4_Position sidx_position = 0; output_stream.Tell(sidx_position); if (create_segment_index) { + AP4_UI32 sidx_timescale = timescale ? timescale : indexed_cursor->m_Track->GetMediaTimeScale(); + AP4_UI64 earliest_presentation_time = (AP4_UI64)(Options.tfdt_start * (double)sidx_timescale); sidx = new AP4_SidxAtom(indexed_cursor->m_Track->GetId(), - timescale ? timescale : indexed_cursor->m_Track->GetMediaTimeScale(), - 0, + sidx_timescale, + earliest_presentation_time, 0); // reserve space for the entries now, but they will be computed and updated later sidx->SetReferenceCount(indexed_segments.ItemCount());
View file
bento4-1.5.1r628.tar.gz/Source/C++/Apps/Mp4Mux/Mp4Mux.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Apps/Mp4Mux/Mp4Mux.cpp
Changed
@@ -2,7 +2,7 @@ | | AP4 - Elementary Stream Muliplexer | -| Copyright 2002-2016 Axiomatic Systems, LLC +| Copyright 2002-2019 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -39,11 +39,12 @@ /*---------------------------------------------------------------------- | constants +---------------------------------------------------------------------*/ -#define BANNER "MP4 Elementary Stream Multiplexer - Version 1.1\n"\ +#define BANNER "MP4 Elementary Stream Multiplexer - Version 2.0\n"\ "(Bento4 Version " AP4_VERSION_STRING ")\n"\ - "(c) 2002-20016 Axiomatic Systems, LLC" + "(c) 2002-20019 Axiomatic Systems, LLC" const unsigned int AP4_MUX_DEFAULT_VIDEO_FRAME_RATE = 24; +const unsigned int AP4_MUX_READ_BUFFER_SIZE = 65536; /*---------------------------------------------------------------------- | globals @@ -301,7 +302,7 @@ } // read some data and feed the parser - AP4_UI08 input_buffer[4096]; + AP4_UI08 input_buffer[AP4_MUX_READ_BUFFER_SIZE]; AP4_Size to_read = parser.GetBytesFree(); if (to_read) { AP4_Size bytes_read = 0; @@ -381,7 +382,7 @@ AP4_AvcFrameParser parser; for (;;) { bool eos; - unsigned char input_buffer[4096]; + unsigned char input_buffer[AP4_MUX_READ_BUFFER_SIZE]; AP4_Size bytes_in_buffer = 0; result = input->ReadPartial(input_buffer, sizeof(input_buffer), bytes_in_buffer); if (AP4_SUCCEEDED(result)) { @@ -602,7 +603,7 @@ AP4_HevcFrameParser parser; for (;;) { bool eos; - unsigned char input_buffer[4096]; + unsigned char input_buffer[AP4_MUX_READ_BUFFER_SIZE]; AP4_Size bytes_in_buffer = 0; result = input->ReadPartial(input_buffer, sizeof(input_buffer), bytes_in_buffer); if (AP4_SUCCEEDED(result)) { @@ -716,8 +717,8 @@ AP4_UI32 min_spatial_segmentation = 0; // TBD (should read from VUI if present) AP4_UI08 parallelism_type = 0; // unknown AP4_UI08 chroma_format = sps->chroma_format_idc; - AP4_UI08 luma_bit_depth = 8; // FIXME: hardcoded temporarily, should be read from the bitstream - AP4_UI08 chroma_bit_depth = 8; // FIXME: hardcoded temporarily, should be read from the bitstream + AP4_UI08 luma_bit_depth = 8; // hardcoded temporarily, should be read from the bitstream + AP4_UI08 chroma_bit_depth = 8; // hardcoded temporarily, should be read from the bitstream AP4_UI16 average_frame_rate = 0; // unknown AP4_UI08 constant_frame_rate = 0; // unknown AP4_UI08 num_temporal_layers = 0; // unknown
View file
bento4-1.5.1r628.tar.gz/Source/C++/Codecs/Ap4HevcParser.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Codecs/Ap4HevcParser.cpp
Changed
@@ -243,11 +243,15 @@ /* abs_delta_rps_minus1 = */ ReadGolomb(bits); if (delta_idx_minus1+1 > stRpsIdx) return AP4_ERROR_INVALID_FORMAT; // should not happen unsigned int RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1); - unsigned int NumDeltaPocs = sps->short_term_ref_pic_sets[RefRpsIdx].num_negative_pics + sps->short_term_ref_pic_sets[RefRpsIdx].num_positive_pics; + unsigned int NumDeltaPocs = sps->short_term_ref_pic_sets[RefRpsIdx].num_delta_pocs; for (unsigned j=0; j<=NumDeltaPocs; j++) { unsigned int used_by_curr_pic_flag /*[j]*/ = bits.ReadBit(); + unsigned int use_delta_flag /*[j]*/ = 1; if (!used_by_curr_pic_flag /*[j]*/) { - /* use_delta_flag[j] = */ bits.ReadBit(); + use_delta_flag /*[j]*/ = bits.ReadBit(); + } + if (used_by_curr_pic_flag /*[j]*/ || use_delta_flag /*[j]*/) { + rps->num_delta_pocs++; } } } else { @@ -256,6 +260,7 @@ if (rps->num_negative_pics > 16 || rps->num_positive_pics > 16) { return AP4_ERROR_INVALID_FORMAT; } + rps->num_delta_pocs = rps->num_negative_pics + rps->num_positive_pics; for (unsigned int i=0; i<rps->num_negative_pics; i++) { rps->delta_poc_s0_minus1[i] = ReadGolomb(bits); rps->used_by_curr_pic_s0_flag[i] = bits.ReadBit();
View file
bento4-1.5.1r628.tar.gz/Source/C++/Codecs/Ap4HevcParser.h -> bento4-1.5.1r629.tar.gz/Source/C++/Codecs/Ap4HevcParser.h
Changed
@@ -161,6 +161,7 @@ unsigned int used_by_curr_pic_s1_flag[16]; unsigned int num_negative_pics; unsigned int num_positive_pics; + unsigned int num_delta_pocs; } AP4_HevcShortTermRefPicSet; /*----------------------------------------------------------------------
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4Atom.h -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4Atom.h
Changed
@@ -495,6 +495,8 @@ const AP4_Atom::Type AP4_ATOM_TYPE_DTSH = AP4_ATOM_TYPE('d','t','s','h'); const AP4_Atom::Type AP4_ATOM_TYPE_DTSL = AP4_ATOM_TYPE('d','t','s','l'); const AP4_Atom::Type AP4_ATOM_TYPE_DTSE = AP4_ATOM_TYPE('d','t','s','e'); +const AP4_Atom::Type AP4_ATOM_TYPE_FLAC = AP4_ATOM_TYPE('f','L','a','C'); +const AP4_Atom::Type AP4_ATOM_TYPE_OPUS = AP4_ATOM_TYPE('O','p','u','s'); const AP4_Atom::Type AP4_ATOM_TYPE_MFRA = AP4_ATOM_TYPE('m','f','r','a'); const AP4_Atom::Type AP4_ATOM_TYPE_TFRA = AP4_ATOM_TYPE('t','f','r','a'); const AP4_Atom::Type AP4_ATOM_TYPE_MFRO = AP4_ATOM_TYPE('m','f','r','o');
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4AtomFactory.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4AtomFactory.cpp
Changed
@@ -197,6 +197,12 @@ stream.GetSize(stream_size); if (stream_size >= start) { size = stream_size - start; + + if (size <= 0xFFFFFFFF) { + size_32 = (AP4_UI32)size; + } else { + size_32 = 1; // signal a large atom + } } } else if (size == 1) { // 64-bit size @@ -206,6 +212,10 @@ return AP4_ERROR_INVALID_FORMAT; } stream.ReadUI64(size); + if (size < 16) { + stream.Seek(start); + return AP4_ERROR_INVALID_FORMAT; + } if (size <= 0xFFFFFFFF) { force_64 = true; } @@ -321,6 +331,8 @@ case AP4_ATOM_TYPE_DTSH: case AP4_ATOM_TYPE_DTSL: case AP4_ATOM_TYPE_DTSE: + case AP4_ATOM_TYPE_FLAC: + case AP4_ATOM_TYPE_OPUS: atom = new AP4_AudioSampleEntry(type, size_32, stream, *this); break;
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4AvccAtom.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4AvccAtom.cpp
Changed
@@ -85,8 +85,8 @@ cursor += 2+AP4_BytesToInt16BE(&payload[cursor]); if (cursor > payload_size) return NULL; } + if (cursor+1 > payload_size) return NULL; unsigned int num_pic_params = payload[cursor++]; - if (cursor > payload_size) return NULL; for (unsigned int i=0; i<num_pic_params; i++) { if (cursor+2 > payload_size) return NULL; cursor += 2+AP4_BytesToInt16BE(&payload[cursor]);
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4CommonEncryption.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4CommonEncryption.cpp
Changed
@@ -2327,6 +2327,36 @@ } /*---------------------------------------------------------------------- +| AP4_CencDecryptingProcessor:GetKeyForTrak ++---------------------------------------------------------------------*/ +const AP4_DataBuffer* +AP4_CencDecryptingProcessor::GetKeyForTrak(AP4_UI32 track_id, AP4_ProtectedSampleDescription* sample_description) +{ + // look for the key by track ID + const AP4_DataBuffer* key = m_KeyMap->GetKey(track_id); + if (!key) { + // no key found by track ID, look for a key by KID + if (sample_description) { + AP4_ProtectionSchemeInfo* scheme_info = sample_description->GetSchemeInfo(); + if (scheme_info) { + AP4_ContainerAtom* schi = scheme_info->GetSchiAtom(); + if (schi) { + AP4_TencAtom* tenc = AP4_DYNAMIC_CAST(AP4_TencAtom, schi->FindChild("tenc")); + if (tenc) { + const AP4_UI08* kid = tenc->GetDefaultKid(); + if (kid) { + key = m_KeyMap->GetKeyByKid(kid); + } + } + } + } + } + } + + return key; +} + +/*---------------------------------------------------------------------- | AP4_CencDecryptingProcessor:CreateTrackHandler +---------------------------------------------------------------------*/ AP4_Processor::TrackHandler* @@ -2363,8 +2393,8 @@ } if (sample_entries.ItemCount() == 0) return NULL; - // look for the key by track ID - const AP4_DataBuffer* key = m_KeyMap->GetKey(trak->GetId()); + // get the key for this track + const AP4_DataBuffer* key = GetKeyForTrak(trak->GetId(), sample_descs.ItemCount() ? sample_descs[0] : NULL); // create a decrypter with this key if (key) { @@ -2385,7 +2415,7 @@ | AP4_CencDecryptingProcessor::CreateFragmentHandler +---------------------------------------------------------------------*/ AP4_Processor::FragmentHandler* -AP4_CencDecryptingProcessor::CreateFragmentHandler(AP4_TrakAtom* /*trak*/, +AP4_CencDecryptingProcessor::CreateFragmentHandler(AP4_TrakAtom* trak, AP4_TrexAtom* trex, AP4_ContainerAtom* traf, AP4_ByteStream& moof_data, @@ -2410,11 +2440,11 @@ sample_description = track_decrypter->GetSampleDescription(index-1); } if (sample_description == NULL) return NULL; + + // get the key for this track + key = GetKeyForTrak(tfhd->GetTrackId(), sample_description); } - // get the matching key by track ID - key = m_KeyMap->GetKey(tfhd->GetTrackId()); - break; } }
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4CommonEncryption.h -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4CommonEncryption.h
Changed
@@ -664,7 +664,10 @@ AP4_ByteStream& moof_data, AP4_Position moof_offset); -protected: +protected: + // methods + const AP4_DataBuffer* GetKeyForTrak(AP4_UI32 track_id, AP4_ProtectedSampleDescription* sample_description); + // members AP4_BlockCipherFactory* m_BlockCipherFactory; const AP4_ProtectionKeyMap* m_KeyMap;
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4DecoderConfigDescriptor.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4DecoderConfigDescriptor.cpp
Changed
@@ -74,11 +74,8 @@ header_size, payload_size) { - // record the start position - AP4_Position start; - stream.Tell(start); - // read descriptor fields + if (payload_size < 13) return; stream.ReadUI08(m_ObjectTypeIndication); unsigned char bits; stream.ReadUI08(bits); @@ -87,9 +84,12 @@ stream.ReadUI24(m_BufferSize); stream.ReadUI32(m_MaxBitrate); stream.ReadUI32(m_AverageBitrate); - + payload_size -= 13; + // read other descriptors - AP4_SubStream* substream = new AP4_SubStream(stream, start+13, payload_size-13); + AP4_Position offset; + stream.Tell(offset); + AP4_SubStream* substream = new AP4_SubStream(stream, offset, payload_size); AP4_Descriptor* descriptor = NULL; while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, descriptor)
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4DescriptorFactory.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4DescriptorFactory.cpp
Changed
@@ -78,55 +78,57 @@ } while (--max && (ext&0x80)); // create the descriptor - switch (tag) { - case AP4_DESCRIPTOR_TAG_OD: - case AP4_DESCRIPTOR_TAG_MP4_OD: - descriptor = new AP4_ObjectDescriptor(stream, tag, header_size, payload_size); - break; - - case AP4_DESCRIPTOR_TAG_IOD: - case AP4_DESCRIPTOR_TAG_MP4_IOD: - descriptor = new AP4_InitialObjectDescriptor(stream, tag, header_size, payload_size); - break; - - case AP4_DESCRIPTOR_TAG_ES_ID_INC: - descriptor = new AP4_EsIdIncDescriptor(stream, header_size, payload_size); - break; - - case AP4_DESCRIPTOR_TAG_ES_ID_REF: - descriptor = new AP4_EsIdRefDescriptor(stream, header_size, payload_size); - break; - - case AP4_DESCRIPTOR_TAG_ES: - descriptor = new AP4_EsDescriptor(stream, header_size, payload_size); - break; - - case AP4_DESCRIPTOR_TAG_DECODER_CONFIG: - descriptor = new AP4_DecoderConfigDescriptor(stream, header_size, payload_size); - break; - - case AP4_DESCRIPTOR_TAG_DECODER_SPECIFIC_INFO: - descriptor = new AP4_DecoderSpecificInfoDescriptor(stream, header_size, payload_size); - break; - - case AP4_DESCRIPTOR_TAG_SL_CONFIG: - if (payload_size != 1) return AP4_ERROR_INVALID_FORMAT; - descriptor = new AP4_SLConfigDescriptor(header_size); - break; - - case AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR_POINTER: - descriptor = new AP4_IpmpDescriptorPointer(stream, header_size, payload_size); - break; - - case AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR: - descriptor = new AP4_IpmpDescriptor(stream, header_size, payload_size); - break; - - default: - descriptor = new AP4_UnknownDescriptor(stream, tag, header_size, payload_size); - break; + if (payload_size) { + switch (tag) { + case AP4_DESCRIPTOR_TAG_OD: + case AP4_DESCRIPTOR_TAG_MP4_OD: + descriptor = new AP4_ObjectDescriptor(stream, tag, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_IOD: + case AP4_DESCRIPTOR_TAG_MP4_IOD: + descriptor = new AP4_InitialObjectDescriptor(stream, tag, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_ES_ID_INC: + descriptor = new AP4_EsIdIncDescriptor(stream, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_ES_ID_REF: + descriptor = new AP4_EsIdRefDescriptor(stream, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_ES: + descriptor = new AP4_EsDescriptor(stream, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_DECODER_CONFIG: + descriptor = new AP4_DecoderConfigDescriptor(stream, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_DECODER_SPECIFIC_INFO: + descriptor = new AP4_DecoderSpecificInfoDescriptor(stream, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_SL_CONFIG: + if (payload_size != 1) return AP4_ERROR_INVALID_FORMAT; + descriptor = new AP4_SLConfigDescriptor(header_size); + break; + + case AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR_POINTER: + descriptor = new AP4_IpmpDescriptorPointer(stream, header_size, payload_size); + break; + + case AP4_DESCRIPTOR_TAG_IPMP_DESCRIPTOR: + descriptor = new AP4_IpmpDescriptor(stream, header_size, payload_size); + break; + + default: + descriptor = new AP4_UnknownDescriptor(stream, tag, header_size, payload_size); + break; + } } - + // skip to the end of the descriptor stream.Seek(offset+header_size+payload_size);
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4ElstAtom.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4ElstAtom.cpp
Changed
@@ -68,10 +68,24 @@ AP4_ByteStream& stream) : AP4_Atom(AP4_ATOM_TYPE_ELST, size, version, flags) { + // read the number of entries AP4_UI32 entry_count; stream.ReadUI32(entry_count); + + // compute bounds + AP4_UI32 max_entries; + if (version == 0) { + max_entries = (size - (AP4_FULL_ATOM_HEADER_SIZE + 4)) / 12; + } else { + max_entries = (size - (AP4_FULL_ATOM_HEADER_SIZE + 4)) / 20; + } + if (entry_count > max_entries) { + entry_count = max_entries; + } + + // read the entries m_Entries.EnsureCapacity(entry_count); - for (AP4_UI32 i=0; i<entry_count; i++) { + for (AP4_UI32 i=0; i < entry_count; i++) { AP4_UI16 media_rate; AP4_UI16 zero; if (version == 0) {
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4EsDescriptor.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4EsDescriptor.cpp
Changed
@@ -63,24 +63,28 @@ AP4_Size payload_size) : AP4_Descriptor(AP4_DESCRIPTOR_TAG_ES, header_size, payload_size) { - AP4_Position start; - stream.Tell(start); - // read descriptor fields + if (payload_size < 3) return; stream.ReadUI16(m_EsId); unsigned char bits; stream.ReadUI08(bits); + payload_size -= 3; m_Flags = (bits>>5)&7; m_StreamPriority = bits&0x1F; if (m_Flags & AP4_ES_DESCRIPTOR_FLAG_STREAM_DEPENDENCY) { + if (payload_size < 2) return; stream.ReadUI16(m_DependsOn); + payload_size -= 2; } else { m_DependsOn = 0; } if (m_Flags & AP4_ES_DESCRIPTOR_FLAG_URL) { unsigned char url_length; + if (payload_size < 1) return; stream.ReadUI08(url_length); + --payload_size; if (url_length) { + if (payload_size < url_length) return; char* url = new char[url_length+1]; if (url) { stream.Read(url, url_length); @@ -88,10 +92,13 @@ m_Url = url; delete[] url; } + payload_size -= url_length; } } if (m_Flags & AP4_ES_DESCRIPTOR_FLAG_URL) { + if (payload_size < 2) return; stream.ReadUI16(m_OcrEsId); + payload_size -= 2; } else { m_OcrEsId = 0; } @@ -99,8 +106,7 @@ // read other descriptors AP4_Position offset; stream.Tell(offset); - AP4_SubStream* substream = new AP4_SubStream(stream, offset, - payload_size-AP4_Size(offset-start)); + AP4_SubStream* substream = new AP4_SubStream(stream, offset, payload_size); AP4_Descriptor* descriptor = NULL; while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, descriptor)
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4FileWriter.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4FileWriter.cpp
Changed
@@ -117,7 +117,7 @@ movie->GetMoovAtom()->Write(stream); // create and write the media data (mdat) - // FIXME: this only supports 32-bit mdat size + // TODO: this only supports 32-bit mdat size stream.WriteUI32((AP4_UI32)mdat_size); stream.WriteUI32(AP4_ATOM_TYPE_MDAT);
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4LinearReader.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4LinearReader.cpp
Changed
@@ -41,8 +41,7 @@ | AP4_LinearReader::AP4_LinearReader +---------------------------------------------------------------------*/ AP4_LinearReader::AP4_LinearReader(AP4_Movie& movie, - AP4_ByteStream* fragment_stream, - AP4_Size max_buffer) : + AP4_ByteStream* fragment_stream) : m_Movie(movie), m_Fragment(NULL), m_FragmentStream(fragment_stream), @@ -50,7 +49,6 @@ m_NextFragmentPosition(0), m_BufferFullness(0), m_BufferFullnessPeak(0), - m_MaxBufferFullness(max_buffer), m_Mfra(NULL) { m_HasFragments = movie.HasFragments(); @@ -404,11 +402,7 @@ AP4_Result AP4_LinearReader::Advance(bool read_data) { - // first, check if we have space to advance - if (m_BufferFullness >= m_MaxBufferFullness) { - return AP4_ERROR_NOT_ENOUGH_SPACE; - } - + AP4_UI64 min_offset = (AP4_UI64)(-1); Tracker* next_tracker = NULL; for (;;) {
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4LinearReader.h -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4LinearReader.h
Changed
@@ -50,14 +50,12 @@ const unsigned int AP4_LINEAR_READER_INITIALIZED = 1; const unsigned int AP4_LINEAR_READER_FLAG_EOS = 2; -const unsigned int AP4_LINEAR_READER_DEFAULT_BUFFER_SIZE = 16*1024*1024; - /*---------------------------------------------------------------------- | AP4_LinearReader +---------------------------------------------------------------------*/ class AP4_LinearReader { public: - AP4_LinearReader(AP4_Movie& movie, AP4_ByteStream* fragment_stream = NULL, AP4_Size max_buffer=AP4_LINEAR_READER_DEFAULT_BUFFER_SIZE); + AP4_LinearReader(AP4_Movie& movie, AP4_ByteStream* fragment_stream = NULL); virtual ~AP4_LinearReader(); AP4_Result EnableTrack(AP4_UI32 track_id); @@ -184,7 +182,6 @@ AP4_Array<Tracker*> m_Trackers; AP4_Size m_BufferFullness; AP4_Size m_BufferFullnessPeak; - AP4_Size m_MaxBufferFullness; AP4_ContainerAtom* m_Mfra; };
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4Mpeg2Ts.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4Mpeg2Ts.cpp
Changed
@@ -282,6 +282,12 @@ bool with_pcr, AP4_ByteStream& output) { + // ISO/IEC 13818-1 section 2.7.5 says a DTS shall appear only if the + // decoding time differs from the presentation time. + if (with_dts && (dts == pts)) { + with_dts = false; + } + unsigned int pes_header_size = 14+(with_dts?5:0); AP4_BitWriter pes_header(pes_header_size);
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4ObjectDescriptor.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4ObjectDescriptor.cpp
Changed
@@ -71,20 +71,23 @@ AP4_Size payload_size) : AP4_Descriptor(tag, header_size, payload_size) { - AP4_Position start; - stream.Tell(start); - // read descriptor fields unsigned short bits; + if (payload_size < 2) return; stream.ReadUI16(bits); + payload_size -= 2; m_ObjectDescriptorId = (bits>>6); m_UrlFlag = ((bits&(1<<5))!=0); if (m_UrlFlag) { unsigned char url_length; + if (payload_size < 1) return; stream.ReadUI08(url_length); + --payload_size; char url[256]; + if (payload_size < url_length) return; stream.Read(url, url_length); + payload_size -= url_length; url[url_length] = '\0'; m_Url = url; } @@ -92,8 +95,7 @@ // read other descriptors AP4_Position offset; stream.Tell(offset); - AP4_SubStream* substream = new AP4_SubStream(stream, offset, - payload_size-AP4_Size(offset-start)); + AP4_SubStream* substream = new AP4_SubStream(stream, offset, payload_size); AP4_Descriptor* descriptor = NULL; while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, descriptor) @@ -223,36 +225,40 @@ m_VisualProfileLevelIndication(0), m_GraphicsProfileLevelIndication(0) { - AP4_Position start; - stream.Tell(start); - // read descriptor fields unsigned short bits; + if (payload_size < 2) return; stream.ReadUI16(bits); + payload_size -= 2; m_ObjectDescriptorId = (bits>>6); m_UrlFlag = ((bits&(1<<5))!=0); m_IncludeInlineProfileLevelFlag = ((bits&(1<<4))!=0); - + if (m_UrlFlag) { unsigned char url_length; + if (payload_size < 1) return; stream.ReadUI08(url_length); + --payload_size; char url[256]; + if (payload_size < url_length) return; stream.Read(url, url_length); + payload_size -= url_length; url[url_length] = '\0'; m_Url = url; } else { + if (payload_size < 5) return; stream.ReadUI08(m_OdProfileLevelIndication); stream.ReadUI08(m_SceneProfileLevelIndication); stream.ReadUI08(m_AudioProfileLevelIndication); stream.ReadUI08(m_VisualProfileLevelIndication); - stream.ReadUI08(m_GraphicsProfileLevelIndication); + stream.ReadUI08(m_GraphicsProfileLevelIndication); + payload_size -= 5; } // read other descriptors AP4_Position offset; stream.Tell(offset); - AP4_SubStream* substream = new AP4_SubStream(stream, offset, - payload_size-AP4_Size(offset-start)); + AP4_SubStream* substream = new AP4_SubStream(stream, offset, payload_size); AP4_Descriptor* descriptor = NULL; while (AP4_DescriptorFactory::CreateDescriptorFromStream(*substream, descriptor)
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4Results.h -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4Results.h
Changed
@@ -55,7 +55,6 @@ const int AP4_ERROR_INVALID_RTP_PACKET_EXTRA_DATA = -20; const int AP4_ERROR_BUFFER_TOO_SMALL = -21; const int AP4_ERROR_NOT_ENOUGH_DATA = -22; -const int AP4_ERROR_NOT_ENOUGH_SPACE = -23; /*---------------------------------------------------------------------- | utility functions
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4Sample.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4Sample.cpp
Changed
@@ -143,8 +143,17 @@ // check the size if (m_Size < size+offset) return AP4_FAILURE; + // check if there's enough data in the stream + AP4_LargeSize stream_size = 0; + AP4_Result result = m_DataStream->GetSize(stream_size); + if (AP4_SUCCEEDED(result)) { + if (size + offset > stream_size) { + return AP4_ERROR_OUT_OF_RANGE; + } + } + // set the buffer size - AP4_Result result = data.SetDataSize(size); + result = data.SetDataSize(size); if (AP4_FAILED(result)) return result; // get the data from the stream
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4SampleDescription.h -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4SampleDescription.h
Changed
@@ -95,6 +95,8 @@ const AP4_UI32 AP4_SAMPLE_FORMAT_VC_1 = AP4_ATOM_TYPE('v','c','-','1'); const AP4_UI32 AP4_SAMPLE_FORMAT_XML_ = AP4_ATOM_TYPE('x','m','l',' '); const AP4_UI32 AP4_SAMPLE_FORMAT_STPP = AP4_ATOM_TYPE('s','t','p','p'); +const AP4_UI32 AP4_SAMPLE_FORMAT_FLAC = AP4_ATOM_TYPE('f','L','a','C'); +const AP4_UI32 AP4_SAMPLE_FORMAT_OPUS = AP4_ATOM_TYPE('O','p','u','s'); const char* AP4_GetFormatName(AP4_UI32 format);
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4SegmentBuilder.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4SegmentBuilder.cpp
Changed
@@ -2,7 +2,7 @@ | | AP4 - Segment Builder | -| Copyright 2002-2014 Axiomatic Systems, LLC +| Copyright 2002-2019 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -46,7 +46,8 @@ /*---------------------------------------------------------------------- | constants +---------------------------------------------------------------------*/ -const AP4_UI32 AP4_SEGMENT_BUILDER_DEFAULT_TIMESCALE = 1000; +const AP4_UI32 AP4_SEGMENT_BUILDER_DEFAULT_TIMESCALE = 1000; +const unsigned int AP4_STREAM_FEEDER_DEFAULT_BUFFER_SIZE = 65536; /*---------------------------------------------------------------------- | AP4_SegmentBuilder::AP4_SegmentBuilder @@ -87,28 +88,6 @@ } /*---------------------------------------------------------------------- -| AP4_FeedSegmentBuilder::AP4_FeedSegmentBuilder -+---------------------------------------------------------------------*/ -AP4_FeedSegmentBuilder::AP4_FeedSegmentBuilder(AP4_Track::Type track_type, - AP4_UI32 track_id, - AP4_UI64 media_time_origin) : - AP4_SegmentBuilder(track_type, track_id, media_time_origin) -{ -} - -/*---------------------------------------------------------------------- -| AP4_AvcSegmentBuilder::AP4_AvcSegmentBuilder -+---------------------------------------------------------------------*/ -AP4_AvcSegmentBuilder::AP4_AvcSegmentBuilder(AP4_UI32 track_id, - double frames_per_second, - AP4_UI64 media_time_origin) : - AP4_FeedSegmentBuilder(AP4_Track::TYPE_VIDEO, track_id, media_time_origin), - m_FramesPerSecond(frames_per_second) -{ - m_Timescale = (unsigned int)(frames_per_second*1000.0); -} - -/*---------------------------------------------------------------------- | AP4_SegmentBuilder::WriteMediaSegment +---------------------------------------------------------------------*/ AP4_Result @@ -118,7 +97,7 @@ if (m_TrackType == AP4_Track::TYPE_VIDEO) { tfhd_flags |= AP4_TFHD_FLAG_DEFAULT_SAMPLE_FLAGS_PRESENT; } - + // setup the moof structure AP4_ContainerAtom* moof = new AP4_ContainerAtom(AP4_ATOM_TYPE_MOOF); AP4_MfhdAtom* mfhd = new AP4_MfhdAtom(sequence_number); @@ -167,7 +146,7 @@ trun_entry.sample_duration = m_Samples[i].GetDuration(); trun_entry.sample_size = m_Samples[i].GetSize(); trun_entry.sample_composition_time_offset = m_Samples[i].GetCtsDelta(); - + mdat_size += trun_entry.sample_size; } @@ -211,69 +190,32 @@ } /*---------------------------------------------------------------------- -| AP4_AvcSegmentBuilder::Feed +| AP4_FeedSegmentBuilder::AP4_FeedSegmentBuilder +---------------------------------------------------------------------*/ -AP4_Result -AP4_AvcSegmentBuilder::Feed(const void* data, - AP4_Size data_size, - AP4_Size& bytes_consumed) +AP4_FeedSegmentBuilder::AP4_FeedSegmentBuilder(AP4_Track::Type track_type, + AP4_UI32 track_id, + AP4_UI64 media_time_origin) : + AP4_SegmentBuilder(track_type, track_id, media_time_origin) { - AP4_Result result; - - AP4_AvcFrameParser::AccessUnitInfo access_unit_info; - result = m_FrameParser.Feed(data, data_size, bytes_consumed, access_unit_info, data == NULL); - if (AP4_FAILED(result)) return result; - - // check if we have an access unit - if (access_unit_info.nal_units.ItemCount()) { - // compute the total size of the sample data - unsigned int sample_data_size = 0; - for (unsigned int i=0; i<access_unit_info.nal_units.ItemCount(); i++) { - sample_data_size += 4+access_unit_info.nal_units[i]->GetDataSize(); - } - - // format the sample data - AP4_MemoryByteStream* sample_data = new AP4_MemoryByteStream(sample_data_size); - for (unsigned int i=0; i<access_unit_info.nal_units.ItemCount(); i++) { - sample_data->WriteUI32(access_unit_info.nal_units[i]->GetDataSize()); - sample_data->Write(access_unit_info.nal_units[i]->GetData(), access_unit_info.nal_units[i]->GetDataSize()); - } - - // compute the timestamp in a drift-less manner - AP4_UI32 duration = 0; - AP4_UI64 dts = 0; - if (m_Timescale !=0 && m_FramesPerSecond != 0.0) { - AP4_UI64 this_sample_time = m_MediaStartTime+m_MediaDuration; - AP4_UI64 next_sample_time = (AP4_UI64)((double)m_Timescale*(double)(m_SampleStartNumber+m_Samples.ItemCount()+1)/m_FramesPerSecond); - duration = (AP4_UI32)(next_sample_time-this_sample_time); - dts = (AP4_UI64)((double)m_Timescale/m_FramesPerSecond*(double)m_Samples.ItemCount()); - } +} - // create a new sample and add it to the list - AP4_Sample sample(*sample_data, 0, sample_data_size, duration, 0, dts, 0, access_unit_info.is_idr); - AddSample(sample); - sample_data->Release(); - - // remember the sample order - m_SampleOrders.Append(SampleOrder(access_unit_info.decode_order, access_unit_info.display_order)); - - // free the memory buffers - for (unsigned int i=0; i<access_unit_info.nal_units.ItemCount(); i++) { - delete access_unit_info.nal_units[i]; - } - access_unit_info.nal_units.Clear(); - - return 1; // one access unit returned - } - - return AP4_SUCCESS; +/*---------------------------------------------------------------------- +| AP4_VideoSegmentBuilder::AP4_VideoSegmentBuilder ++---------------------------------------------------------------------*/ +AP4_VideoSegmentBuilder::AP4_VideoSegmentBuilder(AP4_UI32 track_id, + double frames_per_second, + AP4_UI64 media_time_origin) : + AP4_FeedSegmentBuilder(AP4_Track::TYPE_VIDEO, track_id, media_time_origin), + m_FramesPerSecond(frames_per_second) +{ + m_Timescale = (unsigned int)(frames_per_second*1000.0); } /*---------------------------------------------------------------------- -| AP4_AvcSegmentBuilder::SortSamples +| AP4_VideoSegmentBuilder::SortSamples +---------------------------------------------------------------------*/ void -AP4_AvcSegmentBuilder::SortSamples(SampleOrder* array, unsigned int n) +AP4_VideoSegmentBuilder::SortSamples(SampleOrder* array, unsigned int n) { if (n < 2) { return; @@ -299,10 +241,82 @@ } /*---------------------------------------------------------------------- -| AP4_AvcSegmentBuilder::WriteMediaSegment +| AP4_VideoSegmentBuilder::WriteVideoInitSegment ++---------------------------------------------------------------------*/ +AP4_Result +AP4_VideoSegmentBuilder::WriteVideoInitSegment(AP4_ByteStream& stream, + AP4_SampleDescription* sample_description, + unsigned int width, + unsigned int height, + AP4_UI32 brand) +{ + // create the output file object + AP4_Movie* output_movie = new AP4_Movie(AP4_SEGMENT_BUILDER_DEFAULT_TIMESCALE); + + // create an mvex container + AP4_ContainerAtom* mvex = new AP4_ContainerAtom(AP4_ATOM_TYPE_MVEX); + AP4_MehdAtom* mehd = new AP4_MehdAtom(0); + mvex->AddChild(mehd); + + // create a sample table (with no samples) to hold the sample description + AP4_SyntheticSampleTable* sample_table = new AP4_SyntheticSampleTable(); + sample_table->AddSampleDescription(sample_description, true); + + // create the track + AP4_Track* output_track = new AP4_Track(AP4_Track::TYPE_VIDEO, + sample_table, + m_TrackId, + AP4_SEGMENT_BUILDER_DEFAULT_TIMESCALE, + 0, + m_Timescale, + 0, + m_TrackLanguage.GetChars(), + width << 16, + height << 16); + output_movie->AddTrack(output_track); + + // add a trex entry to the mvex container + AP4_TrexAtom* trex = new AP4_TrexAtom(m_TrackId, + 1, + 0, + 0, + 0); + mvex->AddChild(trex);
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4SegmentBuilder.h -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4SegmentBuilder.h
Changed
@@ -34,11 +34,13 @@ +---------------------------------------------------------------------*/ #include "Ap4Types.h" #include "Ap4AvcParser.h" +#include "Ap4HevcParser.h" #include "Ap4AdtsParser.h" #include "Ap4List.h" #include "Ap4Sample.h" #include "Ap4String.h" #include "Ap4Track.h" +#include "Ap4SampleDescription.h" /*---------------------------------------------------------------------- | class references @@ -67,6 +69,7 @@ // methods virtual AP4_Result AddSample(AP4_Sample& sample); + //virtual AP4_Result CreateTrack(AP4_Track*& track); // create an AP4_Track object representing the media so far virtual AP4_Result WriteMediaSegment(AP4_ByteStream& stream, unsigned int sequence_number); virtual AP4_Result WriteInitSegment(AP4_ByteStream& stream) = 0; @@ -97,49 +100,97 @@ // methods virtual AP4_Result Feed(const void* data, AP4_Size data_size, - AP4_Size& bytes_consumed) = 0; + AP4_Size& bytes_consumed) = 0; }; /*---------------------------------------------------------------------- -| AP4_AvcSegmentBuilder +| AP4_VideoSegmentBuilder +---------------------------------------------------------------------*/ -class AP4_AvcSegmentBuilder : public AP4_FeedSegmentBuilder +class AP4_VideoSegmentBuilder : public AP4_FeedSegmentBuilder { public: // constructor - AP4_AvcSegmentBuilder(AP4_UI32 track_id, - double frames_per_second, - AP4_UI64 media_time_origin = 0); + AP4_VideoSegmentBuilder(AP4_UI32 track_id, + double frames_per_second, + AP4_UI64 media_time_origin = 0); // AP4_SegmentBuilder methods virtual AP4_Result WriteMediaSegment(AP4_ByteStream& stream, unsigned int sequence_number); - virtual AP4_Result WriteInitSegment(AP4_ByteStream& stream); - // methods - AP4_Result Feed(const void* data, - AP4_Size data_size, - AP4_Size& bytes_consumed); - protected: // types struct SampleOrder { SampleOrder(AP4_UI32 decode_order, AP4_UI32 display_order) : m_DecodeOrder(decode_order), m_DisplayOrder(display_order) {} - AP4_UI32 m_DecodeOrder; - AP4_UI32 m_DisplayOrder; + AP4_UI32 m_DecodeOrder; + AP4_UI32 m_DisplayOrder; }; // methods void SortSamples(SampleOrder* array, unsigned int n); + AP4_Result WriteVideoInitSegment(AP4_ByteStream& stream, + AP4_SampleDescription* sample_description, + unsigned int width, + unsigned int height, + AP4_UI32 brand); // members - AP4_AvcFrameParser m_FrameParser; double m_FramesPerSecond; AP4_Array<SampleOrder> m_SampleOrders; }; /*---------------------------------------------------------------------- +| AP4_AvcSegmentBuilder ++---------------------------------------------------------------------*/ +class AP4_AvcSegmentBuilder : public AP4_VideoSegmentBuilder +{ +public: + // constructor + AP4_AvcSegmentBuilder(AP4_UI32 track_id, + double frames_per_second, + AP4_UI64 media_time_origin = 0); + + // AP4_SegmentBuilder methods + virtual AP4_Result WriteInitSegment(AP4_ByteStream& stream); + + // methods + AP4_Result Feed(const void* data, + AP4_Size data_size, + AP4_Size& bytes_consumed); + +protected: + // members + AP4_AvcFrameParser m_FrameParser; +}; + +/*---------------------------------------------------------------------- +| AP4_HevcSegmentBuilder ++---------------------------------------------------------------------*/ +class AP4_HevcSegmentBuilder : public AP4_VideoSegmentBuilder +{ +public: + // constructor + AP4_HevcSegmentBuilder(AP4_UI32 track_id, + double frames_per_second, + AP4_UI32 video_format = AP4_SAMPLE_FORMAT_HEV1, + AP4_UI64 media_time_origin = 0); + + // AP4_SegmentBuilder methods + virtual AP4_Result WriteInitSegment(AP4_ByteStream& stream); + + // methods + AP4_Result Feed(const void* data, + AP4_Size data_size, + AP4_Size& bytes_consumed); + +protected: + // members + AP4_HevcFrameParser m_FrameParser; + AP4_UI32 m_VideoFormat; +}; + +/*---------------------------------------------------------------------- | AP4_AacSegmentBuilder +---------------------------------------------------------------------*/ class AP4_AacSegmentBuilder : public AP4_FeedSegmentBuilder @@ -163,4 +214,28 @@ AP4_MpegAudioSampleDescription* m_SampleDescription; }; +/*---------------------------------------------------------------------- +| AP4_StreamFeeder +| +| Class that can be used to feed an AP4_FeedSegmentBuilder from a stream ++---------------------------------------------------------------------*/ +class AP4_StreamFeeder +{ +public: + // constructor and destructor + AP4_StreamFeeder(AP4_ByteStream* source, AP4_FeedSegmentBuilder& builder); + ~AP4_StreamFeeder(); + + // methods + AP4_Result Feed(); // Read some data from the stream and feed it to the builder + +private: + AP4_ByteStream* m_Source; + AP4_FeedSegmentBuilder& m_Builder; + AP4_UI08* m_FeedBuffer; + AP4_Size m_FeedBufferSize; + AP4_Size m_FeedBytesPending; // number of bytes not yet parsed + AP4_Size m_FeedBytesParsed; // number of bytes already parsed +}; + #endif // _AP4_SEGMENT_BUILDER_H_
View file
bento4-1.5.1r628.tar.gz/Source/C++/Core/Ap4StcoAtom.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Core/Ap4StcoAtom.cpp
Changed
@@ -72,8 +72,13 @@ AP4_UI08 version, AP4_UI32 flags, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_STCO, size, version, flags) + AP4_Atom(AP4_ATOM_TYPE_STCO, size, version, flags), + m_Entries(NULL), + m_EntryCount(0) { + if (size < AP4_FULL_ATOM_HEADER_SIZE + 4) { + return; + } stream.ReadUI32(m_EntryCount); if (m_EntryCount > (size-AP4_FULL_ATOM_HEADER_SIZE-4)/4) { m_EntryCount = (size-AP4_FULL_ATOM_HEADER_SIZE-4)/4;
View file
bento4-1.5.1r628.tar.gz/Source/C++/System/StdC/Ap4StdCFileByteStream.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/System/StdC/Ap4StdCFileByteStream.cpp
Changed
@@ -265,6 +265,9 @@ if (nbWritten > 0) { bytesWritten = (AP4_Size)nbWritten; m_Position += nbWritten; + if (m_Position > m_Size) { + m_Size = m_Position; + } return AP4_SUCCESS; } else { bytesWritten = 0;
View file
bento4-1.5.1r628.tar.gz/Source/C++/Test/FragmentCreator/FragmentCreatorTest.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Test/FragmentCreator/FragmentCreatorTest.cpp
Changed
@@ -44,7 +44,7 @@ main(int argc, char** argv) { if (argc != 8) { - printf("usage: fragmentcreatortest audio|video <media-input-filename> <track-id> <frames-per-segment>|<segment-duration> <frames-per-second>|0 <output-media-segment-filename-pattern> <output-init-segment-filename>\n"); + printf("usage: fragmentcreatortest h265|h264|aac <media-input-filename> <track-id> <frames-per-segment>|<segment-duration> <frames-per-second>|0 <output-media-segment-filename-pattern> <output-init-segment-filename>\n"); return 1; } @@ -67,78 +67,71 @@ } // instantiate a video segment builder or an audio sergment builder - AP4_AvcSegmentBuilder* video_builder = NULL; + AP4_VideoSegmentBuilder* video_builder = NULL; AP4_AacSegmentBuilder* audio_builder = NULL; AP4_FeedSegmentBuilder* feed_builder = NULL; - if (!strcmp(argv[1], "video")) { + if (!strcmp(argv[1], "h265")) { + video_builder = new AP4_HevcSegmentBuilder(track_id, frames_per_second); + feed_builder = video_builder; + } else if (!strcmp(argv[1], "h264")) { video_builder = new AP4_AvcSegmentBuilder(track_id, frames_per_second); feed_builder = video_builder; - } else { + } else if (!strcmp(argv[1], "aac")) { audio_builder = new AP4_AacSegmentBuilder(track_id); feed_builder = audio_builder; + } else { + fprintf(stderr, "ERROR: unsupported media type\n"); + return 1; } + // create a feeder to read from the input and feed the builder + AP4_StreamFeeder stream_feeder(input_stream, *feed_builder); + // parse the input until the end of the stream unsigned int segment_count = 0; - for (;;) { - bool eos; - unsigned char input_buffer[4096]; - AP4_Size bytes_in_buffer = 0; - result = input_stream->ReadPartial(input_buffer, sizeof(input_buffer), bytes_in_buffer); - if (AP4_SUCCEEDED(result)) { - eos = false; - } else if (result == AP4_ERROR_EOS) { + bool eos = false; + while (!eos) { + result = stream_feeder.Feed(); + if (AP4_FAILED(result)) { + if (result != AP4_ERROR_EOS) { + fprintf(stderr, "ERROR: failed to read from stream (%d)\n", result); + break; + } eos = true; - } else { - fprintf(stderr, "ERROR: failed to read from input file\n"); - break; } - AP4_Size offset = 0; - do { - AP4_Size bytes_consumed = 0; - result = feed_builder->Feed(eos?NULL:&input_buffer[offset], - bytes_in_buffer, - bytes_consumed); - if (result < 0) { - fprintf(stderr, "ERROR: Feed() failed (%d)\n", result); - break; + + bool flush = false; + if (video_builder) { + if (video_builder->GetSamples().ItemCount() >= (unsigned int)segment_duration || + (eos && video_builder->GetSamples().ItemCount() != 0)) { + flush = true; } - - offset += bytes_consumed; - bytes_in_buffer -= bytes_consumed; - - bool flush = false; - if (video_builder) { - if (video_builder->GetSamples().ItemCount() >= (unsigned int)segment_duration) { - flush = true; - } - } else { - double target_time = (segment_count+1)*segment_duration; - double elapsed_time = (double)(audio_builder->GetMediaDuration()+audio_builder->GetMediaStartTime())/(double)audio_builder->GetTimescale(); - if (elapsed_time >= target_time) { - flush = true; - } + } else { + double target_time = (segment_count+1)*segment_duration; + double elapsed_time = (double)(audio_builder->GetMediaDuration()+audio_builder->GetMediaStartTime())/(double)audio_builder->GetTimescale(); + if (elapsed_time >= target_time || + (eos && audio_builder->GetSamples().ItemCount() != 0)) { + flush = true; } - if (flush) { - unsigned int max_name_size = (unsigned int)strlen(output_media_segment_filename_pattern)+256; - char* media_segment_filename = new char[max_name_size+1]; - snprintf(media_segment_filename, max_name_size, output_media_segment_filename_pattern, segment_count); - AP4_ByteStream* media_segment_stream = NULL; - - result = AP4_FileByteStream::Create(media_segment_filename, AP4_FileByteStream::STREAM_MODE_WRITE, media_segment_stream); - if (AP4_FAILED(result)) { - fprintf(stderr, "ERROR: cannot create media segment file (%d)\n", result); - return 1; - } - - feed_builder->WriteMediaSegment(*media_segment_stream, segment_count); - - delete[] media_segment_filename; - media_segment_stream->Release(); - ++segment_count; + } + if (flush) { + unsigned int max_name_size = (unsigned int)strlen(output_media_segment_filename_pattern)+256; + char* media_segment_filename = new char[max_name_size+1]; + snprintf(media_segment_filename, max_name_size, output_media_segment_filename_pattern, segment_count); + AP4_ByteStream* media_segment_stream = NULL; + + result = AP4_FileByteStream::Create(media_segment_filename, AP4_FileByteStream::STREAM_MODE_WRITE, media_segment_stream); + if (AP4_FAILED(result)) { + fprintf(stderr, "ERROR: cannot create media segment file (%d)\n", result); + return 1; } - } while (bytes_in_buffer || result > 0); - if (eos) break; + + feed_builder->WriteMediaSegment(*media_segment_stream, segment_count); + + delete[] media_segment_filename; + media_segment_stream->Release(); + ++segment_count; + } } AP4_ByteStream* init_segment_stream = NULL;
View file
bento4-1.5.1r628.tar.gz/Source/C++/Test/LinearReader/LinearReaderTest.cpp -> bento4-1.5.1r629.tar.gz/Source/C++/Test/LinearReader/LinearReaderTest.cpp
Changed
@@ -116,25 +116,6 @@ CHECK(reader.GetBufferFullness() == 0); CHECK(audio_sample_count == audio_track->GetSampleCount()); CHECK(video_sample_count == video_track->GetSampleCount()); - - offset = 0; - audio_sample_count = 0; - //video_sample_count = 0; - reader.SetSampleIndex(audio_track->GetId(), 0); - reader.SetSampleIndex(video_track->GetId(), 0); - do { - result = reader.ReadNextSample(audio_track->GetId(), sample, sample_data); - if (AP4_SUCCEEDED(result)) { - CHECK(offset < sample.GetOffset()); - offset = sample.GetOffset(); - audio_sample_count++; - printf("size=%d, offset=%lld\n", (int)sample.GetSize(), sample.GetOffset()); - } else { - printf("result=%d\n", result); - } - } while (AP4_SUCCEEDED(result)); - CHECK(result == AP4_ERROR_NOT_ENOUGH_SPACE); - CHECK(reader.GetBufferFullness() != 0); // cleanup delete file;
View file
bento4-1.5.1r628.tar.gz/Source/Python/utils/mp4-dash.py -> bento4-1.5.1r629.tar.gz/Source/Python/utils/mp4-dash.py
Changed
@@ -11,6 +11,7 @@ # <platform> depends on the platform you're running on: # Mac OSX --> platform = macosx # Linux x86 --> platform = linux-x86 +# Linux x64 --> platform = linux-x86_64 # Windows --> platform = win32 from optparse import OptionParser @@ -27,7 +28,7 @@ # setup main options VERSION = "1.8.0" -SDK_REVISION = '628' +SDK_REVISION = '629' SCRIPT_PATH = path.abspath(path.dirname(__file__)) sys.path += [SCRIPT_PATH] @@ -42,9 +43,9 @@ NOSPLIT_INIT_FILE_PATTERN = 'init-%s.mp4' ONDEMAND_MEDIA_FILE_PATTERN = '%s-%s.mp4' -PADDED_SEGMENT_PATTERN = 'seg-%04llu.m4s' -PADDED_SEGMENT_URL_PATTERN = 'seg-%04d.m4s' -PADDED_SEGMENT_URL_TEMPLATE = '$RepresentationID$/seg-$Number%04d$.m4s' +PADDED_SEGMENT_PATTERN = 'seg-%05llu.m4s' +PADDED_SEGMENT_URL_PATTERN = 'seg-%05d.m4s' +PADDED_SEGMENT_URL_TEMPLATE = '$RepresentationID$/seg-$Number%05d$.m4s' NOPAD_SEGMENT_PATTERN = 'seg-%llu.m4s' NOPAD_SEGMENT_URL_PATTERN = 'seg-%d.m4s' NOPAD_SEGMENT_URL_TEMPLATE = '$RepresentationID$/seg-$Number$.m4s' @@ -656,6 +657,12 @@ index_playlist_file.write('#EXT-X-I-FRAMES-ONLY\r\n') + + iframe_total_segment_size = 0 + iframe_total_segment_duration = 0 + iframe_bitrate = 0 + iframe_max_bitrate = 0 + if not options.split: # get the I-frame index for a single file json_index = Mp4IframIndex(options, path.join(options.output_dir, media_file_name)) @@ -663,10 +670,18 @@ for i in range(len(track.segment_durations)): if i < len(index): index_entry = index[i] - index_playlist_file.write('#EXTINF:%f,\r\n' % (track.segment_durations[i])) + iframe_segment_duration = track.segment_durations[i] + index_playlist_file.write('#EXTINF:%f,\r\n' % (iframe_segment_duration)) fragment_start = int(index_entry['fragmentStart']) iframe_offset = int(index_entry['offset']) iframe_size = int(index_entry['size']) + + iframe_total_segment_size += iframe_size + iframe_total_segment_duration += iframe_segment_duration + iframe_bitrate = 8.0*(iframe_size/iframe_segment_duration) + if iframe_bitrate > iframe_max_bitrate: + iframe_max_bitrate = iframe_bitrate + iframe_range_size = iframe_size + (iframe_offset-fragment_start) index_playlist_file.write('#EXT-X-BYTERANGE:%d@%d\r\n' % (iframe_range_size, fragment_start)) index_playlist_file.write(media_file_name+'\r\n') @@ -685,12 +700,24 @@ iframe_size = int(index[0]['size']) iframe_offset = int(index[0]['offset']) iframe_range_size = iframe_size + iframe_offset - index_playlist_file.write('#EXTINF:%f,\r\n' % (track.segment_durations[i])) + iframe_segment_duration = track.segment_durations[i] + index_playlist_file.write('#EXTINF:%f,\r\n' % (iframe_segment_duration)) index_playlist_file.write('#EXT-X-BYTERANGE:%d@0\r\n' % (iframe_range_size)) index_playlist_file.write(fragment_basename+'\r\n') + iframe_total_segment_size += iframe_size + iframe_total_segment_duration += iframe_segment_duration + + iframe_bitrate = 8.0*(iframe_size/iframe_segment_duration) + if iframe_bitrate > iframe_max_bitrate: + iframe_max_bitrate = iframe_bitrate + index_playlist_file.write('#EXT-X-ENDLIST\r\n') + iframe_average_segment_bitrate = 8.0*(iframe_total_segment_size/iframe_total_segment_duration) + + return (iframe_average_segment_bitrate, iframe_max_bitrate) + ############################################# def OutputHls(options, set_attributes, audio_sets, video_sets, subtitles_sets, subtitles_files): # all_audio_tracks = sum(audio_sets.values(), []) @@ -760,46 +787,51 @@ media_playlist_name = video_track.representation_id+".m3u8" media_playlist_path = media_playlist_name iframes_playlist_name = video_track.representation_id+"_iframes.m3u8" + iframes_playlist_path = iframes_playlist_name else: media_subdir = video_track.representation_id media_file_name = '' media_playlist_name = options.hls_media_playlist_name media_playlist_path = media_subdir+'/'+media_playlist_name iframes_playlist_name = options.hls_iframes_playlist_name + iframes_playlist_path = media_subdir+'/'+iframes_playlist_name if len(audio_groups): # one entry per audio group for audio_group_name in audio_groups: audio_codec = audio_groups[audio_group_name]['codec'] - master_playlist_file.write('#EXT-X-STREAM-INF:AUDIO="%s",AVERAGE-BANDWIDTH=%d,BANDWIDTH=%d,CODECS="%s",RESOLUTION=%dx%d\r\n' % ( + master_playlist_file.write('#EXT-X-STREAM-INF:AUDIO="%s",AVERAGE-BANDWIDTH=%d,BANDWIDTH=%d,CODECS="%s",RESOLUTION=%dx%d,FRAME-RATE=%s\r\n' % ( audio_group_name, video_track.average_segment_bitrate + audio_groups[audio_group_name]['average_segment_bitrate'], video_track.max_segment_bitrate + audio_groups[audio_group_name]['max_segment_bitrate'], video_track.codec+','+audio_codec, video_track.width, - video_track.height)) + video_track.height, + video_track.frame_rate)) master_playlist_file.write(media_playlist_path+'\r\n') else: # no audio - master_playlist_file.write('#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=%d,BANDWIDTH=%d,CODECS="%s",RESOLUTION=%dx%d\r\n' % ( + master_playlist_file.write('#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=%d,BANDWIDTH=%d,CODECS="%s",RESOLUTION=%dx%d,FRAME-RATE=%s\r\n' % ( video_track.average_segment_bitrate, video_track.max_segment_bitrate, video_track.codec, video_track.width, - video_track.height)) + video_track.height, + video_track.frame_rate)) master_playlist_file.write(media_playlist_path+'\r\n') OutputHlsTrack(options, video_track, media_subdir, media_playlist_name, media_file_name) - OutputHlsIframeIndex(options, video_track, media_subdir, iframes_playlist_name, media_file_name) + iframe_average_segment_bitrate,iframe_max_bitrate = OutputHlsIframeIndex(options, video_track, media_subdir, iframes_playlist_name, media_file_name) + # this will be written later iframe_playlist_lines.append('#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=%d,BANDWIDTH=%d,CODECS="%s",RESOLUTION=%dx%d,URI="%s"\r\n' % ( - video_track.average_segment_bitrate, - video_track.max_segment_bitrate, + iframe_average_segment_bitrate, + iframe_max_bitrate, video_track.codec, video_track.width, video_track.height, - media_playlist_path)) + iframes_playlist_path)) master_playlist_file.write('\r\n# I-Frame Playlists\r\n') master_playlist_file.write(''.join(iframe_playlist_lines)) @@ -1535,6 +1567,7 @@ track_file.name, track = str(track.id), index = True, + copy_udta = True, quiet = True) media_source = MediaSource(track_file.name)
View file
bento4-1.5.1r628.tar.gz/Source/Python/utils/mp4-hls.py -> bento4-1.5.1r629.tar.gz/Source/Python/utils/mp4-hls.py
Changed
@@ -22,7 +22,7 @@ # setup main options VERSION = "1.1.0" -SDK_REVISION = '628' +SDK_REVISION = '629' SCRIPT_PATH = path.abspath(path.dirname(__file__)) sys.path += [SCRIPT_PATH] @@ -444,7 +444,7 @@ int(media_info['stats']['max_segment_bitrate'])+group_info['max_segment_bitrate'], ','.join(codecs)) if 'video' in media_info: - ext_x_stream_inf += ',RESOLUTION='+str(int(media_info['video']['width']))+'x'+str(int(media_info['video']['height'])) + ext_x_stream_inf += ',FRAME-RATE='+str(media_info['stats']['frame_rate'])+',RESOLUTION='+str(int(media_info['video']['width']))+'x'+str(int(media_info['video']['height'])) # audio info if group_name:
View file
bento4-1.5.1r628.tar.gz/Source/Python/utils/skm.py -> bento4-1.5.1r629.tar.gz/Source/Python/utils/skm.py
Changed
@@ -2,6 +2,7 @@ import os import hashlib import json +import urllib KEKID_CONSTANT_1 = "KEKID_1" @@ -149,7 +150,7 @@ kid = spec_params['kid'] if '?' in base_url: (base_url_path, base_url_query) = tuple(base_url.split('?', 1)) - base_url_query = '?'+base_url_query + base_url_query = '?'+urllib.unquote(base_url_query).decode('utf8') else: base_url_path = base_url base_url_query = ''
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.