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 16
View file
bento4.changes
Changed
@@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Sun Jun 7 12:35:09 UTC 2020 - aloisio@gmx.com + +- Update to version 1.6.0-636 +- Refreshed bento4-shared_library.patch + +------------------------------------------------------------------- Mon May 18 08:00:12 UTC 2020 - aloisio@gmx.com - Update to version 1.6.0-634
View file
bento4.spec
Changed
@@ -16,10 +16,10 @@ # -%define _over 1.6.0-634 -%define _libver 1_6_0r634 +%define _over 1.6.0-636 +%define _libver 1_6_0r636 Name: bento4 -Version: 1.6.0r634 +Version: 1.6.0r636 Release: 0 Summary: C++ toolkit for all your MP4 and MPEG DASH media format needs License: GPL-2.0-or-later @@ -60,9 +60,7 @@ write most Quicktime files as well. %prep -%setup -q -n Bento4-%{_over} -%patch0 -p1 -%patch1 -p1 +%autosetup -p1 -n Bento4-%{_over} sed -e 's/__VERSION__/%{version}/g' -i CMakeLists.txt sed -e '6s/.*/AP4_BUILD_CONFIG = Release/' -i Build/Makefiles/Bootstrap.mak
View file
bento4-shared_library.patch
Changed
@@ -1,8 +1,8 @@ -Index: Bento4-1.5.1-628/CMakeLists.txt +Index: Bento4-1.6.0-636/CMakeLists.txt =================================================================== ---- Bento4-1.5.1-628.orig/CMakeLists.txt -+++ Bento4-1.5.1-628/CMakeLists.txt -@@ -27,13 +27,21 @@ file(GLOB AP4_SOURCES +--- Bento4-1.6.0-636.orig/CMakeLists.txt ++++ Bento4-1.6.0-636/CMakeLists.txt +@@ -42,6 +42,14 @@ file(GLOB AP4_SOURCES ${SOURCE_SYSTEM}/StdC/*.cpp ) @@ -14,18 +14,21 @@ + ${SOURCE_ROOT}Codecs/*.h +) + + # Platform specifics if(WIN32) set(AP4_SOURCES ${AP4_SOURCES} ${SOURCE_SYSTEM}/Win32/Ap4Win32Random.cpp) - else() - set(AP4_SOURCES ${AP4_SOURCES} ${SOURCE_SYSTEM}/Posix/Ap4PosixRandom.cpp) - endif() +@@ -57,8 +65,8 @@ set(AP4_INCLUDE_DIRS + ${SOURCE_METADATA} + ) -add_library(ap4 STATIC ${AP4_SOURCES}) +-target_include_directories(ap4 PUBLIC ${AP4_INCLUDE_DIRS}) +add_library(ap4-__VERSION__ SHARED ${AP4_SOURCES}) ++target_include_directories(ap4-__VERSION__ PUBLIC ${AP4_INCLUDE_DIRS}) - # Includes - include_directories( -@@ -47,6 +55,11 @@ include_directories( + # Use the statically linked C runtime library + if(MSVC) +@@ -72,12 +80,16 @@ if(BUILD_APPS) file(GLOB BENTO4_APPS RELATIVE ${SOURCE_ROOT}/Apps ${SOURCE_ROOT}/Apps/*) foreach(app ${BENTO4_APPS}) string(TOLOWER ${app} binary_name) @@ -34,7 +37,12 @@ - target_link_libraries(${binary_name} ap4) + target_link_libraries(${binary_name} ap4-__VERSION__) + INSTALL(TARGETS ${binary_name} DESTINATION bin) + + if(MSVC) + set_property(TARGET ${binary_name} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") + target_compile_definitions(${binary_name} PRIVATE -D_CONSOLE) + endif() endforeach() -+ +INSTALL (TARGETS ap4-__VERSION__ DESTINATION lib${LIB_SUFFIX}) +INSTALL(FILES ${SDK_INCLUDES} DESTINATION include/ap4) + endif(BUILD_APPS)
View file
bento4-1.6.0r634.tar.gz/.github/workflows/ci.yml -> bento4-1.6.0r636.tar.gz/.github/workflows/ci.yml
Changed
@@ -10,7 +10,7 @@ branches: [ master ] jobs: - build-linux-macos: + build: name: Bento4 Build ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: @@ -19,13 +19,19 @@ include: - os: ubuntu-latest CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release + CMAKE_OUTPUT_SUBDIR: x86_64-unknown-linux + PYTHON3_COMMAND: python3 - os: macos-latest CMAKE_OPTIONS: -G Xcode + CMAKE_OUTPUT_SUBDIR: universal-apple-macosx + PYTHON3_COMMAND: python3 - os: windows-latest CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release + CMAKE_OUTPUT_SUBDIR: x86_64-microsoft-win32 + PYTHON3_COMMAND: py steps: - # Checks-out the repository under $GITHUB_WORKSPACE, so that the jobs can access it + # Check out the repository under $GITHUB_WORKSPACE, so that the jobs can access it - uses: actions/checkout@v2 # CMake Build @@ -33,5 +39,19 @@ run: | mkdir cmakebuild cd cmakebuild - cmake ${{matrix.CMAKE_OPTIONS}} .. + mkdir ${{matrix.CMAKE_OUTPUT_SUBDIR}} + cd ${{matrix.CMAKE_OUTPUT_SUBDIR}} + cmake ${{matrix.CMAKE_OPTIONS}} ../.. cmake --build . --config Release + + # Create SDK + - name: Create SDK + if: github.event_name == 'push' + run: ${{matrix.PYTHON3_COMMAND}} Scripts/SdkPackager.py + + # Upload the SDK + - name: Upload SDK + if: github.event_name == 'push' + uses: actions/upload-artifact@v2 + with: + path: SDK/*.zip
View file
bento4-1.6.0r634.tar.gz/.gitignore -> bento4-1.6.0r636.tar.gz/.gitignore
Changed
@@ -53,3 +53,4 @@ .coverage coverage_html Test/Output +Build/Targets/x86_64-microsoft-win32-vs2019/.vs
View file
bento4-1.6.0r634.tar.gz/Build/Docker/Dockerfile -> bento4-1.6.0r636.tar.gz/Build/Docker/Dockerfile
Changed
@@ -1,7 +1,7 @@ FROM alpine:latest # Setup environment variables -ENV BENTO4_VERSION 1.5.1-629 +ENV BENTO4_VERSION 1.6.0-636 # Install Dependencies RUN apk update && apk add --no-cache ca-certificates bash python3 make cmake gcc g++ git
View file
bento4-1.6.0r634.tar.gz/CMakeLists.txt -> bento4-1.6.0r636.tar.gz/CMakeLists.txt
Changed
@@ -1,6 +1,12 @@ # cmake -DCMAKE_BUILD_TYPE=Debug .. # cmake -DCMAKE_BUILD_TYPE=Release .. -cmake_minimum_required(VERSION 2.8) +if(MSVC) + cmake_policy(SET CMP0091 NEW) + cmake_minimum_required(VERSION 3.15) +else() + cmake_minimum_required(VERSION 3.10) +endif() + project(bento4) # Variables @@ -20,6 +26,13 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-warn-absolute-paths") endif() +set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12) + +if(MSVC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GF /Gy /GR") +endif() + # AP4 Library file(GLOB AP4_SOURCES ${SOURCE_CODECS}/*.cpp @@ -29,26 +42,42 @@ ${SOURCE_SYSTEM}/StdC/*.cpp ) +# Platform specifics if(WIN32) set(AP4_SOURCES ${AP4_SOURCES} ${SOURCE_SYSTEM}/Win32/Ap4Win32Random.cpp) else() set(AP4_SOURCES ${AP4_SOURCES} ${SOURCE_SYSTEM}/Posix/Ap4PosixRandom.cpp) endif() -add_library(ap4 STATIC ${AP4_SOURCES}) - # Includes -include_directories( +set(AP4_INCLUDE_DIRS ${SOURCE_CORE} ${SOURCE_CODECS} ${SOURCE_CRYPTO} ${SOURCE_METADATA} ) +add_library(ap4 STATIC ${AP4_SOURCES}) +target_include_directories(ap4 PUBLIC ${AP4_INCLUDE_DIRS}) + +# Use the statically linked C runtime library +if(MSVC) + set_property(TARGET ap4 PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") + target_compile_definitions(ap4 PRIVATE -D_LIB) +endif() + # Apps +option(BUILD_APPS "Build example applications" ON) +if(BUILD_APPS) file(GLOB BENTO4_APPS RELATIVE ${SOURCE_ROOT}/Apps ${SOURCE_ROOT}/Apps/*) foreach(app ${BENTO4_APPS}) string(TOLOWER ${app} binary_name) add_executable(${binary_name} ${SOURCE_ROOT}/Apps/${app}/${app}.cpp) target_link_libraries(${binary_name} ap4) + + if(MSVC) + set_property(TARGET ${binary_name} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") + target_compile_definitions(${binary_name} PRIVATE -D_CONSOLE) + endif() endforeach() +endif(BUILD_APPS)
View file
bento4-1.6.0r634.tar.gz/Documents/MkDocs/mkdocs.yml -> bento4-1.6.0r636.tar.gz/Documents/MkDocs/mkdocs.yml
Changed
@@ -14,6 +14,10 @@ docs_dir: 'src' +# Repo info +repo_name: axiomatic-systems/Bento4 +repo_url: https://github.com/axiomatic-systems/Bento4 + # Extensions markdown_extensions: - admonition
View file
bento4-1.6.0r634.tar.gz/README.md -> bento4-1.6.0r636.tar.gz/README.md
Changed
@@ -138,3 +138,12 @@ For Release builds: ```make AP4_BUILD_CONFIG=Release``` + +Release Notes +------------- + +### 1.6.0-636 +Dolby Vision encryption now properly encrypts in a NAL-unit-aware mode + +### Previous releases +(no seaparate notes, please refer to commit logs) \ No newline at end of file
View file
bento4-1.6.0r634.tar.gz/Scripts/SdkPackager.py -> bento4-1.6.0r636.tar.gz/Scripts/SdkPackager.py
Changed
@@ -38,16 +38,20 @@ cmd = 'git status --porcelain -b' lines = os.popen(cmd).readlines() branch = '' + suffix = '' if not lines[0].startswith('## master'): print('WARNING: not on master branch') branch = '+' + lines[0][3:].strip() if len(lines) > 1: - print('ERROR: git status not empty') + print('WARNING: git status not empty') print(''.join(lines)) - return None + suffix = '*' cmd = 'git tag --contains HEAD' tags = os.popen(cmd).readlines() + if not tags: + # no tags, use the commit hash + return os.popen('git rev-parse --short HEAD').readlines()[0].strip() + suffix if len(tags) != 1: print('ERROR: expected exactly one tag for HEAD, found', len(tags), ':', tags) return None @@ -55,7 +59,7 @@ sep = version.find('-') if sep < 0: print('ERROR: unrecognized version string format:', version) - return version[sep+1:] + branch + return version[sep+1:] + branch + suffix ############################################################# # File Copy
View file
bento4-1.6.0r634.tar.gz/Scripts/SdkPrepForRelease.py -> bento4-1.6.0r636.tar.gz/Scripts/SdkPrepForRelease.py
Changed
@@ -40,17 +40,26 @@ filename = os.path.join(BENTO4_HOME, "Source", "Python", "utils", "mp4-dash.py") print("Patching", filename) file_lines = open(filename).readlines() -file_out = open(filename, "wb") +file_out = open(filename, "w") for line in file_lines: if line.startswith("SDK_REVISION = "): line = "SDK_REVISION = '"+SDK_REVISION+"'\n" - file_out.write(line.encode('ascii')) + file_out.write(line) filename = os.path.join(BENTO4_HOME, "Source", "Python", "utils", "mp4-hls.py") print("Patching", filename) file_lines = open(filename).readlines() -file_out = open(filename, "wb") +file_out = open(filename, "w") for line in file_lines: if line.startswith("SDK_REVISION = "): line = "SDK_REVISION = '"+SDK_REVISION+"'\n" - file_out.write(line.encode('ascii')) + file_out.write(line) + +filename = os.path.join(BENTO4_HOME, "Build", "Docker", "Dockerfile") +print("Patching", filename) +file_lines = open(filename).readlines() +file_out = open(filename, "w") +for line in file_lines: + if line.startswith("ENV BENTO4_VERSION 1.6.0-"): + line = "ENV BENTO4_VERSION 1.6.0-"+SDK_REVISION+"\n" + file_out.write(line)
View file
bento4-1.6.0r634.tar.gz/Source/C++/Apps/Mp4Mux/Mp4Mux.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Apps/Mp4Mux/Mp4Mux.cpp
Changed
@@ -99,6 +99,9 @@ " optional params:\n" " track: audio, video, or integer track ID (default=all tracks)\n" "\n" + "Common optional parameters for all types:\n" + " language: language code (3-character ISO 639-2 Alpha-3 code)\n" + "\n" "If no type is specified for an input, the type will be inferred from the file extension\n" "\n" "Options:\n" @@ -220,12 +223,36 @@ } /*---------------------------------------------------------------------- +| GetLanguageFromParameters ++---------------------------------------------------------------------*/ +static const char* +GetLanguageFromParameters(AP4_Array<Parameter>& parameters, const char* defaut_value) +{ + // check if we have a language parameter + for (unsigned int i=0; i<parameters.ItemCount(); i++) { + if (parameters[i].m_Name == "language") { + const char* language = parameters[i].m_Value.GetChars(); + + // the language must be a 3-character ISO 639-2 Alpha-3 code + if (strlen(language) != 3) { + fprintf(stderr, "ERROR: language codes must be 3-character ISO 639-2 Alpha-3 codes\n"); + return NULL; + } + + return language; + } + } + + return defaut_value; +} + +/*---------------------------------------------------------------------- | AddAacTrack +---------------------------------------------------------------------*/ static void AddAacTrack(AP4_Movie& movie, const char* input_name, - AP4_Array<Parameter>& /*parameters*/, + AP4_Array<Parameter>& parameters, SampleFileStorage& sample_storage) { AP4_ByteStream* input; @@ -235,6 +262,10 @@ return; } + // check if we have a language parameter + const char* language = GetLanguageFromParameters(parameters, "und"); + if (!language) return; + // create a sample table AP4_SyntheticSampleTable* sample_table = new AP4_SyntheticSampleTable(); @@ -332,7 +363,7 @@ sample_count*1024, // track duration sample_rate, // media time scale sample_count*1024, // media duration - "und", // language + language, // language 0, 0); // width, height // cleanup @@ -358,6 +389,10 @@ return; } + // check if we have a language parameter + const char* language = GetLanguageFromParameters(parameters, "und"); + if (!language) return; + // see if the frame rate is specified unsigned int video_frame_rate = AP4_MUX_DEFAULT_VIDEO_FRAME_RATE*1000; for (unsigned int i=0; i<parameters.ItemCount(); i++) { @@ -538,7 +573,7 @@ video_track_duration, // track duration video_frame_rate, // media time scale video_media_duration, // media duration - "und", // language + language, // language video_width<<16, // width video_height<<16 // height ); @@ -573,6 +608,10 @@ return; } + // check if we have a language parameter + const char* language = GetLanguageFromParameters(parameters, "und"); + if (!language) return; + // see if the frame rate is specified unsigned int video_frame_rate = AP4_MUX_DEFAULT_VIDEO_FRAME_RATE*1000; for (unsigned int i=0; i<parameters.ItemCount(); i++) { @@ -796,7 +835,7 @@ video_track_duration, // track duration video_frame_rate, // media time scale video_media_duration, // media duration - "und", // language + language, // language video_width<<16, // width video_height<<16 // height ); @@ -835,7 +874,10 @@ if (input_movie == NULL) { return; } - + + // check if we have a language parameter + const char* language = GetLanguageFromParameters(parameters, NULL); + // check the parameters to decide which track(s) to import unsigned int track_id = 0; for (unsigned int i=0; i<parameters.ItemCount(); i++) { @@ -879,8 +921,15 @@ AP4_Track* track = track_item->GetData(); if (track_id == 0 || track->GetId() == track_id) { track = track->Clone(); + // reset the track ID so that it can be re-assigned track->SetId(0); + + // override the language if specified in the parameters + if (language) { + track->SetTrackLanguage(language); + } + movie.AddTrack(track); } track_item = track_item->GetNext();
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4Atom.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4Atom.cpp
Changed
@@ -1,6 +1,6 @@ /***************************************************************** | -| AP4 - Atoms +| AP4 - Atoms | | Copyright 2002-2008 Axiomatic Systems, LLC | @@ -57,7 +57,7 @@ AP4_Atom::TypeFromString(const char* s) { // convert the name into an atom type - return ((AP4_UI32)s[0])<<24 | + return ((AP4_UI32)s[0])<<24 | ((AP4_UI32)s[1])<<16 | ((AP4_UI32)s[2])<< 8 | ((AP4_UI32)s[3]); @@ -66,7 +66,7 @@ /*---------------------------------------------------------------------- | AP4_Atom::AP4_Atom +---------------------------------------------------------------------*/ -AP4_Atom::AP4_Atom(Type type, AP4_UI32 size /* = AP4_ATOM_HEADER_SIZE */) : +AP4_Atom::AP4_Atom(Type type, AP4_UI32 size /* = AP4_ATOM_HEADER_SIZE */) : m_Type(type), m_Size32(size), m_Size64(0), @@ -80,7 +80,7 @@ /*---------------------------------------------------------------------- | AP4_Atom::AP4_Atom +---------------------------------------------------------------------*/ -AP4_Atom::AP4_Atom(Type type, AP4_UI64 size, bool force_64) : +AP4_Atom::AP4_Atom(Type type, AP4_UI64 size, bool force_64) : m_Type(type), m_Size32(0), m_Size64(0), @@ -95,9 +95,9 @@ /*---------------------------------------------------------------------- | AP4_Atom::AP4_Atom +---------------------------------------------------------------------*/ -AP4_Atom::AP4_Atom(Type type, - AP4_UI32 size, - AP4_UI08 version, +AP4_Atom::AP4_Atom(Type type, + AP4_UI32 size, + AP4_UI08 version, AP4_UI32 flags) : m_Type(type), m_Size32(size), @@ -112,10 +112,10 @@ /*---------------------------------------------------------------------- | AP4_Atom::AP4_Atom +---------------------------------------------------------------------*/ -AP4_Atom::AP4_Atom(Type type, +AP4_Atom::AP4_Atom(Type type, AP4_UI64 size, bool force_64, - AP4_UI08 version, + AP4_UI08 version, AP4_UI32 flags) : m_Type(type), m_Size32(0), @@ -132,8 +132,8 @@ | AP4_Atom::ReadFullHeader +---------------------------------------------------------------------*/ AP4_Result -AP4_Atom::ReadFullHeader(AP4_ByteStream& stream, - AP4_UI08& version, +AP4_Atom::ReadFullHeader(AP4_ByteStream& stream, + AP4_UI08& version, AP4_UI32& flags) { AP4_UI32 header; @@ -275,7 +275,7 @@ char name[5]; AP4_FormatFourCharsPrintable(name, m_Type); name[4] = '\0'; - inspector.StartAtom(name, + inspector.StartAtom(name, m_Version, m_Flags, GetHeaderSize(), @@ -288,7 +288,7 @@ | AP4_Atom::Detach +---------------------------------------------------------------------*/ AP4_Result -AP4_Atom::Detach() +AP4_Atom::Detach() { if (m_Parent) { return m_Parent->RemoveChild(this); @@ -304,25 +304,25 @@ AP4_Atom::Clone() { AP4_Atom* clone = NULL; - + // check the size (refuse to clone atoms that are too large) AP4_LargeSize size = GetSize(); if (size > AP4_ATOM_MAX_CLONE_SIZE) return NULL; // create a memory byte stream to which we can serialize AP4_MemoryByteStream* mbs = new AP4_MemoryByteStream((AP4_Size)GetSize()); - + // serialize to memory if (AP4_FAILED(Write(*mbs))) { mbs->Release(); return NULL; } - + // create the clone from the serialized form mbs->Seek(0); AP4_DefaultAtomFactory atom_factory; atom_factory.CreateAtomFromStream(*mbs, clone); - + // release the memory stream mbs->Release(); @@ -332,9 +332,9 @@ /*---------------------------------------------------------------------- | AP4_UnknownAtom::AP4_UnknownAtom +---------------------------------------------------------------------*/ -AP4_UnknownAtom::AP4_UnknownAtom(Type type, +AP4_UnknownAtom::AP4_UnknownAtom(Type type, AP4_UI64 size, - AP4_ByteStream& stream) : + AP4_ByteStream& stream) : AP4_Atom(type, size), m_SourceStream(&stream) { @@ -347,7 +347,7 @@ stream.Read(m_Payload.UseData(), payload_size); return; } - + // store source stream position stream.Tell(m_SourcePosition); @@ -372,7 +372,7 @@ /*---------------------------------------------------------------------- | AP4_UnknownAtom::AP4_UnknownAtom +---------------------------------------------------------------------*/ -AP4_UnknownAtom::AP4_UnknownAtom(Type type, +AP4_UnknownAtom::AP4_UnknownAtom(Type type, const AP4_UI08* payload, AP4_Size payload_size) : AP4_Atom(type, AP4_ATOM_HEADER_SIZE+payload_size, false), @@ -421,7 +421,7 @@ if (m_SourceStream == NULL) { return stream.Write(m_Payload.GetData(), m_Payload.GetDataSize()); } - + // remember the source position AP4_Position position; m_SourceStream->Tell(position); @@ -444,7 +444,7 @@ /*---------------------------------------------------------------------- | AP4_UnknownAtom::Clone +---------------------------------------------------------------------*/ -AP4_Atom* +AP4_Atom* AP4_UnknownAtom::Clone() { return new AP4_UnknownAtom(*this); @@ -463,16 +463,20 @@ /*---------------------------------------------------------------------- | AP4_NullTerminatedStringAtom::AP4_NullTerminatedStringAtom +---------------------------------------------------------------------*/ -AP4_NullTerminatedStringAtom::AP4_NullTerminatedStringAtom(AP4_Atom::Type type, - AP4_UI64 size, +AP4_NullTerminatedStringAtom::AP4_NullTerminatedStringAtom(AP4_Atom::Type type, + AP4_UI64 size, AP4_ByteStream& stream) : AP4_Atom(type, size) { - AP4_Size str_size = (AP4_Size)size-AP4_ATOM_HEADER_SIZE; - char* str = new char[str_size]; - stream.Read(str, str_size); - str[str_size-1] = '\0'; // force null-termination - m_Value = str; + AP4_Size str_size = (AP4_Size)size - AP4_ATOM_HEADER_SIZE; + + if (str_size) { + char* str = new char[str_size]; + stream.Read(str, str_size); + str[str_size - 1] = '\0'; // force null-termination + m_Value = str; + delete[] str; + } } /*---------------------------------------------------------------------- @@ -605,7 +609,7 @@ AP4_Result result = m_Children.Find(AP4_AtomFinder(type, index), atom); if (AP4_SUCCEEDED(result)) { return atom;
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4Atom.h -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4Atom.h
Changed
@@ -184,6 +184,9 @@ void AddField(const char* name, const unsigned char* bytes, AP4_Size size, FormatHint hint); private: + // methods + static AP4_String EscapeString(const char* string); + // members AP4_ByteStream* m_Stream; AP4_Cardinal m_Depth;
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4CommonEncryption.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4CommonEncryption.cpp
Changed
@@ -1455,8 +1455,12 @@ case AP4_ATOM_TYPE_AVC2: case AP4_ATOM_TYPE_AVC3: case AP4_ATOM_TYPE_AVC4: + case AP4_ATOM_TYPE_DVAV: + case AP4_ATOM_TYPE_DVA1: case AP4_ATOM_TYPE_HEV1: case AP4_ATOM_TYPE_HVC1: + case AP4_ATOM_TYPE_DVHE: + case AP4_ATOM_TYPE_DVH1: enc_format = AP4_ATOM_TYPE_ENCV; break; @@ -1629,13 +1633,17 @@ if (format == AP4_ATOM_TYPE_AVC1 || format == AP4_ATOM_TYPE_AVC2 || format == AP4_ATOM_TYPE_AVC3 || - format == AP4_ATOM_TYPE_AVC4) { + format == AP4_ATOM_TYPE_AVC4 || + format == AP4_ATOM_TYPE_DVAV || + format == AP4_ATOM_TYPE_DVA1) { AP4_AvccAtom* avcc = AP4_DYNAMIC_CAST(AP4_AvccAtom, entries[0]->GetChild(AP4_ATOM_TYPE_AVCC)); if (avcc) { nalu_length_size = avcc->GetNaluLengthSize(); } } else if (format == AP4_ATOM_TYPE_HEV1 || - format == AP4_ATOM_TYPE_HVC1) { + format == AP4_ATOM_TYPE_HVC1 || + format == AP4_ATOM_TYPE_DVHE || + format == AP4_ATOM_TYPE_DVH1) { AP4_HvccAtom* hvcc = AP4_DYNAMIC_CAST(AP4_HvccAtom, entries[0]->GetChild(AP4_ATOM_TYPE_HVCC)); if (hvcc) { nalu_length_size = hvcc->GetNaluLengthSize();
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4Config.h -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4Config.h
Changed
@@ -99,6 +99,11 @@ #define AP4_ftell ftell #endif +/* MinGW-w64 */ +#if defined(__MINGW32__) || defined (__MINGW64__) +#define AP4_CONFIG_HAVE_FOPEN_S +#endif + /* Symbian */ #if defined(__SYMBIAN32__) #undef APT_CONFIG_HAVE_NEW_H
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4CttsAtom.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4CttsAtom.cpp
Changed
@@ -74,8 +74,20 @@ m_LookupCache.sample = 0; m_LookupCache.entry_index = 0; + if (size < AP4_FULL_ATOM_HEADER_SIZE + 4) { + return; + } + + // read the number of entries AP4_UI32 entry_count; stream.ReadUI32(entry_count); + + // check that there's enough data + if (((size - AP4_FULL_ATOM_HEADER_SIZE - 4) / 8) < entry_count) { + return; + } + + // read the entries m_Entries.SetItemCount(entry_count); unsigned char* buffer = new unsigned char[entry_count*8]; AP4_Result result = stream.Read(buffer, entry_count*8);
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4FtypAtom.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4FtypAtom.cpp
Changed
@@ -46,7 +46,7 @@ m_MajorBrand(0), m_MinorVersion(0) { - if (size < 16) return; + if (size < AP4_ATOM_HEADER_SIZE + 8) return; stream.ReadUI32(m_MajorBrand); stream.ReadUI32(m_MinorVersion); size -= 16;
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4MdhdAtom.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4MdhdAtom.cpp
Changed
@@ -66,8 +66,11 @@ m_TimeScale(time_scale), m_Duration(duration) { - m_Language.Assign(language, 3); - + if (strlen(language) == 3) { + m_Language.Assign(language, 3); + } else { + m_Language = "und"; + } if (duration > 0xFFFFFFFF) { m_Version = 1; m_Size32 += 12; @@ -146,13 +149,18 @@ } // write the language - AP4_UI08 l0 = m_Language[0]-0x60; - AP4_UI08 l1 = m_Language[1]-0x60; - AP4_UI08 l2 = m_Language[2]-0x60; - result = stream.WriteUI08((l0<<2 | l1>>3)&0xFF); - if (AP4_FAILED(result)) return result; - result = stream.WriteUI08((l1<<5 | l2)&0xFF); - if (AP4_FAILED(result)) return result; + if (m_Language.GetLength() == 3) { + AP4_UI08 l0 = m_Language[0]-0x60; + AP4_UI08 l1 = m_Language[1]-0x60; + AP4_UI08 l2 = m_Language[2]-0x60; + result = stream.WriteUI08((l0<<2 | l1>>3)&0xFF); + if (AP4_FAILED(result)) return result; + result = stream.WriteUI08((l1<<5 | l2)&0xFF); + if (AP4_FAILED(result)) return result; + } else { + result = stream.WriteUI16(0); + if (AP4_FAILED(result)) return result; + } // pre-defined return stream.WriteUI16(0); @@ -168,6 +176,20 @@ } /*---------------------------------------------------------------------- +| AP4_MdhdAtom::SetLanguage ++---------------------------------------------------------------------*/ +AP4_Result +AP4_MdhdAtom::SetLanguage(const char* language) +{ + if (strlen(language) != 3) { + return AP4_ERROR_INVALID_PARAMETERS; + } + m_Language = language; + + return AP4_SUCCESS; +} + +/*---------------------------------------------------------------------- | AP4_MdhdAtom::InspectFields +---------------------------------------------------------------------*/ AP4_Result
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4MdhdAtom.h -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4MdhdAtom.h
Changed
@@ -67,6 +67,7 @@ AP4_UI32 GetTimeScale() { return m_TimeScale; } void SetTimeScale(AP4_UI32 timescale) { m_TimeScale = timescale; } const AP4_String& GetLanguage() { return m_Language; } + AP4_Result SetLanguage(const char* language); private: // methods
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4SaizAtom.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4SaizAtom.cpp
Changed
@@ -85,7 +85,7 @@ stream.ReadUI32(m_SampleCount); remains -= 5; if (m_DefaultSampleInfoSize == 0) { - // means that the sample info entries have different sizes + // means that the sample info entries have different sizes if (m_SampleCount > remains) m_SampleCount = remains; // sanity check AP4_Cardinal sample_count = m_SampleCount; m_Entries.SetItemCount(sample_count);
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4StszAtom.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4StszAtom.cpp
Changed
@@ -69,28 +69,32 @@ AP4_UI08 version, AP4_UI32 flags, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_STSZ, size, version, flags) + AP4_Atom(AP4_ATOM_TYPE_STSZ, size, version, flags), + m_SampleSize(0), + m_SampleCount(0) { + if (size < AP4_FULL_ATOM_HEADER_SIZE + 8) { + return; + } + stream.ReadUI32(m_SampleSize); - stream.ReadUI32(m_SampleCount); + AP4_UI32 sample_count; + stream.ReadUI32(sample_count); if (m_SampleSize == 0) { // means that the samples have different sizes // check for overflow - if (m_SampleCount > (size-8)/4) { - m_SampleCount = 0; + if (m_SampleCount > (size - AP4_FULL_ATOM_HEADER_SIZE - 8) / 4) { return; } // read the entries - AP4_Cardinal sample_count = m_SampleCount; - m_Entries.SetItemCount(sample_count); - unsigned char* buffer = new unsigned char[sample_count*4]; + unsigned char* buffer = new unsigned char[sample_count * 4]; AP4_Result result = stream.Read(buffer, sample_count*4); if (AP4_FAILED(result)) { delete[] buffer; - m_Entries.Clear(); - m_SampleCount = 0; return; } + m_SampleCount = sample_count; + m_Entries.SetItemCount((AP4_Cardinal)sample_count); for (unsigned int i=0; i<sample_count; i++) { m_Entries[i] = AP4_BytesToUInt32BE(&buffer[i*4]); }
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4Stz2Atom.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4Stz2Atom.cpp
Changed
@@ -72,29 +72,40 @@ AP4_UI08 version, AP4_UI32 flags, AP4_ByteStream& stream) : - AP4_Atom(AP4_ATOM_TYPE_STZ2, size, version, flags) + AP4_Atom(AP4_ATOM_TYPE_STZ2, size, version, flags), + m_FieldSize(0), + m_SampleCount(0) { + if (size < AP4_FULL_ATOM_HEADER_SIZE + 8) { + return; + } + AP4_UI08 reserved; stream.ReadUI08(reserved); stream.ReadUI08(reserved); stream.ReadUI08(reserved); - stream.ReadUI08(m_FieldSize); - stream.ReadUI32(m_SampleCount); - if (m_FieldSize != 4 && m_FieldSize != 8 && m_FieldSize != 16) { - // illegale field size + AP4_UI08 field_size; + stream.ReadUI08(field_size); + if (field_size != 4 && field_size != 8 && field_size != 16) { + // illegal field size return; } + AP4_UI32 sample_count; + stream.ReadUI32(sample_count); - AP4_Cardinal sample_count = m_SampleCount; - m_Entries.SetItemCount(sample_count); - unsigned int table_size = (sample_count*m_FieldSize+7)/8; - if ((table_size+8) > size) return; + m_FieldSize = field_size; + m_SampleCount = sample_count; + unsigned int table_size = (sample_count * field_size + 7) / 8; + if (table_size > size - AP4_FULL_ATOM_HEADER_SIZE - 8) { + return; + } unsigned char* buffer = new unsigned char[table_size]; AP4_Result result = stream.Read(buffer, table_size); if (AP4_FAILED(result)) { delete[] buffer; return; } + m_Entries.SetItemCount((AP4_Cardinal)sample_count); switch (m_FieldSize) { case 4: for (unsigned int i=0; i<sample_count; i++) {
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4Track.cpp -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4Track.cpp
Changed
@@ -556,3 +556,19 @@ } return NULL; } + +/*---------------------------------------------------------------------- +| AP4_Track::SetTrackLanguage ++---------------------------------------------------------------------*/ +AP4_Result +AP4_Track::SetTrackLanguage(const char* language) +{ + if (strlen(language) != 3) { + return AP4_ERROR_INVALID_PARAMETERS; + } + + if (AP4_MdhdAtom* mdhd = AP4_DYNAMIC_CAST(AP4_MdhdAtom, m_TrakAtom->FindChild("mdia/mdhd"))) { + return mdhd->SetLanguage(language); + } + return AP4_ERROR_INVALID_STATE; +}
View file
bento4-1.6.0r634.tar.gz/Source/C++/Core/Ap4Track.h -> bento4-1.6.0r636.tar.gz/Source/C++/Core/Ap4Track.h
Changed
@@ -133,6 +133,7 @@ AP4_UI64 GetMediaDuration() const; // in the timescale of the media const char* GetTrackName() const; const char* GetTrackLanguage() const; + AP4_Result SetTrackLanguage(const char* language); AP4_Result Attach(AP4_MoovAtom* moov); protected:
View file
bento4-1.6.0r634.tar.gz/Source/Python/utils/mp4-dash.py -> bento4-1.6.0r636.tar.gz/Source/Python/utils/mp4-dash.py
Changed
@@ -27,6 +27,7 @@ import json import math import operator +import struct from functools import reduce from subtitles import SubtitlesFile from mp4utils import MakePsshBox,\ @@ -57,7 +58,7 @@ # setup main options VERSION = "2.0.0" -SDK_REVISION = '634' +SDK_REVISION = '636' SCRIPT_PATH = path.abspath(path.dirname(__file__)) sys.path += [SCRIPT_PATH] @@ -115,6 +116,8 @@ CENC_2013_NAMESPACE = 'urn:mpeg:cenc:2013' +DASHIF_NAMESPACE = 'https://dashif.org/' + DASH_DEFAULT_ROLE_NAMESPACE = 'urn:mpeg:dash:role:2011' DASH_MEDIA_SEGMENT_URL_PATTERN_SMOOTH = "/QualityLevels($Bandwidth$)/Fragments(%s=$Time$)" @@ -294,11 +297,17 @@ if options.clearkey: container.append(xml.Comment(' Clear Key ')) xml.register_namespace('ckey', CLEARKEY_CKEY_NAMESPACE) + xml.register_namespace('dashif', DASHIF_NAMESPACE) cp = xml.SubElement(container, 'ContentProtection', schemeIdUri=CLEARKEY_SCHEME_ID_URI, value=CLEARKEY_CONTENT_PROTECTION_VALUE) if options.clearkey_license_uri: + # First entry with the legacy namespace ck_license = xml.SubElement(cp, '{'+CLEARKEY_CKEY_NAMESPACE+'}Laurl', Lic_type=CLEARKEY_LICENSE_TYPE) ck_license.text = options.clearkey_license_uri + # Second entry with the dashif namespace + ck_license = xml.SubElement(cp, '{'+DASHIF_NAMESPACE+'}laurl') + ck_license.text = options.clearkey_license_uri + # Marlin if options.marlin: container.append(xml.Comment(' Marlin ')) @@ -336,8 +345,7 @@ container.append(xml.Comment(' Widevine ')) cp = xml.SubElement(container, 'ContentProtection', schemeIdUri=WIDEVINE_SCHEME_ID_URI) if options.widevine_header: - pssh_payload = ComputeWidevineHeader(options.widevine_header, options.encryption_cenc_scheme, default_kid) - pssh_box = MakePsshBox(bytes.fromhex(WIDEVINE_PSSH_SYSTEM_ID), pssh_payload) + pssh_box = ComputeWidevinePssh(options.widevine_header, options.encryption_cenc_scheme, default_kid) pssh_b64 = Base64Encode(pssh_box) pssh = xml.SubElement(cp, '{' + CENC_2013_NAMESPACE + '}pssh') pssh.text = pssh_b64 @@ -494,6 +502,9 @@ language = audio_tracks[0].language if (language != 'und') or options.always_output_lang: kwargs['lang'] = language + label = audio_tracks[0].label + if label != '': + kwargs['label'] = label adaptation_set = xml.SubElement(*args, **kwargs) # see if we have descriptors @@ -638,8 +649,7 @@ def ComputeHlsWidevineKeyLine(options, track): # V2 key line kid = track.key_info['kid'] - widevine_header = ComputeWidevineHeader(options.widevine_header, options.encryption_cenc_scheme, kid) - pssh_box = MakePsshBox(bytes.fromhex(WIDEVINE_PSSH_SYSTEM_ID), widevine_header) + pssh_box = ComputeWidevinePssh(options.widevine_header, options.encryption_cenc_scheme, kid) key_line = 'URI="data:text/plain;base64,{}",KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYID=0x{},KEYFORMATVERSIONS="1"'.format( Base64Encode(pssh_box), kid @@ -827,7 +837,7 @@ audio_groups = {} for adaptation_set_name, audio_tracks in list(audio_sets.items()): language = audio_tracks[0].language - language_name = LanguageNames.get(language, language) + language_name = audio_tracks[0].language_name audio_group_name = adaptation_set_name[0]+'/'+adaptation_set_name[2] audio_groups[audio_group_name] = { @@ -861,10 +871,11 @@ media_playlist_name = options.hls_media_playlist_name media_playlist_path = media_subdir+'/'+media_playlist_name + group_name = audio_track.label if audio_track.label != '' else language_name master_playlist_file.write('#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="{}",LANGUAGE="{}",NAME="{}",AUTOSELECT=YES,DEFAULT={},URI="{}"\n'.format( audio_group_name, language, - language_name, + group_name, 'YES' if select_as_default else 'NO', media_playlist_path)) select_as_default = False @@ -949,7 +960,7 @@ # only accept IMSC1 tracks continue language = subtitles_track.language - language_name = LanguageNames.get(language, language) + language_name = subtitles_track.language_name if options.on_demand or not options.split: media_subdir = '' @@ -1004,7 +1015,11 @@ # process the audio tracks for audio_track in audio_tracks: - stream_name = "audio_"+audio_track.language + stream_name = audio_track.label + if stream_name == '': + stream_name = audio_track.language_name + if stream_name == '' or stream_name == 'Unknown': + stream_name = "audio_"+audio_track.language audio_url_pattern="QualityLevels({bitrate})/Fragments(%s={start time})" % (stream_name) stream_index = xml.SubElement(client_manifest, 'StreamIndex', @@ -1241,6 +1256,7 @@ audio_adaptation_sets = {} video_adaptation_sets = {} subtitles_adaptation_sets = {} + label_indexes = {} for media_source in media_sources: track_id = media_source.spec['track'] track_type = media_source.spec['type'] @@ -1285,21 +1301,43 @@ language = options.language_map[language] track.language = language + # track language name + track.language_name = media_source.spec.get('+language_name', LanguageNames.get(language, language)) + + # track representation id + custom_representation_id = media_source.spec.get('+representation_id') + if custom_representation_id: + track.representation_id = custom_representation_id + # video scan type if track.type == 'video': track.scan_type = media_source.spec.get('+scan_type', track.scan_type) + # label + track.label = media_source.spec.get('+label', '') + + # update label indexes (so that we can use numbers instead of strings for labels) + for track in tracks: + if track.label not in label_indexes: + label_indexes[track.label] = len(label_indexes) + 1 + # process audio tracks for track in [t for t in tracks if t.type == 'audio']: adaptation_set_name = ('audio', track.language, track.codec_family) + + # add the label index + adaptation_set_name += (str(label_indexes[track.label]),) + + # lookup the adaptation set and start a new one if no entry is found adaptation_set = audio_adaptation_sets.get(adaptation_set_name, []) - audio_adaptation_sets[adaptation_set_name] = adaptation_set - # only keep this track if there isn't already a track with the same codec at the same bitrate (within 10%) + # only keep this track if there isn't already a track with the same + # codec at the same bitrate (within 10%) with_same_bandwidth = [t for t in adaptation_set if abs(float(t.bandwidth-track.bandwidth)/float(t.bandwidth)) < 0.1] if with_same_bandwidth: continue + audio_adaptation_sets[adaptation_set_name] = adaptation_set adaptation_set.append(track) track.order_index = len(adaptation_set) @@ -1324,6 +1362,30 @@ adaptation_set.append(track) track.order_index = len(adaptation_set) + # Try to simplify the adaptation set names where there's unnecessary sub-classification + # NOTE: in this version, we only try to simplify based on the last element of the name + # and we only try to simplify audio adaptation sets, because they are the only ones with + # labels. This should be updated when/if we add support for labels on other types. + for adaptation_set in [audio_adaptation_sets]: + prefixed = {} + + # skip empty sets + if not adaptation_set: + continue + + for name in adaptation_set: + prefix = name[:-1] + entry = prefixed.get(name[:-1], [0, name]) + entry[0] += 1 + prefixed[prefix] = entry + + for prefix in prefixed: + [count, name] = prefixed[prefix] + if count == 1: + # there's only one entry with that prefix, we can simplify + adaptation_set[prefix] = adaptation_set[name] + del adaptation_set[name] +
View file
bento4-1.6.0r634.tar.gz/Source/Python/utils/mp4-hls.py -> bento4-1.6.0r636.tar.gz/Source/Python/utils/mp4-hls.py
Changed
@@ -31,7 +31,7 @@ # setup main options VERSION = "1.2.0" -SDK_REVISION = '634' +SDK_REVISION = '636' SCRIPT_PATH = path.abspath(path.dirname(__file__)) sys.path += [SCRIPT_PATH]
View file
bento4-1.6.0r634.tar.gz/Source/Python/utils/mp4utils.py -> bento4-1.6.0r636.tar.gz/Source/Python/utils/mp4utils.py
Changed
@@ -378,6 +378,7 @@ self.max_segment_bitrate = 0 self.bandwidth = 0 self.language = '' + self.language_name = '' self.order_index = 0 self.key_info = {} self.id = info['id'] @@ -430,6 +431,7 @@ self.channels = sample_desc['channels'] self.language = info['language'] + self.language_name = LanguageNames.get(LanguageCodeMap.get(self.language, 'und'), '') def update(self, options): # compute the total number of samples @@ -714,13 +716,15 @@ break return int(bandwidth) -def MakeNewDir(dir, exit_if_exists=False, severity=None): +def MakeNewDir(dir, exit_if_exists=False, severity=None, recursive=False): if path.exists(dir): if severity: sys.stderr.write(severity+': ') sys.stderr.write('directory "'+dir+'" already exists\n') if exit_if_exists: sys.exit(1) + elif recursive: + os.makedirs(dir) else: os.mkdir(dir) @@ -1185,36 +1189,30 @@ return buffer def ComputeWidevineHeader(header_spec, encryption_scheme, kid_hex): - # construct the base64 header - if header_spec.startswith('#'): - header_b64 = header_spec[1:] - header = Base64Decode(header_b64) - if not header: - raise Exception('invalid base64 encoding') - return header - else: - try: - pairs = header_spec.split('#') - fields = {} - for pair in pairs: - name, value = pair.split(':', 1) - fields[name] = value - except: - raise Exception('invalid syntax for argument') - - protobuf_fields = [(1, 1), (2, bytes.fromhex(kid_hex))] - if 'provider' in fields: - protobuf_fields.append((3, fields['provider'])) - if 'content_id' in fields: - protobuf_fields.append((4, bytes.fromhex(fields['content_id']))) - if 'policy' in fields: - protobuf_fields.append((6, fields['policy'])) - - if encryption_scheme != 'cenc': - four_cc = struct.unpack('>I', encryption_scheme.encode('ascii'))[0] - protobuf_fields.append((9, four_cc)) - - return WidevineMakeHeader(protobuf_fields) + try: + pairs = header_spec.split('#') + fields = {} + for pair in pairs: + name, value = pair.split(':', 1) + fields[name] = value + except: + raise Exception('invalid syntax for argument') + + protobuf_fields = [(2, bytes.fromhex(kid_hex))] + if 'provider' in fields: + protobuf_fields.append((3, fields['provider'])) + if 'content_id' in fields: + protobuf_fields.append((4, bytes.fromhex(fields['content_id']))) + if 'policy' in fields: + protobuf_fields.append((6, fields['policy'])) + + if encryption_scheme == 'cenc': + protobuf_fields.append((1, 1)) + + four_cc = struct.unpack('>I', encryption_scheme.encode('ascii'))[0] + protobuf_fields.append((9, four_cc)) + + return WidevineMakeHeader(protobuf_fields) ############################################# # Module Exports
View file
bento4-1.6.0r634.tar.gz/Source/Python/utils/wv-request.py -> bento4-1.6.0r636.tar.gz/Source/Python/utils/wv-request.py
Changed
@@ -5,6 +5,7 @@ import aes import hashlib import base64 +import struct from optparse import OptionParser WV_DEFAULT_SERVER_URL = 'https://license.uat.widevine.com/cenc/getcontentkey' @@ -41,6 +42,8 @@ help="List of track types, separated by ','") parser.add_option('-l', '--policy', dest="policy", default='', help="Policy") +parser.add_option('-s', '--protection-scheme', dest="protection_scheme", default='', + help="Protection Scheme ('cenc', 'cbc1', 'cens', 'cbcs'), defaults to 'cenc'") (options, args) = parser.parse_args() if not options.content_id: @@ -54,6 +57,9 @@ 'policy': options.policy } +if options.protection_scheme: + rq_payload['protection_scheme'] = struct.unpack('>I',options.protection_scheme.encode("ascii"))[0] + if options.track_types: rq_payload['tracks'] = [{'type': track_type} for track_type in options.track_types.split(',')] else:
View file
bento4-1.6.0r634.tar.gz/tasks/build.py -> bento4-1.6.0r636.tar.gz/tasks/build.py
Changed
@@ -19,7 +19,7 @@ shutil.rmtree(target_dir, ignore_errors=True) try: os.makedirs(target_dir) - except: + except FileExistsError: pass with ctx.cd(target_dir): generator = ''
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
.