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 2
View file
bento4.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Wed Jun 7 07:03:05 UTC 2017 - aloisio@gmx.com + +- Update to 1.5.0-615 + +------------------------------------------------------------------- Tue Apr 11 11:00:01 UTC 2017 - aloisio@gmx.com - Initial package (v1.5.0-614)
View file
bento4.spec
Changed
@@ -16,10 +16,10 @@ # -%define _over 1.5.0-614 -%define _libver 1_5_0r614 +%define _over 1.5.0-615 +%define _libver 1_5_0r615 Name: bento4 -Version: 1.5.0r614 +Version: 1.5.0r615 Release: 0 Summary: C++ toolkit for all your MP4 and MPEG DASH media format needs License: GPL-2.0
View file
bento4-1.5.0r614.tar.gz/Documents/Websites/www.bok.net/dash/players/html5/presets.js -> bento4-1.5.0r615.tar.gz/Documents/Websites/www.bok.net/dash/players/html5/presets.js
Changed
@@ -17,59 +17,59 @@ emeConfig: 'manual' }, { - title: 'Guido Bunny WV', - url: 'https://s3.amazonaws.com/exp.tutorial/output_bunny/stream.mpd', - licenseUrl: 'https://wv.test.expressplay.com/hms/wv/rights/?ExpressPlayToken=AQAAAw3paOwAAABQTIL_9kQ0ovZm4rsIOjZosklIDNdmy4olq4L9ivYyzS5RiMqVyPhTQT4Z2lWqQskU4Kn9Lno4H-pQSbJ8NxQiyB3Sb-w0OGBLhYlz29DiPoP8wTJginn-6qHfMsbxv5_03U5FMg', - emeConfig: 'license-url' - }, - { - title: 'Local Bunny ClearKey', - url: 'http://192.168.1.199:8081/bunny_wv/stream.mpd', - kid: '12341234123412341234123412341234', - key: '43215678123412341234123412341234', + title: 'Local Test, CENC, ClearKey', + url: 'http://localhost:8081/clearkey_cenc/stream.mpd', + kid: '000102030405060708090a0b0c0d0e0f', + key: '00112233445566778899aabbccddeeff', emeConfig: 'manual' }, { - title: 'Local Bunny WV', - url: 'http://192.168.1.199:8081/bunny_wv/stream.mpd', - licenseUrl: 'https://wv.test.expressplay.com/hms/wv/rights/?ExpressPlayToken=AQAAAw3paOwAAABQTIL_9kQ0ovZm4rsIOjZosklIDNdmy4olq4L9ivYyzS5RiMqVyPhTQT4Z2lWqQskU4Kn9Lno4H-pQSbJ8NxQiyB3Sb-w0OGBLhYlz29DiPoP8wTJginn-6qHfMsbxv5_03U5FMg', - emeConfig: 'license-url' + title: 'Local Test, CBC1, ClearKey', + url: 'http://localhost:8081/clearkey__cbc1/stream.mpd', + kid: '000102030405060708090a0b0c0d0e0f', + key: '00112233445566778899aabbccddeeff', + emeConfig: 'manual' }, { - title: 'Local Bunny WV - Video Only', - url: 'http://192.168.1.199:8081/bunny_video_wv/stream.mpd', - licenseUrl: 'https://wv.test.expressplay.com/hms/wv/rights/?ExpressPlayToken=AQAAAw3paOwAAABQTIL_9kQ0ovZm4rsIOjZosklIDNdmy4olq4L9ivYyzS5RiMqVyPhTQT4Z2lWqQskU4Kn9Lno4H-pQSbJ8NxQiyB3Sb-w0OGBLhYlz29DiPoP8wTJginn-6qHfMsbxv5_03U5FMg', - emeConfig: 'license-url' + title: 'Local Test, CENS, ClearKey', + url: 'http://localhost:8081/clearkey__cens/stream.mpd', + kid: '000102030405060708090a0b0c0d0e0f', + key: '00112233445566778899aabbccddeeff', + emeConfig: 'manual' }, { - title: 'Local Bunny WV - FFMPEG', - url: 'http://192.168.1.199:8081/bunny_ff_wv/stream.mpd', - licenseUrl: 'https://wv.test.expressplay.com/hms/wv/rights/?ExpressPlayToken=AQAAAw3paOwAAABQTIL_9kQ0ovZm4rsIOjZosklIDNdmy4olq4L9ivYyzS5RiMqVyPhTQT4Z2lWqQskU4Kn9Lno4H-pQSbJ8NxQiyB3Sb-w0OGBLhYlz29DiPoP8wTJginn-6qHfMsbxv5_03U5FMg', - emeConfig: 'license-url' + title: 'Local Test, CBCS, ClearKey', + url: 'http://localhost:8081/clearkey__cbcs/stream.mpd', + kid: '000102030405060708090a0b0c0d0e0f', + key: '00112233445566778899aabbccddeeff', + emeConfig: 'manual' }, { - title: 'Local Sintel ClearKey', - url: 'http://192.168.1.199:8081/sintel_wv/stream.mpd', - kid: '12341234123412341234123412341234', - key: '43215678123412341234123412341234', + title: 'Local Test, CENC, Widevine', + url: 'http://localhost:8081/widevine_cenc/stream.mpd', + kid: '90351951686b5e1ba222439ecec1f12a', + key: '0a237b0752cbf1a827e2fecfb87479a2', emeConfig: 'manual' }, { - title: 'Local Sintel WV', - url: 'http://192.168.1.199:8081/sintel_wv/stream.mpd', - licenseUrl: 'https://wv.test.expressplay.com/hms/wv/rights/?ExpressPlayToken=AQAAAw3paOwAAABQTIL_9kQ0ovZm4rsIOjZosklIDNdmy4olq4L9ivYyzS5RiMqVyPhTQT4Z2lWqQskU4Kn9Lno4H-pQSbJ8NxQiyB3Sb-w0OGBLhYlz29DiPoP8wTJginn-6qHfMsbxv5_03U5FMg', - emeConfig: 'license-url' + title: 'Local Test, CBC1, Widevine', + url: 'http://localhost:8081/widevine_cbc1/stream.mpd', + kid: '90351951686b5e1ba222439ecec1f12a', + key: '0a237b0752cbf1a827e2fecfb87479a2', + emeConfig: 'manual' }, { - title: 'Local Mango WV', - url: 'http://192.168.1.199:8081/tears_wv/stream.mpd', - licenseUrl: 'https://wv.test.expressplay.com/hms/wv/rights/?ExpressPlayToken=AQAAAw3paOwAAABQTIL_9kQ0ovZm4rsIOjZosklIDNdmy4olq4L9ivYyzS5RiMqVyPhTQT4Z2lWqQskU4Kn9Lno4H-pQSbJ8NxQiyB3Sb-w0OGBLhYlz29DiPoP8wTJginn-6qHfMsbxv5_03U5FMg', - emeConfig: 'license-url' + title: 'Local Test, CENS, Widevine', + url: 'http://localhost:8081/widevine_cens/stream.mpd', + kid: '90351951686b5e1ba222439ecec1f12a', + key: '0a237b0752cbf1a827e2fecfb87479a2', + emeConfig: 'manual' }, { - title: 'Local Bunny PR', - url: 'http://192.168.1.199:8081/bunny_pr/stream.mpd', - licenseUrl: 'http://pr.test.expressplay.com/playready/RightsManager.asmx?ExpressPlayToken=AQAAAw3pWq4AAABg6n4MVsv33YnWphWSMTHOCPWrKJmUxfMbfQ6Q8OaxvdWo5cuBvYZADKNNUG9gO45Y9IBO2VZk1PU7YQBr-_jE4hBswX6U0iHTZO2lw7dkcprR2eaP-X0dv7hcfkWhshL51vKV-ibDwSPJx5Or-5F-eZqAyWc', - emeConfig: 'license-url' + title: 'Local Test, CBCS, Widevine', + url: 'http://localhost:8081/widevine_cbcs/stream.mpd', + kid: '90351951686b5e1ba222439ecec1f12a', + key: '0a237b0752cbf1a827e2fecfb87479a2', + emeConfig: 'manual' } ];
View file
bento4-1.5.0r614.tar.gz/Documents/Websites/www.bok.net/dash/players/html5/shaka-player/app.js -> bento4-1.5.0r615.tar.gz/Documents/Websites/www.bok.net/dash/players/html5/shaka-player/app.js
Changed
@@ -120,7 +120,7 @@ var mediaUrl = document.getElementById('manifestUrlInput').value; // (re)configure the player - drmConfig = { + var drmConfig = { drm: { servers: { 'com.widevine.alpha': 'https://widevine-proxy.appspot.com/proxy'
View file
bento4-1.5.0r614.tar.gz/Documents/Websites/www.bok.net/dash/players/html5/shaka-player/index.html -> bento4-1.5.0r615.tar.gz/Documents/Websites/www.bok.net/dash/players/html5/shaka-player/index.html
Changed
@@ -1,11 +1,10 @@ <html> <head> - <title>Sample DASH Player using dash.js</title> + <title>Sample DASH Player using Shaka Player</title> <!-- <script src="shaka-player.compiled.debug.js"></script> --> - - <script src="third_party/closure/goog/base.js"></script> - <script src="dist/deps.js"></script> - <script src="shaka-player.uncompiled.js"></script> + <!-- <script src="third_party/closure/goog/base.js"></script> --> + <!-- <script src="dist/deps.js"></script> --> + <script src="//cdnjs.cloudflare.com/ajax/libs/shaka-player/2.0.5/shaka-player.compiled.debug.js"></script> <script src="app.js"></script> <script src="../presets.js"></script>
View file
bento4-1.5.0r614.tar.gz/Source/C++/Apps/Mp42Hls/Mp42Hls.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Apps/Mp42Hls/Mp42Hls.cpp
Changed
@@ -1080,7 +1080,10 @@ last_ts = audio_ts; } if (segment_output) { - // compute the segment size (not including padding) + // flush the output stream + segment_output->Flush(); + + // compute the segment size (including padding) AP4_Position segment_end = 0; segment_output->Tell(segment_end); AP4_UI32 segment_size = 0; @@ -1090,9 +1093,6 @@ segment_size = (AP4_UI32)(segment_end-segment_position); } - // flush the output stream - segment_output->Flush(); - // update counters segment_sizes.Append(segment_size); segment_positions.Append(segment_position);
View file
bento4-1.5.0r614.tar.gz/Source/C++/Apps/Mp4Fragment/Mp4Fragment.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Apps/Mp4Fragment/Mp4Fragment.cpp
Changed
@@ -202,6 +202,7 @@ AP4_Ordinal m_FragmentIndex; AP4_Sample m_Sample; AP4_UI64 m_Timestamp; + AP4_UI64 m_UnscaledTimestamp; bool m_Eos; AP4_TfraAtom* m_Tfra; }; @@ -215,6 +216,7 @@ m_SampleIndex(0), m_FragmentIndex(0), m_Timestamp(0), + m_UnscaledTimestamp(0), m_Eos(false), m_Tfra(new AP4_TfraAtom(0)) { @@ -571,7 +573,7 @@ // emit a fragment for the selected track if (Options.verbosity > 1) { - printf("fragment: track ID %d ", cursor->m_Track->GetId()); + printf("fragment: track ID %d\n", cursor->m_Track->GetId()); } // decide which sample description index to use @@ -608,8 +610,7 @@ AP4_TfdtAtom* tfdt = new AP4_TfdtAtom(1, cursor->m_Timestamp + (AP4_UI64)(Options.tfdt_start * (double)cursor->m_Track->GetMediaTimeScale())); traf->AddChild(tfdt); } - AP4_UI32 trun_flags = AP4_TRUN_FLAG_DATA_OFFSET_PRESENT | - AP4_TRUN_FLAG_SAMPLE_DURATION_PRESENT | + AP4_UI32 trun_flags = AP4_TRUN_FLAG_DATA_OFFSET_PRESENT | AP4_TRUN_FLAG_SAMPLE_SIZE_PRESENT; AP4_UI32 first_sample_flags = 0; if (cursor->m_Track->GetType() == AP4_Track::TYPE_VIDEO) { @@ -626,9 +627,11 @@ fragments.Add(fragment); // add samples to the fragment - unsigned int sample_count = 0; + unsigned int sample_count = 0; 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; for (;;) { // if we have one non-zero CTS delta, we'll need to express it if (cursor->m_Sample.GetCtsDelta()) { @@ -638,11 +641,13 @@ // add one sample trun_entries.SetItemCount(sample_count+1); AP4_TrunAtom::Entry& trun_entry = trun_entries[sample_count]; - trun_entry.sample_duration = timescale? - (AP4_UI32)AP4_ConvertTime(cursor->m_Sample.GetDuration(), - cursor->m_Track->GetMediaTimeScale(), - timescale): - cursor->m_Sample.GetDuration(); + AP4_UI64 next_unscaled_timestamp = cursor->m_UnscaledTimestamp+cursor->m_Sample.GetDuration(); + AP4_UI64 next_scaled_timestamp = timescale? + AP4_ConvertTime(next_unscaled_timestamp, + cursor->m_Track->GetMediaTimeScale(), + timescale): + next_unscaled_timestamp; + trun_entry.sample_duration = (AP4_UI32)(next_scaled_timestamp-cursor->m_Timestamp); trun_entry.sample_size = cursor->m_Sample.GetSize(); trun_entry.sample_composition_time_offset = timescale? (AP4_UI32)AP4_ConvertTime(cursor->m_Sample.GetCtsDelta(), @@ -655,8 +660,20 @@ fragment->m_MdatSize += trun_entry.sample_size; fragment->m_Duration += trun_entry.sample_duration; + // check if the durations are all the same + if (all_segment_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; + } + } + } + // next sample - cursor->m_Timestamp += trun_entry.sample_duration; + cursor->m_UnscaledTimestamp = next_unscaled_timestamp; + cursor->m_Timestamp = next_scaled_timestamp; result = cursor->SetSampleIndex(cursor->m_SampleIndex+1); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to get sample %d (%d)\n", cursor->m_SampleIndex+1, result); @@ -673,10 +690,19 @@ break; // done with this fragment } } - if (Options.verbosity > 1) { + if (Options.verbosity > 2) { printf(" %d samples\n", sample_count); + printf(" constant sample duration: %s\n", all_segment_durations_equal?"yes":"no"); } - + + // update the 'trun' flags if needed + if (all_segment_durations_equal) { + tfhd->SetDefaultSampleDuration(constant_sample_duration); + tfhd->UpdateFlags(tfhd->GetFlags() | AP4_TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT); + } else { + trun->SetFlags(trun->GetFlags() | AP4_TRUN_FLAG_SAMPLE_DURATION_PRESENT); + } + // update moof and children trun->SetEntries(trun_entries); trun->SetDataOffset((AP4_UI32)moof->GetSize()+AP4_ATOM_HEADER_SIZE);
View file
bento4-1.5.0r614.tar.gz/Source/C++/Apps/Mp4Info/Mp4Info.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Apps/Mp4Info/Mp4Info.cpp
Changed
@@ -40,13 +40,19 @@ /*---------------------------------------------------------------------- | constants +---------------------------------------------------------------------*/ -#define BANNER "MP4 File Info - Version 1.3.3\n"\ +#define BANNER "MP4 File Info - Version 1.3.4\n"\ "(Bento4 Version " AP4_VERSION_STRING ")\n"\ - "(c) 2002-2015 Axiomatic Systems, LLC" + "(c) 2002-2017 Axiomatic Systems, LLC" /*---------------------------------------------------------------------- | globals +---------------------------------------------------------------------*/ +typedef struct { + AP4_UI64 sample_count; + AP4_UI64 duration; + double bitrate; +} MediaInfo; + typedef enum { TEXT_FORMAT, JSON_FORMAT @@ -964,12 +970,11 @@ } /*---------------------------------------------------------------------- -| ComputeBitrate +| ScanMedia +---------------------------------------------------------------------*/ -static double -ComputeBitrate(AP4_Movie& movie, AP4_Track& track, AP4_ByteStream& stream) +static void +ScanMedia(AP4_Movie& movie, AP4_Track& track, AP4_ByteStream& stream, MediaInfo& info) { - double bitrate = 0.0; AP4_UI64 total_size = 0; AP4_UI64 total_duration = 0; @@ -979,6 +984,8 @@ AP4_LinearReader reader(movie, &stream); reader.EnableTrack(track.GetId()); + info.sample_count = 0; + AP4_Sample sample; if (movie.HasFragments()) { AP4_DataBuffer sample_data; @@ -988,11 +995,13 @@ if (AP4_SUCCEEDED(result)) { total_size += sample.GetSize(); total_duration += sample.GetDuration(); + ++info.sample_count; } else { break; } } } else { + info.sample_count = track.GetSampleCount(); for (unsigned int i=0; i<track.GetSampleCount(); i++) { if (AP4_SUCCEEDED(track.GetSample(i, sample))) { total_size += sample.GetSize(); @@ -1000,13 +1009,14 @@ } total_duration = track.GetMediaDuration(); } + info.duration = total_duration; double duration_ms = (double)AP4_ConvertTime(total_duration, track.GetMediaTimeScale(), 1000); if (duration_ms) { - bitrate = 8.0*1000.0*(double)total_size/duration_ms; + info.bitrate = 8.0*1000.0*(double)total_size/duration_ms; + } else { + info.bitrate = 0.0; } - - return bitrate; } /*---------------------------------------------------------------------- @@ -1053,7 +1063,14 @@ printf(" duration: %lld (media timescale units)\n", track.GetMediaDuration()); printf(" duration: %d (ms)\n", (AP4_UI32)AP4_ConvertTime(track.GetMediaDuration(), track.GetMediaTimeScale(), 1000)); if (!fast) { - printf(" bitrate (computed): %.3f Kbps\n", (float)ComputeBitrate(movie, track, stream)/1000.0); + MediaInfo media_info; + ScanMedia(movie, track, stream, media_info); + printf(" bitrate (computed): %.3f Kbps\n", media_info.bitrate/1000.0); + if (movie.HasFragments()) { + printf(" sample count with fragments: %lld\n", media_info.sample_count); + printf(" duration with fragments: %lld\n", media_info.duration); + printf(" duration with fragments: %d (ms)\n", (AP4_UI32)AP4_ConvertTime(media_info.duration, track.GetMediaTimeScale(), 1000)); + } } if (track.GetWidth() || track.GetHeight()) { printf(" display width: %f\n", (float)track.GetWidth()/65536.0); @@ -1141,8 +1158,17 @@ printf(" \"duration\":%lld,\n", track.GetMediaDuration()); printf(" \"duration_ms\":%d", (AP4_UI32)AP4_ConvertTime(track.GetMediaDuration(), track.GetMediaTimeScale(), 1000)); if (!fast) { + MediaInfo media_info; + ScanMedia(movie, track, stream, media_info); printf(",\n"); - printf(" \"bitrate\":%.3f\n", (float)ComputeBitrate(movie, track, stream)/1000.0); + printf(" \"bitrate\":%.3f", media_info.bitrate/1000.0); + if (movie.HasFragments()) { + printf(",\n"); + printf(" \"sample_count_with_fragments\":%lld,\n", media_info.sample_count); + printf(" \"duration_with_fragments\":%lld,\n", media_info.duration); + printf(" \"duration_with_fragments_ms\":%d", (AP4_UI32)AP4_ConvertTime(media_info.duration, track.GetMediaTimeScale(), 1000)); + } + printf("\n"); } else { printf("\n"); } @@ -1259,13 +1285,19 @@ break; } } + + if (Options.format == JSON_FORMAT) { + printf("],\n"); + } + + // fast-start switch (Options.format) { case TEXT_FORMAT: - printf("\n"); + printf(" fast start: %s\n\n", file.IsMoovBeforeMdat() ? "yes" : "no"); break; case JSON_FORMAT: - printf("]\n},\n"); + printf(" \"fast_start\":%s\n},\n", file.IsMoovBeforeMdat() ? "true" : "false"); break; } } @@ -1535,7 +1567,6 @@ if (Options.format == JSON_FORMAT) printf("{\n"); AP4_File* file = new AP4_File(*input, true); - input->Release(); ShowFileInfo(*file); AP4_Movie* movie = file->GetMovie(); @@ -1576,6 +1607,7 @@ if (Options.format == JSON_FORMAT) printf("}\n"); + input->Release(); delete file; return 0;
View file
bento4-1.5.0r614.tar.gz/Source/C++/Codecs/Ap4AvcParser.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Codecs/Ap4AvcParser.cpp
Changed
@@ -263,7 +263,9 @@ | AP4_AvcFrameParser::ParseSPS +---------------------------------------------------------------------*/ AP4_Result -AP4_AvcFrameParser::ParseSPS(const unsigned char* data, unsigned int data_size, AP4_AvcSequenceParameterSet& sps) +AP4_AvcFrameParser::ParseSPS(const unsigned char* data, + unsigned int data_size, + AP4_AvcSequenceParameterSet& sps) { sps.raw_bytes.SetData(data, data_size); AP4_DataBuffer unescaped(data, data_size); @@ -404,7 +406,9 @@ | AP4_AvcFrameParser::ParsePPS +---------------------------------------------------------------------*/ AP4_Result -AP4_AvcFrameParser::ParsePPS(const unsigned char* data, unsigned int data_size, AP4_AvcPictureParameterSet& pps) +AP4_AvcFrameParser::ParsePPS(const unsigned char* data, + unsigned int data_size, + AP4_AvcPictureParameterSet& pps) { pps.raw_bytes.SetData(data, data_size); AP4_DataBuffer unescaped(data, data_size); @@ -497,10 +501,10 @@ | AP4_AvcFrameParser::ParseSliceHeader +---------------------------------------------------------------------*/ AP4_Result -AP4_AvcFrameParser::ParseSliceHeader(const AP4_UI08* data, - unsigned int data_size, - unsigned int nal_unit_type, - AP4_AvcSliceHeader& slice_header) +AP4_AvcFrameParser::ParseSliceHeader(const AP4_UI08* data, + unsigned int data_size, + unsigned int nal_unit_type, + AP4_AvcSliceHeader& slice_header) { AP4_DataBuffer unescaped(data, data_size); AP4_NalParser::Unescape(unescaped);
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4CommonEncryption.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4CommonEncryption.cpp
Changed
@@ -64,60 +64,64 @@ const unsigned int AP4_CENC_NAL_UNIT_ENCRYPTION_MIN_SIZE = 112; /*---------------------------------------------------------------------- -| AP4_CencSampleEncrypter::~AP4_CencSampleEncrypter -+---------------------------------------------------------------------*/ -AP4_CencSampleEncrypter::~AP4_CencSampleEncrypter() -{ - delete m_Cipher; -} - -/*---------------------------------------------------------------------- -| AP4_CencCtrSampleEncrypter::EncryptSampleData +| AP4_CencBasicSubSampleMapper::GetSubSampleMap +---------------------------------------------------------------------*/ AP4_Result -AP4_CencCtrSampleEncrypter::EncryptSampleData(AP4_DataBuffer& data_in, - AP4_DataBuffer& data_out, - AP4_DataBuffer& /* sample_infos */) +AP4_CencBasicSubSampleMapper::GetSubSampleMap(AP4_DataBuffer& sample_data, + AP4_Array<AP4_UI16>& bytes_of_cleartext_data, + AP4_Array<AP4_UI32>& bytes_of_encrypted_data) { - // the output has the same size as the input - data_out.SetDataSize(data_in.GetDataSize()); - // setup direct pointers to the buffers - const AP4_UI08* in = data_in.GetData(); - AP4_UI08* out = data_out.UseData(); + const AP4_UI08* in = sample_data.GetData(); - // setup the IV - m_Cipher->SetIV(m_Iv); + // process the sample data, one NALU at a time + const AP4_UI08* in_end = sample_data.GetData()+sample_data.GetDataSize(); + while ((AP4_Size)(in_end-in) > 1+m_NaluLengthSize) { + unsigned int nalu_length; + switch (m_NaluLengthSize) { + case 1: + nalu_length = *in; + break; + + case 2: + nalu_length = AP4_BytesToUInt16BE(in); + break; + + case 4: + nalu_length = AP4_BytesToUInt32BE(in); + break; + + default: + return AP4_ERROR_INVALID_FORMAT; + } - // process the sample data - if (data_in.GetDataSize()) { - AP4_Size out_size = data_out.GetDataSize(); - AP4_Result result = m_Cipher->ProcessBuffer(in, data_in.GetDataSize(), out, &out_size, false); - if (AP4_FAILED(result)) return result; - } - - // update the IV - if (m_IvSize == 16) { - unsigned int block_count = (data_in.GetDataSize()+15)/16; - AP4_UI64 counter = AP4_BytesToUInt64BE(&m_Iv[8]); - AP4_BytesFromUInt64BE(&m_Iv[8], counter+block_count); - } else if (m_IvSize == 8){ - AP4_UI64 counter = AP4_BytesToUInt64BE(&m_Iv[0]); - AP4_BytesFromUInt64BE(&m_Iv[0], counter+1); - } else { - return AP4_ERROR_INTERNAL; + unsigned int chunk_size = m_NaluLengthSize+nalu_length; + unsigned int cleartext_size = chunk_size%16; + unsigned int block_count = chunk_size/16; + if (cleartext_size < m_NaluLengthSize+1) { + AP4_ASSERT(block_count); + --block_count; + cleartext_size += 16; + } + + // move the pointers + in += chunk_size; + + // store the info + bytes_of_cleartext_data.Append((AP4_UI16)cleartext_size); + bytes_of_encrypted_data.Append((AP4_UI32)(block_count*16)); } return AP4_SUCCESS; } /*---------------------------------------------------------------------- -| AP4_CencCtrSubSampleEncrypter::GetSubSampleMap +| AP4_CencAdvancedSubSampleEncrypter::GetSubSampleMap +---------------------------------------------------------------------*/ AP4_Result -AP4_CencCtrSubSampleEncrypter::GetSubSampleMap(AP4_DataBuffer& sample_data, - AP4_Array<AP4_UI16>& bytes_of_cleartext_data, - AP4_Array<AP4_UI32>& bytes_of_encrypted_data) +AP4_CencAdvancedSubSampleMapper::GetSubSampleMap(AP4_DataBuffer& sample_data, + AP4_Array<AP4_UI16>& bytes_of_cleartext_data, + AP4_Array<AP4_UI32>& bytes_of_encrypted_data) { // setup direct pointers to the buffers const AP4_UI08* in = sample_data.GetData(); @@ -209,6 +213,54 @@ } /*---------------------------------------------------------------------- +| AP4_CencSampleEncrypter::~AP4_CencSampleEncrypter ++---------------------------------------------------------------------*/ +AP4_CencSampleEncrypter::~AP4_CencSampleEncrypter() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_CencCtrSampleEncrypter::EncryptSampleData ++---------------------------------------------------------------------*/ +AP4_Result +AP4_CencCtrSampleEncrypter::EncryptSampleData(AP4_DataBuffer& data_in, + AP4_DataBuffer& data_out, + AP4_DataBuffer& /* sample_infos */) +{ + // the output has the same size as the input + data_out.SetDataSize(data_in.GetDataSize()); + + // setup direct pointers to the buffers + const AP4_UI08* in = data_in.GetData(); + AP4_UI08* out = data_out.UseData(); + + // setup the IV + m_Cipher->SetIV(m_Iv); + + // process the sample data + if (data_in.GetDataSize()) { + AP4_Size out_size = data_out.GetDataSize(); + AP4_Result result = m_Cipher->ProcessBuffer(in, data_in.GetDataSize(), out, &out_size, false); + if (AP4_FAILED(result)) return result; + } + + // update the IV + if (m_IvSize == 16) { + unsigned int block_count = (data_in.GetDataSize()+15)/16; + AP4_UI64 counter = AP4_BytesToUInt64BE(&m_Iv[8]); + AP4_BytesFromUInt64BE(&m_Iv[8], counter+block_count); + } else if (m_IvSize == 8){ + AP4_UI64 counter = AP4_BytesToUInt64BE(&m_Iv[0]); + AP4_BytesFromUInt64BE(&m_Iv[0], counter+1); + } else { + return AP4_ERROR_INTERNAL; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- | AP4_CencCtrSubSampleEncrypter::EncryptSampleData +---------------------------------------------------------------------*/ AP4_Result @@ -233,7 +285,7 @@ // get the subsample map AP4_Array<AP4_UI16> bytes_of_cleartext_data; AP4_Array<AP4_UI32> bytes_of_encrypted_data; - AP4_Result result = GetSubSampleMap(data_in, bytes_of_cleartext_data, bytes_of_encrypted_data); + AP4_Result result = m_SubSampleMapper->GetSubSampleMap(data_in, bytes_of_cleartext_data, bytes_of_encrypted_data); if (AP4_FAILED(result)) return result; // process the data @@ -279,58 +331,6 @@ } /*---------------------------------------------------------------------- -| AP4_CencCbcSubSampleEncrypter::GetSubSampleMap -+---------------------------------------------------------------------*/ -AP4_Result -AP4_CencCbcSubSampleEncrypter::GetSubSampleMap(AP4_DataBuffer& sample_data, - AP4_Array<AP4_UI16>& bytes_of_cleartext_data, - AP4_Array<AP4_UI32>& bytes_of_encrypted_data) -{ - // setup direct pointers to the buffers - const AP4_UI08* in = sample_data.GetData(); - - // process the sample data, one NALU at a time - const AP4_UI08* in_end = sample_data.GetData()+sample_data.GetDataSize(); - while ((AP4_Size)(in_end-in) > 1+m_NaluLengthSize) { - unsigned int nalu_length; - switch (m_NaluLengthSize) { - case 1: - nalu_length = *in; - break; - - case 2: - nalu_length = AP4_BytesToUInt16BE(in); - break; - - case 4: - nalu_length = AP4_BytesToUInt32BE(in); - break; -
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4CommonEncryption.h -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4CommonEncryption.h
Changed
@@ -2,7 +2,7 @@ | | AP4 - Common Encryption support | -| Copyright 2002-2011 Axiomatic Systems, LLC +| Copyright 2002-2017 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). @@ -98,7 +98,8 @@ protected: // constructors AP4_CencTrackEncryption(AP4_UI08 version); - AP4_CencTrackEncryption(AP4_UI08 default_is_protected, + AP4_CencTrackEncryption(AP4_UI08 version, + AP4_UI08 default_is_protected, AP4_UI08 default_per_sample_iv_size, const AP4_UI08* default_kid, AP4_UI08 default_constant_iv_size = 0, @@ -108,7 +109,7 @@ private: // members - AP4_UI08 m_FormatVersion; // cannot be called m_Version because it would conflict with AP4_Atom::m_Version + AP4_UI08 m_Version_; // cannot be called m_Version because it would conflict with AP4_Atom::m_Version AP4_UI08 m_DefaultIsProtected; AP4_UI08 m_DefaultPerSampleIvSize; AP4_UI08 m_DefaultConstantIvSize; @@ -145,7 +146,8 @@ AP4_Cardinal GetSampleInfoCount() { return m_SampleInfoCount; } AP4_Result AddSampleInfo(const AP4_UI08* iv, AP4_DataBuffer& subsample_info); AP4_Result SetSampleInfosSize(AP4_Size size); - AP4_Result CreateSampleInfoTable(AP4_UI08 default_crypt_byte_block, + AP4_Result CreateSampleInfoTable(AP4_UI08 flags, + AP4_UI08 default_crypt_byte_block, AP4_UI08 default_skip_byte_block, AP4_UI08 default_per_sample_iv_size, AP4_UI08 default_constant_iv_size, @@ -190,6 +192,7 @@ static AP4_Result Create(AP4_ProtectedSampleDescription* sample_description, AP4_ContainerAtom* traf, AP4_UI32& cipher_type, + bool& reset_iv_at_each_subsample, AP4_ByteStream& aux_info_data, AP4_Position aux_info_data_offset, AP4_CencSampleInfoTable*& sample_info_table); @@ -200,11 +203,13 @@ AP4_SaizAtom*& saiz, AP4_CencSampleEncryption*& sample_encryption_atom, AP4_UI32& cipher_type, + bool& reset_iv_at_each_subsample, AP4_ByteStream& aux_info_data, AP4_Position aux_info_data_offset, AP4_CencSampleInfoTable*& sample_info_table); - static AP4_Result Create(AP4_UI08 crypt_byte_block, + static AP4_Result Create(AP4_UI08 flags, + AP4_UI08 crypt_byte_block, AP4_UI08 skip_byte_block, AP4_UI08 per_sample_iv_size, AP4_UI08 constant_iv_size, @@ -223,12 +228,14 @@ AP4_CencSampleInfoTable*& sample_info_table); // constructor - AP4_CencSampleInfoTable(AP4_UI08 crypt_byte_block, + AP4_CencSampleInfoTable(AP4_UI08 flags, + AP4_UI08 crypt_byte_block, AP4_UI08 skip_byte_block, AP4_UI32 sample_count, AP4_UI08 iv_size); // methods + AP4_UI08 GetFlags() { return m_Flags; } AP4_UI08 GetCryptByteBlock() { return m_CryptByteBlock; } AP4_UI08 GetSkipByteBlock() { return m_SkipByteBlock; } AP4_UI32 GetSampleCount() { return m_SampleCount; } @@ -261,9 +268,10 @@ AP4_Result Serialize(AP4_DataBuffer& buffer); private: + AP4_UI32 m_SampleCount; + AP4_UI08 m_Flags; AP4_UI08 m_CryptByteBlock; AP4_UI08 m_SkipByteBlock; - AP4_UI32 m_SampleCount; AP4_UI08 m_IvSize; AP4_DataBuffer m_IvData; AP4_Array<AP4_UI16> m_BytesOfCleartextData; @@ -284,7 +292,7 @@ | +---------------+----------------+------------------------------------+ | | 4 bytes | 32-bit integer | sample_count | | +---------------+----------------+------------------------------------+ -| | 1 byte | 8-bit integer | reserved (0) | +| | 1 byte | 8-bit integer | flags | | +---------------+----------------+------------------------------------+ | | 1 byte | 8-bit integer | crypt_byte_block | | +---------------+----------------+------------------------------------+ @@ -349,8 +357,11 @@ { public: // constructor and destructor - AP4_CencSampleEncrypter(AP4_StreamCipher* cipher) : m_Cipher(cipher) { - AP4_SetMemory(m_Iv, 0, 16); + AP4_CencSampleEncrypter(AP4_StreamCipher* cipher, + bool constant_iv) : + m_Cipher(cipher), + m_ConstantIv(constant_iv) { + AP4_SetMemory(m_Iv, 0, 16); }; virtual ~AP4_CencSampleEncrypter(); @@ -371,6 +382,7 @@ protected: AP4_UI08 m_Iv[16]; AP4_StreamCipher* m_Cipher; + bool m_ConstantIv; }; /*---------------------------------------------------------------------- @@ -380,8 +392,10 @@ { public: // constructor and destructor - AP4_CencCtrSampleEncrypter(AP4_StreamCipher* cipher, unsigned int iv_size) : - AP4_CencSampleEncrypter(cipher), + AP4_CencCtrSampleEncrypter(AP4_StreamCipher* cipher, + bool constant_iv, + unsigned int iv_size) : + AP4_CencSampleEncrypter(cipher, constant_iv), m_IvSize(iv_size) {} // methods @@ -400,8 +414,9 @@ { public: // constructor and destructor - AP4_CencCbcSampleEncrypter(AP4_StreamCipher* cipher) : - AP4_CencSampleEncrypter(cipher) {} + AP4_CencCbcSampleEncrypter(AP4_StreamCipher* cipher, + bool constant_iv) : + AP4_CencSampleEncrypter(cipher, constant_iv) {} // methods virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, @@ -410,45 +425,126 @@ }; /*---------------------------------------------------------------------- -| AP4_CencSubSampleEncrypter +| AP4_CencSubSampleMapper +---------------------------------------------------------------------*/ -class AP4_CencSubSampleEncrypter : public AP4_CencSampleEncrypter +class AP4_CencSubSampleMapper { public: // constructor and destructor - AP4_CencSubSampleEncrypter(AP4_StreamCipher* cipher, - AP4_Size nalu_length_size, - AP4_UI32 format) : - AP4_CencSampleEncrypter(cipher), + AP4_CencSubSampleMapper(AP4_Size nalu_length_size, AP4_UI32 format) : m_NaluLengthSize(nalu_length_size), m_Format(format) {} - + virtual ~AP4_CencSubSampleMapper() {} + // methods - virtual bool UseSubSamples() { return true; } - + virtual AP4_Result GetSubSampleMap(AP4_DataBuffer& sample_data, + AP4_Array<AP4_UI16>& bytes_of_cleartext_data, + AP4_Array<AP4_UI32>& bytes_of_encrypted_data) = 0; + +protected: // members AP4_Size m_NaluLengthSize; AP4_UI32 m_Format; }; /*---------------------------------------------------------------------- +| AP4_CencBasicSubSampleMapper ++---------------------------------------------------------------------*/ +class AP4_CencBasicSubSampleMapper : public AP4_CencSubSampleMapper +{ +public: + // constructor and destructor + AP4_CencBasicSubSampleMapper(AP4_Size nalu_length_size, AP4_UI32 format) : + AP4_CencSubSampleMapper(nalu_length_size, format) {} + + // methods + virtual AP4_Result GetSubSampleMap(AP4_DataBuffer& sample_data, + AP4_Array<AP4_UI16>& bytes_of_cleartext_data, + AP4_Array<AP4_UI32>& bytes_of_encrypted_data); +}; + +/*---------------------------------------------------------------------- +| AP4_CencAdvancedSubSampleMapper ++---------------------------------------------------------------------*/ +class AP4_CencAdvancedSubSampleMapper : public AP4_CencSubSampleMapper
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4ElstAtom.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4ElstAtom.cpp
Changed
@@ -80,7 +80,7 @@ stream.ReadUI32(media_time); stream.ReadUI16(media_rate); stream.ReadUI16(zero); - m_Entries.Append(AP4_ElstEntry(segment_duration, media_time, media_rate)); + m_Entries.Append(AP4_ElstEntry(segment_duration, (AP4_SI32)media_time, media_rate)); } else { AP4_UI64 segment_duration; AP4_UI64 media_time; @@ -88,7 +88,7 @@ stream.ReadUI64(media_time); stream.ReadUI16(media_rate); stream.ReadUI16(zero); - m_Entries.Append(AP4_ElstEntry(segment_duration, media_time, media_rate)); + m_Entries.Append(AP4_ElstEntry(segment_duration, (AP4_SI64)media_time, media_rate)); } } }
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4FragmentSampleTable.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4FragmentSampleTable.cpp
Changed
@@ -47,7 +47,8 @@ AP4_ByteStream* sample_stream, AP4_Position moof_offset, AP4_Position mdat_payload_offset, - AP4_UI64 dts_origin) + AP4_UI64 dts_origin) : + m_Duration(0) { AP4_TfhdAtom* tfhd = AP4_DYNAMIC_CAST(AP4_TfhdAtom, traf->GetChild(AP4_ATOM_TYPE_TFHD)); if (tfhd == NULL) return;
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4Piff.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4Piff.cpp
Changed
@@ -88,7 +88,8 @@ AP4_UI08 default_iv_size, const AP4_UI08* default_kid) : AP4_UuidAtom(AP4_FULL_UUID_ATOM_HEADER_SIZE+20, AP4_UUID_PIFF_TRACK_ENCRYPTION_ATOM, 0, 0), - AP4_CencTrackEncryption(default_algorithm_id, + AP4_CencTrackEncryption(0, + default_algorithm_id, default_iv_size, default_kid) {
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4SampleTable.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4SampleTable.cpp
Changed
@@ -58,14 +58,14 @@ // create the stsd atom AP4_StsdAtom* stsd = new AP4_StsdAtom(this); - // create the stsz atom - AP4_StszAtom* stsz = new AP4_StszAtom(); + // create the stts atom + AP4_SttsAtom* stts = new AP4_SttsAtom(); // create the stsc atom AP4_StscAtom* stsc = new AP4_StscAtom(); - // create the stts atom - AP4_SttsAtom* stts = new AP4_SttsAtom(); + // create the stsz atom + AP4_StszAtom* stsz = new AP4_StszAtom(); // create the stss atom AP4_StssAtom* stss = new AP4_StssAtom(); @@ -180,10 +180,10 @@ // attach the children of stbl stbl->AddChild(stsd); - stbl->AddChild(stsz); - stbl->AddChild(stsc); stbl->AddChild(stts); if (ctts) stbl->AddChild(ctts); + stbl->AddChild(stsc); + stbl->AddChild(stsz); if (!all_samples_are_sync && stss->GetEntries().ItemCount() != 0) { stbl->AddChild(stss); } else {
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4SencAtom.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4SencAtom.cpp
Changed
@@ -85,6 +85,24 @@ } /*---------------------------------------------------------------------- +| AP4_SencAtom::AP4_SencAtom ++---------------------------------------------------------------------*/ +AP4_SencAtom::AP4_SencAtom(AP4_UI08 per_sample_iv_size, + AP4_UI08 constant_iv_size, + const AP4_UI08* constant_iv, + AP4_UI08 crypt_byte_block, + AP4_UI08 skip_byte_block): + AP4_Atom(AP4_ATOM_TYPE_SENC, AP4_FULL_ATOM_HEADER_SIZE+4, 0, 0), + AP4_CencSampleEncryption(*this, + per_sample_iv_size, + constant_iv_size, + constant_iv, + crypt_byte_block, + skip_byte_block) +{ +} + +/*---------------------------------------------------------------------- | AP4_SencAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4SencAtom.h -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4SencAtom.h
Changed
@@ -49,9 +49,14 @@ // constructors AP4_SencAtom(AP4_UI08 iv_size = 16); AP4_SencAtom(AP4_UI32 algorithm_id, - AP4_UI08 iv_size, + AP4_UI08 per_sample_iv_size, const AP4_UI08* kid); - + AP4_SencAtom(AP4_UI08 per_sample_iv_size, + AP4_UI08 constant_iv_size, + const AP4_UI08* constant_iv, + AP4_UI08 crypt_byte_block, + AP4_UI08 skip_byte_block); + // methods virtual AP4_Result InspectFields(AP4_AtomInspector& inspector); virtual AP4_Result WriteFields(AP4_ByteStream& stream);
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4TencAtom.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4TencAtom.cpp
Changed
@@ -65,7 +65,8 @@ AP4_UI08 default_per_sample_iv_size, const AP4_UI08* default_kid) : AP4_Atom(AP4_ATOM_TYPE_TENC, AP4_FULL_ATOM_HEADER_SIZE+20, 0, 0), - AP4_CencTrackEncryption(default_is_protected, + AP4_CencTrackEncryption(0, + default_is_protected, default_per_sample_iv_size, default_kid) { @@ -82,7 +83,8 @@ AP4_UI08 default_crypt_byte_block, AP4_UI08 default_skip_byte_block) : AP4_Atom(AP4_ATOM_TYPE_TENC, AP4_FULL_ATOM_HEADER_SIZE+20+(default_per_sample_iv_size?0:1+default_constant_iv_size), 1, 0), - AP4_CencTrackEncryption(default_is_protected, + AP4_CencTrackEncryption(1, + default_is_protected, default_per_sample_iv_size, default_kid, default_constant_iv_size,
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4TfhdAtom.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4TfhdAtom.cpp
Changed
@@ -124,6 +124,16 @@ } /*---------------------------------------------------------------------- +| AP4_TfhdAtom::UpdateFlags ++---------------------------------------------------------------------*/ +void +AP4_TfhdAtom::UpdateFlags(AP4_UI32 flags) +{ + m_Flags = flags; + m_Size32 = ComputeSize(flags); +} + +/*---------------------------------------------------------------------- | AP4_TfhdAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result
View file
bento4-1.5.0r614.tar.gz/Source/C++/Core/Ap4TfhdAtom.h -> bento4-1.5.0r615.tar.gz/Source/C++/Core/Ap4TfhdAtom.h
Changed
@@ -81,6 +81,8 @@ AP4_UI32 GetDefaultSampleFlags() { return m_DefaultSampleFlags; } void SetDefaultSampleFlags(AP4_UI32 flags) { m_DefaultSampleFlags = flags; } + void UpdateFlags(AP4_UI32 flags); + private: // methods AP4_TfhdAtom(AP4_UI32 size,
View file
bento4-1.5.0r614.tar.gz/Source/C++/Crypto/Ap4StreamCipher.cpp -> bento4-1.5.0r615.tar.gz/Source/C++/Crypto/Ap4StreamCipher.cpp
Changed
@@ -519,3 +519,129 @@ return DecryptBuffer(in, in_size, out, out_size, is_last_buffer); } } + +/*---------------------------------------------------------------------- +| AP4_PatternStreamCipher ++---------------------------------------------------------------------*/ +AP4_PatternStreamCipher::AP4_PatternStreamCipher(AP4_StreamCipher* cipher, + AP4_UI08 crypt_byte_block, + AP4_UI08 skip_byte_block) : + m_Cipher(cipher), + m_CryptByteBlock(crypt_byte_block), + m_SkipByteBlock(skip_byte_block), + m_StreamOffset(0) +{ +} + +/*---------------------------------------------------------------------- +| AP4_PatternStreamCipher::~AP4_PatternStreamCipher ++---------------------------------------------------------------------*/ +AP4_PatternStreamCipher::~AP4_PatternStreamCipher() +{ + delete m_Cipher; +} + +/*---------------------------------------------------------------------- +| AP4_PatternStreamCipher::SetStreamOffset ++---------------------------------------------------------------------*/ +AP4_Result +AP4_PatternStreamCipher::SetStreamOffset(AP4_UI64 /*offset*/, + AP4_Cardinal* /*preroll*/) +{ + return AP4_ERROR_NOT_SUPPORTED; +} + +/*---------------------------------------------------------------------- +| AP4_PatternStreamCipher ++---------------------------------------------------------------------*/ +AP4_Result +AP4_PatternStreamCipher::ProcessBuffer(const AP4_UI08* in, + AP4_Size in_size, + AP4_UI08* out, + AP4_Size* out_size, + bool /* is_last_buffer */) +{ + // set default return values + *out_size = 0; + + // check that the range is block-aligned (required by the spec for pattern encryption) + if (m_StreamOffset % 16) return AP4_ERROR_INVALID_FORMAT; + + // compute where we are in the pattern + unsigned int pattern_span = m_CryptByteBlock+m_SkipByteBlock; + unsigned int block_position = (unsigned int)(m_StreamOffset/16); + unsigned int pattern_position = block_position % pattern_span; + + // process the range + while (*out_size < in_size) { + unsigned int crypt_size = 0; + unsigned int skip_size = m_SkipByteBlock*16; + if (pattern_position < m_CryptByteBlock) { + // in the encrypted part + crypt_size = (m_CryptByteBlock-pattern_position)*16; + } else { + // in the skipped part + skip_size = pattern_span-pattern_position; + } + + // clip + AP4_Size remain = in_size-*out_size; + if (crypt_size > remain) { + crypt_size = 16*(remain/16); + skip_size = remain-crypt_size; + } + if (crypt_size+skip_size > remain) { + skip_size = remain-crypt_size; + } + + // encrypted part + if (crypt_size) { + AP4_Size in_chunk_size = crypt_size; + AP4_Size out_chunk_size = crypt_size; + + AP4_Result result = m_Cipher->ProcessBuffer(in, in_chunk_size, out, &out_chunk_size); + if (AP4_FAILED(result)) return result; + // check that we got back what we expectected + if (out_chunk_size != in_chunk_size) { + return AP4_ERROR_INTERNAL; + } + in += crypt_size; + out += crypt_size; + *out_size += crypt_size; + m_StreamOffset += crypt_size; + } + + // skipped part + if (skip_size) { + AP4_CopyMemory(out, in, skip_size); + in += skip_size; + out += skip_size; + *out_size += skip_size; + m_StreamOffset += skip_size; + } + + // we're now at the start of a new pattern + pattern_position = 0; + } + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- +| AP4_PatternStreamCipher ++---------------------------------------------------------------------*/ +AP4_Result +AP4_PatternStreamCipher::SetIV(const AP4_UI08* iv) +{ + m_StreamOffset = 0; + return m_Cipher->SetIV(iv); +} + +/*---------------------------------------------------------------------- +| AP4_PatternStreamCipher ++---------------------------------------------------------------------*/ +const AP4_UI08* +AP4_PatternStreamCipher::GetIV() +{ + return m_Cipher->GetIV(); +}
View file
bento4-1.5.0r614.tar.gz/Source/C++/Crypto/Ap4StreamCipher.h -> bento4-1.5.0r615.tar.gz/Source/C++/Crypto/Ap4StreamCipher.h
Changed
@@ -165,4 +165,39 @@ bool is_last_buffer); }; +/*---------------------------------------------------------------------- +| AP4_PatternStreamCipher ++---------------------------------------------------------------------*/ +class AP4_PatternStreamCipher : public AP4_StreamCipher +{ +public: + // methods + + /** + * The stream cipher is passed with transfer of ownership (it will + * be destroyed when this object is destroyed). + */ + AP4_PatternStreamCipher(AP4_StreamCipher* cipher, AP4_UI08 crypt_byte_block, AP4_UI08 skip_byte_block); + ~AP4_PatternStreamCipher(); + + // AP4_StreamCipher implementation + virtual AP4_Result SetStreamOffset(AP4_UI64 offset, + AP4_Cardinal* preroll); + virtual AP4_UI64 GetStreamOffset() { return m_StreamOffset; } + virtual AP4_Result ProcessBuffer(const AP4_UI08* in, + AP4_Size in_size, + AP4_UI08* out, + AP4_Size* out_size, + bool is_last_buffer = false); + virtual AP4_Result SetIV(const AP4_UI08* iv); + virtual const AP4_UI08* GetIV(); + +private: + // members + AP4_StreamCipher* m_Cipher; + AP4_UI08 m_CryptByteBlock; + AP4_UI08 m_SkipByteBlock; + AP4_UI64 m_StreamOffset; +}; + #endif // _AP4_STREAM_CIPHER_H_
View file
bento4-1.5.0r614.tar.gz/Source/Python/utils/mp4-dash.py -> bento4-1.5.0r615.tar.gz/Source/Python/utils/mp4-dash.py
Changed
@@ -22,12 +22,13 @@ import re import platform import sys +import math from mp4utils import * from subtitles import * # setup main options -VERSION = "1.7.0" -SDK_REVISION = '614' +VERSION = "1.8.0" +SDK_REVISION = '615' SCRIPT_PATH = path.abspath(path.dirname(__file__)) sys.path += [SCRIPT_PATH] @@ -106,6 +107,13 @@ TempFiles = [] +MpegCencSchemeMap = { + 'cenc': 'MPEG-CENC', + 'cbc1': 'MPEG-CBC1', + 'cens': 'MPEG-CENS', + 'cbcs': 'MPEG-CBCS' +} + ############################################# def AddSegmentList(options, container, subdir, track, use_byte_range=False): if subdir: @@ -206,7 +214,7 @@ kids = [] for track in tracks: kid = track.kid - if kid is None: + if kid is None and not options.no_media: PrintErrorAndExit('ERROR: no encryption info found in track '+str(track)) if kid not in kids: kids.append(kid) @@ -227,7 +235,7 @@ if options.eme_signaling in ['pssh-v0', 'pssh-v1']: container.append(xml.Comment(' EME Common Encryption ')) xml.register_namespace('cenc', CENC_2013_NAMESPACE) - cp = xml.SubElement(container, 'ContentProtection', schemeIdUri=EME_COMMON_ENCRYPTION_SCHEME_ID_URI, value='cenc') + cp = xml.SubElement(container, 'ContentProtection', schemeIdUri=EME_COMMON_ENCRYPTION_SCHEME_ID_URI, value=options.encryption_cenc_scheme) if options.eme_signaling == 'pssh-v1': pssh_box = MakePsshBoxV1(EME_COMMON_ENCRYPTION_PSSH_SYSTEM_ID.decode('hex'), [default_kid], '') else: @@ -239,7 +247,7 @@ # MPEG Common Encryption container.append(xml.Comment(' MPEG Common Encryption ')) xml.register_namespace('cenc', CENC_2013_NAMESPACE) - cp = xml.SubElement(container, 'ContentProtection', schemeIdUri=MPEG_COMMON_ENCRYPTION_SCHEME_ID_URI, value='cenc') + cp = xml.SubElement(container, 'ContentProtection', schemeIdUri=MPEG_COMMON_ENCRYPTION_SCHEME_ID_URI, value=options.encryption_cenc_scheme) default_kid_with_dashes = (default_kid[0:8]+'-'+default_kid[8:12]+'-'+default_kid[12:16]+'-'+default_kid[16:20]+'-'+default_kid[20:32]).lower() cp.set('{'+CENC_2013_NAMESPACE+'}default_KID', default_kid_with_dashes) @@ -564,7 +572,7 @@ ############################################# def OutputHlsTrack(options, track, media_subdir, media_playlist_name, media_file_name): - hls_target_duration = 10 + hls_target_duration = math.ceil(max(track.segment_durations)) media_playlist_file = open(path.join(options.output_dir, media_subdir, media_playlist_name), 'w+') media_playlist_file.write('#EXTM3U\r\n') @@ -582,6 +590,10 @@ media_playlist_file.write('#EXT-X-MAP:URI="%s"\r\n' % (SPLIT_INIT_SEGMENT_NAME)) segment_pattern = SEGMENT_PATTERN.replace('ll','') + if options.encryption_key: + key_info = options.track_key_infos.get(track.id) + media_playlist_file.write('#EXT-X-KEY:METHOD=SAMPLE-AES,URI="'+options.hls_key_url+'",IV=0x'+key_info['iv']+'\r\n') + for i in range(len(track.segment_durations)): media_playlist_file.write('#EXTINF:%f,\r\n' % (track.segment_durations[i])) if options.on_demand: @@ -618,8 +630,25 @@ language_name = LanguageNames.get(language, language).decode('utf-8') audio_group_name = adaptation_set_name[0]+'/'+adaptation_set_name[2] - audio_groups[audio_group_name] = adaptation_set_name[2] + audio_groups[audio_group_name] = { + 'codec': '', + 'average_segment_bitrate': 0, + 'max_segment_bitrate': 0 + } for audio_track in audio_tracks: + # update the avergage and max bitrates + if audio_track.average_segment_bitrate > audio_groups[audio_group_name]['average_segment_bitrate']: + audio_groups[audio_group_name]['average_segment_bitrate'] = audio_track.average_segment_bitrate + if audio_track.max_segment_bitrate > audio_groups[audio_group_name]['max_segment_bitrate']: + audio_groups[audio_group_name]['max_segment_bitrate'] = audio_track.max_segment_bitrate + + # update/check the codec + if audio_groups[audio_group_name]['codec'] == '': + audio_groups[audio_group_name]['codec'] = audio_track.codec + else: + if audio_groups[audio_group_name]['codec'] != audio_track.codec: + print 'WARNING: audio codecs not all the same:', audio_groups[audio_group_name]['codec'], audio_track.codec + if options.on_demand: media_subdir = '' media_file_name = audio_track.parent.media_name @@ -662,16 +691,28 @@ raise Exception('mode not yet supported with HLS') - for audio_group_name in audio_groups: - audio_codec = audio_groups[audio_group_name] - master_playlist_file.write('#EXT-X-STREAM-INF:AUDIO="%s",AVERAGE-BANDWIDTH=%d,BANDWIDTH=%d,CODECS="%s",RESOLUTION=%dx%d\r\n' % ( - audio_group_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' % ( + 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)) + 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' % ( video_track.average_segment_bitrate, video_track.max_segment_bitrate, - video_track.codec+','+audio_codec, + video_track.codec, video_track.width, video_track.height)) master_playlist_file.write(media_playlist_path+'\r\n') + OutputHlsTrack(options, video_track, media_subdir, media_playlist_name, media_file_name) ############################################# @@ -1056,6 +1097,15 @@ key_info['key'] = key_hex key_info['kid'] = kid_hex + if options.hls: + # for HLS, we need to know the IV + import random + sys_random = random.SystemRandom() + random_iv = sys_random.getrandbits(128) + key_info['iv'] = '%016x' % random_iv + else: + key_info['iv'] = 'random' + options.key_infos.append(key_info) ############################################# @@ -1141,6 +1191,8 @@ help="Smooth Streaming FourCC value for H.264 video (default=H264) [some older players use AVC1]", metavar="<fourcc>", default='H264') parser.add_option('', '--hls', dest="hls", default=False, action="store_true", help="Output HLS playlists in addition to MPEG DASH") + parser.add_option('', '--hls-key-url', dest="hls_key_url", + help="HLS key URL (default: key.bin)", metavar="<url>", default='key.bin') parser.add_option('', '--hls-master-playlist-name', dest="hls_master_playlist_name", help="HLS master playlist name (default: master.m3u8)", metavar="<filename>", default='master.m3u8') parser.add_option('', '--hls-media-playlist-name', dest="hls_media_playlist_name", @@ -1157,6 +1209,8 @@ help="Encrypt some or all tracks with MPEG CENC (AES-128), where <key-spec> specifies the KID(s) and Key(s) to use, using one of the following forms: " + "(1) <KID>:<key> with <KID> as a 32-character hex string and <key> either a 32-character hex string or the character '#' followed by a base64-encoded key seed; or " + "(2) @<key-locator> where <key-locator> is an expression of one of the supported key locator schemes. Each entry may be prefixed with an optional track filter, and multiple <key-spec> entries can be used, separated by ','. (see online docs for details)") + parser.add_option('', "--encryption-cenc-scheme", dest="encryption_cenc_scheme", metavar='<cenc-scheme>', default='cenc', choices=('cenc', 'cbc1', 'cens', 'cbcs'), + help="MPEG Common Encryption scheme (cenc, cbc1, cens or cbcs). (default: cenc)") parser.add_option('', "--encryption-args", dest="encryption_args", metavar='<cmdline-arguments>', default=None, help="Pass additional command line arguments to mp4encrypt (separated by spaces)") parser.add_option('', "--eme-signaling", dest="eme_signaling", metavar='<eme-signaling-type>', choices=['pssh-v0', 'pssh-v1'], @@ -1288,6 +1342,10 @@ if options.primetime_metadata: options.primetime = True + if options.hls: + if options.encryption_key and options.encryption_cenc_scheme != 'cbcs': + raise Exception('--hls requires --encryption-cenc-scheme=cbcs') + # compute the KID(s) and encryption key(s) if needed if options.encryption_key: ResolveEncryptionKeys(options) @@ -1351,7 +1409,7 @@ media_sources.append(media_source) # encrypt the input files if needed - if not options.no_media and options.encryption_key: + if options.encryption_key: encrypted_files = {} for media_source in media_sources: if media_source.format != 'mp4': continue @@ -1382,6 +1440,11 @@ if track['type'].lower() in key_info['filter']: options.track_key_infos[track['id']] = key_info + # skip now if we're only outputing the MPD + if options.no_media: + continue +
View file
bento4-1.5.0r614.tar.gz/Source/Python/utils/mp4-hls.py -> bento4-1.5.0r615.tar.gz/Source/Python/utils/mp4-hls.py
Changed
@@ -27,7 +27,7 @@ # setup main options VERSION = "1.1.0" -SDK_REVISION = '614' +SDK_REVISION = '615' SCRIPT_PATH = path.abspath(path.dirname(__file__)) sys.path += [SCRIPT_PATH]
View file
bento4-1.5.0r614.tar.gz/Test/Bento4CryptoTester.py -> bento4-1.5.0r615.tar.gz/Test/Bento4CryptoTester.py
Changed
@@ -119,16 +119,22 @@ BIN_ROOT=sys.argv[1] files = sys.argv[2:] +if len(sys.argv) >= 4: + methods = sys.argv[3].split(',') +else: + methods = None + counter = 0 for file in files: json_info = Mp4Info(file, format='json', fast=True) info = json.loads(json_info, strict=False) - if info['movie']['fragments']: - methods = METHODS_FOR_FRAGMENTED_MP4 - else: - methods = METHODS_FOR_LINEAR_MP4 + if methods is None: + if info['movie']['fragments']: + methods = METHODS_FOR_FRAGMENTED_MP4 + else: + methods = METHODS_FOR_LINEAR_MP4 for method in methods: for key in KEYS:
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
.