├── .gitattributes ├── .gitignore ├── .ycm_extra_conf.py ├── AUTHORS ├── CMakeLists.txt ├── LICENSE ├── alpha_encoder ├── Makefile ├── README └── alpha_encoder.cc ├── shared ├── common.sh ├── indent.cc ├── indent.h ├── webm_chunk_writer.cc ├── webm_chunk_writer.h ├── webm_constants.h ├── webm_endian.cc ├── webm_endian.h ├── webm_file.cc ├── webm_file.h ├── webm_incremental_reader.cc ├── webm_incremental_reader.h ├── webm_live_muxer.cc ├── webm_live_muxer.h └── webm_tools_types.h ├── vpx_ios ├── IosPlayer │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Default-568h@2x.png │ ├── Info.plist │ ├── IosPlayer.xcodeproj │ │ └── project.pbxproj │ ├── IosPlayer.xcworkspace │ │ └── contents.xcworkspacedata │ ├── IosPlayerTests │ │ ├── Info.plist │ │ ├── IxoDASHChunkIndexerTests.m │ │ ├── IxoDASHManifestParserTests.m │ │ ├── IxoDASHManifestTestData.h │ │ ├── IxoDASHManifestTestData.m │ │ ├── IxoDataSourceTests.m │ │ ├── IxoMutableDASHManifest.h │ │ ├── IxoMutableDASHManifest.m │ │ ├── IxoPlayerTestCommon.h │ │ └── IxoPlayerTestCommon.m │ ├── IxoDASHChunkIndexer.h │ ├── IxoDASHChunkIndexer.mm │ ├── IxoDASHManifestParser.h │ ├── IxoDASHManifestParser.m │ ├── IxoDASHManifestParserConstants.h │ ├── IxoDASHManifestParserConstants.m │ ├── IxoDASHStartData.h │ ├── IxoDASHStartData.mm │ ├── IxoDataSource.h │ ├── IxoDataSource.m │ ├── IxoDownloadOperation.h │ ├── IxoDownloadOperation.m │ ├── IxoDownloadQueue.h │ ├── IxoDownloadQueue.m │ ├── IxoDownloadRecord.h │ ├── IxoDownloadRecord.m │ ├── Podfile │ ├── TextViewController.h │ ├── TextViewController.m │ ├── main.m │ └── testdata │ │ ├── download_webm_files.sh │ │ ├── manifest_vp8_vorbis.mpd │ │ ├── manifest_vp9_vorbis.mpd │ │ ├── manifest_vp9_vorbis_rep_codecs.mpd │ │ └── print_cluster_pos_array.sh ├── README.IxoPlayer ├── README.VPXExample ├── VPXExample │ ├── .gitignore │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ ├── Main_iPad.storyboard │ │ └── Main_iPhone.storyboard │ ├── GlkVideoViewController.h │ ├── GlkVideoViewController.mm │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── VPXExample-Info.plist │ ├── VPXExample-Prefix.pch │ ├── VPXExample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── VPXExample Debug.xcscheme │ │ │ └── VPXExample Release.xcscheme │ ├── VPXExampleTests │ │ ├── VPXExampleTests-Info.plist │ │ ├── VPXExampleTests.m │ │ └── en.lproj │ │ │ └── InfoPlist.strings │ ├── ViewController.h │ ├── ViewController.mm │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── ivf_frame_parser.h │ ├── ivf_frame_parser.mm │ ├── main.m │ ├── nv12_fragment_shader.glsl │ ├── nv12_vertex_shader.glsl │ ├── video_buffer_pool.h │ ├── video_buffer_pool.mm │ ├── vpx_example_common.h │ ├── vpx_frame_parser.h │ ├── vpx_player.h │ ├── vpx_player.mm │ ├── webm_frame_parser.h │ └── webm_frame_parser.mm ├── build │ └── download_file.sh └── testserver │ └── server.py ├── webm_crypt ├── AUTHORS ├── LICENSE ├── Makefile ├── PATENTS ├── Readme.txt ├── aes_ctr.h ├── environment.props ├── webm_crypt.cc ├── webm_crypt_2010.sln └── webm_crypt_2010.vcxproj └── webm_dash_manifest ├── Makefile ├── adaptation_set.cc ├── adaptation_set.h ├── dash_model.cc ├── dash_model.h ├── period.cc ├── period.h ├── representation.cc ├── representation.h ├── webm_dash_manifest.cc ├── webm_dash_manifest.sln └── webm_dash_manifest.vcproj /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sln -crlf 2 | *.vcproj -crlf 3 | *.vcxproj -crlf 4 | *.vsprops -crlf 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Microsoft Visual Studio files 2 | *.ncb 3 | *.opensdf 4 | *.sdf 5 | *.suo 6 | *.user 7 | Debug 8 | Release 9 | 10 | # Compiled Object files 11 | *.o 12 | 13 | # OS X junk 14 | .DS_Store 15 | 16 | # Precompiled headers 17 | *.pch 18 | 19 | # Xcode junk 20 | project.xcworkspace/ 21 | xcuserdata/ 22 | 23 | # Other files 24 | *.swp 25 | *.webm 26 | -------------------------------------------------------------------------------- /.ycm_extra_conf.py: -------------------------------------------------------------------------------- 1 | import os 2 | import ycm_core 3 | 4 | # These are the compilation flags that will be used in case there's no 5 | # compilation database set (by default, one is not set). 6 | # CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. 7 | flags = [ 8 | '-Wall', 9 | '-Wextra', 10 | '-Werror', 11 | '-Wc++98-compat', 12 | '-Wno-long-long', 13 | '-Wno-variadic-macros', 14 | '-fexceptions', 15 | '-DNDEBUG', 16 | # THIS IS IMPORTANT! Without a "-std=" flag, clang won't know which 17 | # language to use when compiling headers. So it will guess. Badly. So C++ 18 | # headers will be compiled as C headers. You don't want that so ALWAYS specify 19 | # a "-std=". 20 | # For a C project, you would set this to something like 'c99' instead of 21 | # 'c++11'. 22 | '-std=c++11', 23 | # ...and the same thing goes for the magic -x option which specifies the 24 | # language that the files to be compiled are written in. This is mostly 25 | # relevant for c++ headers. 26 | # For a C project, you would set this to 'c' instead of 'c++'. 27 | '-x', 28 | 'c++', 29 | '-isystem', 30 | '../BoostParts', 31 | '-isystem', 32 | # This path will only work on OS X, but extra paths that don't exist are not 33 | # harmful 34 | '/System/Library/Frameworks/Python.framework/Headers', 35 | '-isystem', 36 | '../llvm/include', 37 | '-isystem', 38 | '../llvm/tools/clang/include', 39 | '-I', 40 | '.', 41 | '-I', 42 | './ClangCompleter', 43 | '-isystem', 44 | './tests/gmock/gtest', 45 | '-isystem', 46 | './tests/gmock/gtest/include', 47 | '-isystem', 48 | './tests/gmock', 49 | '-isystem', 50 | './tests/gmock/include', 51 | '-isystem', 52 | '/usr/include', 53 | '-isystem', 54 | '/usr/local/include', 55 | '-isystem', 56 | '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1', 57 | '-isystem', 58 | '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include', 59 | '-I', 60 | '../libwebm' 61 | ] 62 | 63 | 64 | # Set this to the absolute path to the folder (NOT the file!) containing the 65 | # compile_commands.json file to use that instead of 'flags'. See here for 66 | # more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html 67 | # 68 | # Most projects will NOT need to set this to anything; you can just change the 69 | # 'flags' list of compilation flags. Notice that YCM itself uses that approach. 70 | compilation_database_folder = '' 71 | 72 | if os.path.exists( compilation_database_folder ): 73 | database = ycm_core.CompilationDatabase( compilation_database_folder ) 74 | else: 75 | database = None 76 | 77 | SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] 78 | 79 | def DirectoryOfThisScript(): 80 | return os.path.dirname( os.path.abspath( __file__ ) ) 81 | 82 | 83 | def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): 84 | if not working_directory: 85 | return list( flags ) 86 | new_flags = [] 87 | make_next_absolute = False 88 | path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] 89 | for flag in flags: 90 | new_flag = flag 91 | 92 | if make_next_absolute: 93 | make_next_absolute = False 94 | if not flag.startswith( '/' ): 95 | new_flag = os.path.join( working_directory, flag ) 96 | 97 | for path_flag in path_flags: 98 | if flag == path_flag: 99 | make_next_absolute = True 100 | break 101 | 102 | if flag.startswith( path_flag ): 103 | path = flag[ len( path_flag ): ] 104 | new_flag = path_flag + os.path.join( working_directory, path ) 105 | break 106 | 107 | if new_flag: 108 | new_flags.append( new_flag ) 109 | return new_flags 110 | 111 | 112 | def IsHeaderFile( filename ): 113 | extension = os.path.splitext( filename )[ 1 ] 114 | return extension in [ '.h', '.hxx', '.hpp', '.hh' ] 115 | 116 | 117 | def GetCompilationInfoForFile( filename ): 118 | # The compilation_commands.json file generated by CMake does not have entries 119 | # for header files. So we do our best by asking the db for flags for a 120 | # corresponding source file, if any. If one exists, the flags for that file 121 | # should be good enough. 122 | if IsHeaderFile( filename ): 123 | basename = os.path.splitext( filename )[ 0 ] 124 | for extension in SOURCE_EXTENSIONS: 125 | replacement_file = basename + extension 126 | if os.path.exists( replacement_file ): 127 | compilation_info = database.GetCompilationInfoForFile( 128 | replacement_file ) 129 | if compilation_info.compiler_flags_: 130 | return compilation_info 131 | return None 132 | return database.GetCompilationInfoForFile( filename ) 133 | 134 | 135 | def FlagsForFile( filename, **kwargs ): 136 | if database: 137 | # Bear in mind that compilation_info.compiler_flags_ does NOT return a 138 | # python list, but a "list-like" StringVec object 139 | compilation_info = GetCompilationInfoForFile( filename ) 140 | if not compilation_info: 141 | return None 142 | 143 | final_flags = MakeRelativePathsInFlagsAbsolute( 144 | compilation_info.compiler_flags_, 145 | compilation_info.compiler_working_dir_ ) 146 | 147 | # NOTE: This is just for YouCompleteMe; it's highly likely that your project 148 | # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR 149 | # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. 150 | try: 151 | final_flags.remove( '-stdlib=libc++' ) 152 | except ValueError: 153 | pass 154 | else: 155 | relative_to = DirectoryOfThisScript() 156 | final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) 157 | 158 | return { 159 | 'flags': final_flags, 160 | 'do_cache': True 161 | } 162 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Frank Galligan 2 | James Zern 3 | Tom Finegan 4 | Vignesh Venkatasubramanian 5 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | ## 3 | ## Use of this source code is governed by a BSD-style license 4 | ## that can be found in the LICENSE file in the root of the source 5 | ## tree. An additional intellectual property rights grant can be found 6 | ## in the file PATENTS. All contributing project authors may 7 | ## be found in the AUTHORS file in the root of the source tree. 8 | cmake_minimum_required(VERSION 2.8) 9 | project(WEBMTOOLS) 10 | 11 | set(WEBMTOOLS_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 12 | # TODO(tomfinegan): The libwebm source directory must be configurable. 13 | set(LIBWEBM_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../libwebm") 14 | # This is where LIBWEBM targets are built. 15 | set(LIBWEBM_BUILD_DIR "${CMAKE_BINARY_DIR}/libwebm_build") 16 | 17 | # Libwebm section. 18 | # Add the libwebm CMakeLists.txt and set the binary dir to allow access to 19 | # libwebm build output. 20 | add_subdirectory("${LIBWEBM_SRC_DIR}" "${LIBWEBM_BUILD_DIR}") 21 | include_directories("${LIBWEBM_SRC_DIR}" 22 | "${WEBMTOOLS_SRC_DIR}/shared") 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, The WebM Project authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | * Neither the name of Google, nor the WebM Project, nor the names 16 | of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written 18 | permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | -------------------------------------------------------------------------------- /alpha_encoder/Makefile: -------------------------------------------------------------------------------- 1 | LIBWEBM := ../../libwebm 2 | OBJECTS := alpha_encoder.o 3 | EXE := alpha_encoder 4 | INCLUDES = -I$(LIBWEBM) 5 | DEBUG := -g 6 | CXXFLAGS = -W -Wall -O3 $(DEBUG) 7 | 8 | $(EXE): $(OBJECTS) 9 | $(CXX) $(OBJECTS) -L$(LIBWEBM) -lwebm -o $(EXE) 10 | 11 | %.o: %.cc 12 | $(CXX) -c $(CXXFLAGS) $(INCLUDES) $< -o $@ 13 | 14 | all: $(EXE) 15 | 16 | clean: 17 | $(RM) $(OBJECTS) $(EXE) Makefile.bak 18 | 19 | .PHONY: all clean 20 | -------------------------------------------------------------------------------- /alpha_encoder/README: -------------------------------------------------------------------------------- 1 | This is the VP8 Alpha Encoder which can produce VP8 videos with alpha channel 2 | from raw AYUV videos. 3 | 4 | To convert an avi/vp6a video with alpha into raw ayuv video, use: 5 | ffmpeg -i -f rawvideo -c:v rawvideo -an -pix_fmt yuva420p raw.out 6 | 7 | Make sure to note the width and height in the output. 8 | 9 | Then, you can encode the raw file with VP8 along with the alpha using: 10 | ./alpha_encoder -w -h -i raw.out -o vp8alpha.webm 11 | 12 | Various supported options can be found by running: 13 | ./alpha_encoder -? 14 | 15 | The design doc of how this works can be found here: http://goo.gl/wCP1y 16 | -------------------------------------------------------------------------------- /shared/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ## 3 | ## Copyright (c) 2015 The WebM project authors. All Rights Reserved. 4 | ## 5 | ## Use of this source code is governed by a BSD-style license 6 | ## that can be found in the LICENSE file in the root of the source 7 | ## tree. An additional intellectual property rights grant can be found 8 | ## in the file PATENTS. All contributing project authors may 9 | ## be found in the AUTHORS file in the root of the source tree. 10 | ## 11 | set -e 12 | devnull='> /dev/null 2>&1' 13 | 14 | readonly ORIG_PWD="$(pwd)" 15 | 16 | elog() { 17 | echo "${0##*/} failed because: $@" 1>&2 18 | } 19 | 20 | vlog() { 21 | if [ "${VERBOSE}" = "yes" ]; then 22 | echo "$@" 23 | fi 24 | } 25 | 26 | # Terminates script when name of current directory does not match $1. 27 | check_dir() { 28 | current_dir="$(pwd)" 29 | required_dir="$1" 30 | if [ "${current_dir##*/}" != "${required_dir}" ]; then 31 | elog "This script must be run from the ${required_dir} directory." 32 | exit 1 33 | fi 34 | } 35 | 36 | # Terminates the script when $1 is not in $PATH. Any arguments required for 37 | # the tool being tested to return a successful exit code can be passed as 38 | # additional arguments. 39 | check_tool() { 40 | tool="$1" 41 | shift 42 | tool_args="$@" 43 | if ! eval "${tool}" ${tool_args} > /dev/null 2>&1; then 44 | elog "${tool} must be in your path." 45 | exit 1 46 | fi 47 | } 48 | 49 | -------------------------------------------------------------------------------- /shared/indent.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "indent.h" 12 | 13 | #include 14 | 15 | namespace webm_tools { 16 | 17 | Indent::Indent(int indent) 18 | : indent_(indent), 19 | indent_str_() { 20 | Update(); 21 | } 22 | 23 | void Indent::Adjust(int indent) { 24 | indent_ += indent; 25 | if (indent_ < 0) 26 | indent_ = 0; 27 | 28 | Update(); 29 | } 30 | 31 | void Indent::Update() { 32 | indent_str_ = std::string(indent_, ' '); 33 | } 34 | 35 | } // namespace webm_tools 36 | -------------------------------------------------------------------------------- /shared/indent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef SHARED_INDENT_H_ 12 | #define SHARED_INDENT_H_ 13 | 14 | #include 15 | 16 | #include "webm_tools_types.h" 17 | 18 | namespace webm_tools { 19 | 20 | const int kIncreaseIndent = 2; 21 | const int kDecreaseIndent = -2; 22 | 23 | // Used for formatting output so objects only have to keep track of spacing 24 | // within their scope. 25 | class Indent { 26 | public: 27 | explicit Indent(int indent); 28 | 29 | // Changes the number of spaces output. The value adjusted is relative to 30 | // |indent_|. 31 | void Adjust(int indent); 32 | 33 | std::string indent_str() const { return indent_str_; } 34 | 35 | private: 36 | // Called after |indent_| is changed. This will set |indent_str_| to the 37 | // proper number of spaces. 38 | void Update(); 39 | 40 | int indent_; 41 | std::string indent_str_; 42 | 43 | WEBM_TOOLS_DISALLOW_COPY_AND_ASSIGN(Indent); 44 | }; 45 | 46 | } // namespace webm_tools 47 | 48 | #endif // SHARED_INDENT_H_ 49 | -------------------------------------------------------------------------------- /shared/webm_chunk_writer.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #include "webm_chunk_writer.h" 10 | 11 | #include 12 | #include 13 | 14 | #include "mkvmuxer.hpp" 15 | #include "webmids.hpp" 16 | 17 | namespace webm_tools { 18 | 19 | WebMChunkWriter::WebMChunkWriter() 20 | : bytes_buffered_(0), 21 | bytes_written_(0), 22 | chunk_end_(0), 23 | ptr_write_buffer_(NULL) { 24 | } 25 | 26 | WebMChunkWriter::~WebMChunkWriter() { 27 | } 28 | 29 | int32 WebMChunkWriter::Init(WriteBuffer* ptr_write_buffer) { 30 | if (!ptr_write_buffer) { 31 | fprintf(stderr, "Cannot Init, NULL write buffer.\n"); 32 | return kInvalidArg; 33 | } 34 | ptr_write_buffer_ = ptr_write_buffer; 35 | return kSuccess; 36 | } 37 | 38 | void WebMChunkWriter::EraseChunk() { 39 | if (ptr_write_buffer_) { 40 | WriteBuffer::iterator erase_end_pos = 41 | ptr_write_buffer_->begin() + static_cast(chunk_end_); 42 | ptr_write_buffer_->erase(ptr_write_buffer_->begin(), erase_end_pos); 43 | bytes_buffered_ = ptr_write_buffer_->size(); 44 | chunk_end_ = 0; 45 | } 46 | } 47 | 48 | int32 WebMChunkWriter::Write(const void* ptr_buffer, uint32 buffer_length) { 49 | if (!ptr_write_buffer_) { 50 | fprintf(stderr, "Cannot Write, not Initialized.\n"); 51 | return kNotInitialized; 52 | } 53 | if (!ptr_buffer || !buffer_length) { 54 | fprintf(stderr, "Error invalid arg passed to Write.\n"); 55 | return kInvalidArg; 56 | } 57 | const uint8* ptr_data = reinterpret_cast(ptr_buffer); 58 | ptr_write_buffer_->insert(ptr_write_buffer_->end(), 59 | ptr_data, 60 | ptr_data + buffer_length); 61 | bytes_written_ += buffer_length; 62 | bytes_buffered_ = ptr_write_buffer_->size(); 63 | return kSuccess; 64 | } 65 | 66 | void WebMChunkWriter::ElementStartNotify(uint64 element_id, int64 position) { 67 | if (element_id == mkvmuxer::kMkvCluster) { 68 | chunk_end_ = bytes_buffered_; 69 | fprintf(stdout, "chunk_end_=%lld position=%lld\n", chunk_end_, position); 70 | } 71 | } 72 | 73 | } // namespace webm_tools 74 | -------------------------------------------------------------------------------- /shared/webm_chunk_writer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #ifndef SHARED_WEBM_CHUNK_WRITER_H_ 10 | #define SHARED_WEBM_CHUNK_WRITER_H_ 11 | 12 | #include 13 | 14 | #include "mkvmuxer.hpp" 15 | #include "webm_tools_types.h" 16 | 17 | namespace webm_tools { 18 | 19 | // Buffer object implementing libwebm's IMkvWriter interface. Uses 20 | // |WriteBuffer| passed to |Init()| to store data written by libwebm. 21 | class WebMChunkWriter : public mkvmuxer::IMkvWriter { 22 | public: 23 | typedef std::vector WriteBuffer; 24 | 25 | enum { 26 | kNotImplemented = -200, 27 | kNotInitialized = -2, 28 | kInvalidArg = -1, 29 | kSuccess = 0, 30 | }; 31 | WebMChunkWriter(); 32 | virtual ~WebMChunkWriter(); 33 | 34 | // Stores |ptr_buffer| and returns |kSuccess|. 35 | int32 Init(WriteBuffer* ptr_write_buffer); 36 | 37 | // Accessors. 38 | int64 bytes_written() const { return bytes_written_; } 39 | int64 chunk_end() const { return chunk_end_; } 40 | 41 | // Erases chunk from |ptr_write_buffer_|, resets |chunk_end_| to 0, and 42 | // updates |bytes_buffered_|. 43 | void EraseChunk(); 44 | 45 | // mkvmuxer::IMkvWriter methods 46 | // Returns total bytes of data passed to |Write|. 47 | virtual int64 Position() const { return bytes_written_; } 48 | 49 | // Not seekable, return |kNotImplemented| on seek attempts. 50 | virtual int32 Position(int64 /* pos */) { return kNotImplemented; } 51 | 52 | // Always returns false: |WebMChunkWriter| is never seekable. Written data 53 | // goes into a vector, and data is buffered only until a chunk is completed. 54 | virtual bool Seekable() const { return false; } 55 | 56 | // Writes |ptr_buffer| contents to |ptr_write_buffer_|. 57 | virtual int32 Write(const void* ptr_buffer, uint32 buffer_length); 58 | 59 | // Called by libwebm, and notifies writer of element start position. 60 | virtual void ElementStartNotify(uint64 element_id, int64 position); 61 | 62 | private: 63 | int64 bytes_buffered_; 64 | int64 bytes_written_; 65 | int64 chunk_end_; 66 | WriteBuffer* ptr_write_buffer_; 67 | WEBM_TOOLS_DISALLOW_COPY_AND_ASSIGN(WebMChunkWriter); 68 | }; 69 | 70 | } // namespace webm_tools 71 | 72 | #endif // SHARED_WEBM_CHUNK_WRITER_H_ 73 | -------------------------------------------------------------------------------- /shared/webm_constants.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #ifndef SHARED_WEBM_CONSTANTS_H_ 10 | #define SHARED_WEBM_CONSTANTS_H_ 11 | 12 | namespace webm_tools { 13 | 14 | const double kNanosecondsPerSecond = 1000000000.0; 15 | const int kNanosecondsPerSecondi = 1000000000; 16 | const int kNanosecondsPerMillisecond = 1000000; 17 | 18 | } // namespace webm_tools 19 | 20 | #endif // SHARED_WEBM_CONSTANTS_H_ 21 | -------------------------------------------------------------------------------- /shared/webm_endian.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #include "webm_endian.h" 10 | 11 | namespace { 12 | 13 | // Swaps unsigned 64 bit values to big endian if needed. Returns |value| 14 | // unmodified if architecture is big endian. Returns swapped bytes of |value| 15 | // if architecture is little endian. Returns 0 otherwise. 16 | webm_tools::uint64 swap64_check_little_endian(webm_tools::uint64 value) { 17 | // Check endianness. 18 | union { 19 | webm_tools::uint64 val64; 20 | webm_tools::uint8 c[8]; 21 | } check; 22 | check.val64 = 0x0123456789ABCDEFULL; 23 | 24 | // Check for big endian. 25 | if (check.c[7] == 0xEF) 26 | return value; 27 | 28 | // Check for not little endian. 29 | if (check.c[0] != 0xEF) 30 | return 0; 31 | 32 | return value << 56 | 33 | ((value << 40) & 0x00FF000000000000ULL) | 34 | ((value << 24) & 0x0000FF0000000000ULL) | 35 | ((value << 8) & 0x000000FF00000000ULL) | 36 | ((value >> 8) & 0x00000000FF000000ULL) | 37 | ((value >> 24) & 0x0000000000FF0000ULL) | 38 | ((value >> 40) & 0x000000000000FF00ULL) | 39 | value >> 56; 40 | } 41 | 42 | } // namespace 43 | 44 | namespace webm_tools { 45 | 46 | uint64 host_to_bigendian(uint64 value) { 47 | return swap64_check_little_endian(value); 48 | } 49 | 50 | uint64 bigendian_to_host(uint64 value) { 51 | return swap64_check_little_endian(value); 52 | } 53 | 54 | } // namespace webm_tools 55 | -------------------------------------------------------------------------------- /shared/webm_endian.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #ifndef SHARED_WEBM_ENDIAN_H_ 10 | #define SHARED_WEBM_ENDIAN_H_ 11 | 12 | #include "webm_tools_types.h" 13 | 14 | namespace webm_tools { 15 | 16 | // Swaps unsigned 64 bit values to big endian if needed. Returns |value| if 17 | // architecture is big endian. Returns little endian value if architecture is 18 | // little endian. Returns 0 otherwise. 19 | uint64 host_to_bigendian(uint64 value); 20 | 21 | // Swaps unsigned 64 bit values to little endian if needed. Returns |value| if 22 | // architecture is big endian. Returns little endian value if architecture is 23 | // little endian. Returns 0 otherwise. 24 | uint64 bigendian_to_host(uint64 value); 25 | 26 | } // namespace webm_tools 27 | 28 | #endif // SHARED_WEBM_ENDIAN_H_ 29 | -------------------------------------------------------------------------------- /shared/webm_incremental_reader.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "webm_incremental_reader.h" 12 | 13 | #include 14 | #include 15 | 16 | #include "mkvparser/mkvparser.h" 17 | #include "mkvparser/mkvreader.h" 18 | 19 | namespace webm_tools { 20 | 21 | WebmIncrementalReader::WebmIncrementalReader() 22 | : ptr_buffer_(NULL), 23 | window_length_(0), 24 | bytes_consumed_(0), 25 | end_of_segment_position_(-1) { 26 | } 27 | 28 | WebmIncrementalReader::~WebmIncrementalReader() { 29 | } 30 | 31 | int WebmIncrementalReader::SetBufferWindow(const uint8* ptr_buffer, 32 | int32 length, 33 | int64 bytes_consumed) { 34 | if (!ptr_buffer || !length) { 35 | fprintf(stderr, "Invalid arg(s)\n"); 36 | return kInvalidArg; 37 | } 38 | ptr_buffer_ = ptr_buffer; 39 | window_length_ = length; 40 | bytes_consumed_ = bytes_consumed; 41 | return kSuccess; 42 | } 43 | 44 | bool WebmIncrementalReader::SetEndOfSegmentPosition(int64 position) { 45 | // Check if end position has already been set. 46 | if (end_of_segment_position_ != -1) { 47 | return (end_of_segment_position_ == position); 48 | } 49 | 50 | // Check if |position| is invalid. 51 | if (position <= 0) { 52 | return (position == -1); 53 | } 54 | end_of_segment_position_ = position; 55 | return true; 56 | } 57 | 58 | int WebmIncrementalReader::Read(int64 read_pos, 59 | long length_requested, // NOLINT 60 | uint8* ptr_buf) { 61 | if (!ptr_buf) { 62 | fprintf(stderr, "NULL ptr_buf\n"); 63 | return kInvalidArg; 64 | } 65 | 66 | // |read_pos| includes |bytes_consumed_|, which is not going to work with the 67 | // buffer window-- calculate actual offset within |ptr_buf|. 68 | const int64 window_pos = read_pos - bytes_consumed_; 69 | if (window_pos < 0) { 70 | fprintf(stderr, "Error bad window_pos:%lld read_pos:%lld\n", 71 | window_pos, read_pos); 72 | return kInvalidArg; 73 | } 74 | 75 | // Is enough data in the buffer? 76 | const int64 bytes_available = window_length_ - window_pos; 77 | if (bytes_available < length_requested) { 78 | // No, not enough data buffered. 79 | return kNeedMoreData; 80 | } 81 | 82 | // Yes, there's enough data in the buffer. 83 | memcpy(ptr_buf, ptr_buffer_ + window_pos, length_requested); 84 | return kSuccess; 85 | } 86 | 87 | // Called by libwebm to obtain length of readable data. Returns 88 | // |bytes_consumed_| + |length_| as available amount, which is the size of the 89 | // buffer current window plus the sum of the sizes of all parsed elements. 90 | int WebmIncrementalReader::Length(int64* ptr_total, int64* ptr_available) { 91 | if (!ptr_total || !ptr_available) { 92 | fprintf(stderr, "Invalid arg(s)\n"); 93 | return kInvalidArg; 94 | } 95 | *ptr_total = end_of_segment_position_; 96 | *ptr_available = bytes_consumed_ + window_length_; 97 | return kSuccess; 98 | } 99 | 100 | } // namespace webm_tools 101 | -------------------------------------------------------------------------------- /shared/webm_incremental_reader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef SHARED_WEBM_INCREMENTAL_READER_H_ 12 | #define SHARED_WEBM_INCREMENTAL_READER_H_ 13 | 14 | #include "mkvparser/mkvreader.h" 15 | 16 | #include "webm_tools_types.h" 17 | 18 | namespace webm_tools { 19 | 20 | // Provides a moving window into a buffer, and implements libwebm's IMkvReader 21 | // interface. |WebmBufferParser| sets the window into a buffer by calling 22 | // |SetBufferWindow|, and libwebm parses the data using the |Read| and |Length| 23 | // methods. 24 | class WebmIncrementalReader : public mkvparser::IMkvReader { 25 | public: 26 | enum { 27 | kInvalidArg = -1, 28 | kSuccess = 0, 29 | kNeedMoreData = 1, 30 | }; 31 | WebmIncrementalReader(); 32 | virtual ~WebmIncrementalReader(); 33 | 34 | // Updates the buffer window and returns |kSuccess|. 35 | int SetBufferWindow(const uint8* ptr_buffer, int32 length, 36 | int64 bytes_consumed); 37 | 38 | // Sets the end of the segment to |position|. |position| is the end of the 39 | // segment in bytes. The end position may only be set once. Returns true on 40 | // success. 41 | bool SetEndOfSegmentPosition(int64 position); 42 | 43 | // IMkvReader methods. 44 | virtual int Read(int64 read_pos, long length_requested, // NOLINT 45 | uint8* ptr_buf); 46 | virtual int Length(int64* ptr_total, int64* ptr_available); 47 | 48 | private: 49 | // Buffer window pointer. 50 | const uint8* ptr_buffer_; 51 | 52 | // Length of the buffer window to which |ptr_buffer_| provides access. 53 | int32 window_length_; 54 | 55 | // Sum of all parsed element lengths. 56 | int64 bytes_consumed_; 57 | 58 | // The end of the segment. -1 represents an unknown segment size. 59 | int64 end_of_segment_position_; 60 | 61 | WEBM_TOOLS_DISALLOW_COPY_AND_ASSIGN(WebmIncrementalReader); 62 | }; 63 | 64 | } // namespace webm_tools 65 | 66 | #endif // SHARED_WEBM_INCREMENTAL_READER_H_ 67 | -------------------------------------------------------------------------------- /shared/webm_tools_types.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #ifndef SHARED_WEBM_TOOLS_TYPES_H_ 10 | #define SHARED_WEBM_TOOLS_TYPES_H_ 11 | 12 | // Copied from Chromium basictypes.h 13 | // A macro to disallow the copy constructor and operator= functions 14 | // This should be used in the private: declarations for a class 15 | #define WEBM_TOOLS_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 16 | TypeName(const TypeName&); \ 17 | void operator=(const TypeName&) 18 | 19 | #if defined(_MSC_VER) 20 | #define snprintf sprintf_s 21 | #define strtoull _strtoui64 22 | #endif 23 | 24 | namespace webm_tools { 25 | 26 | typedef unsigned char uint8; 27 | typedef int int32; 28 | typedef unsigned int uint32; 29 | typedef long long int64; // NOLINT 30 | typedef unsigned long long uint64; // NOLINT 31 | 32 | } // namespace webm_tools 33 | 34 | #endif // SHARED_WEBM_TOOLS_TYPES_H_ 35 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | @interface AppDelegate : UIResponder 11 | 12 | @property(strong, nonatomic) UIWindow* window; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "AppDelegate.h" 9 | #import "TextViewController.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication*)application 18 | didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { 19 | // We're in training wheels mode! Just create a window. 20 | 21 | // Create the window. 22 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 23 | if (self.window == nil) 24 | return NO; 25 | 26 | self.window.backgroundColor = [UIColor blackColor]; 27 | [self.window makeKeyAndVisible]; 28 | 29 | // Create the text view. 30 | TextViewController* debug_console = [[TextViewController alloc] init]; 31 | if (debug_console == nil) 32 | return NO; 33 | 34 | // Make our text view the root controller. 35 | self.window.rootViewController = debug_console; 36 | 37 | // Show the window. 38 | [self.window makeKeyAndVisible]; 39 | 40 | return YES; 41 | } 42 | 43 | - (void)applicationWillResignActive:(UIApplication*)application { 44 | // Sent when the application is about to move from active to inactive state. 45 | // This can occur for certain types of temporary interruptions (such as an 46 | // incoming phone call or SMS message) or when the user quits the application 47 | // and it begins the transition to the background state. 48 | // Use this method to pause ongoing tasks, disable timers, and throttle down 49 | // OpenGL ES frame rates. Games should use this method to pause the game. 50 | } 51 | 52 | - (void)applicationDidEnterBackground:(UIApplication*)application { 53 | // Use this method to release shared resources, save user data, invalidate 54 | // timers, and store enough application state information to restore your 55 | // application to its current state in case it is terminated later. 56 | // If your application supports background execution, this method is called 57 | // instead of applicationWillTerminate: when the user quits. 58 | } 59 | 60 | - (void)applicationWillEnterForeground:(UIApplication*)application { 61 | // Called as part of the transition from the background to the inactive state; 62 | // here you can undo many of the changes made on entering the background. 63 | } 64 | 65 | - (void)applicationDidBecomeActive:(UIApplication*)application { 66 | // Restart any tasks that were paused (or not yet started) while the 67 | // application was inactive. If the application was previously in the 68 | // background, optionally refresh the user interface. 69 | } 70 | 71 | - (void)applicationWillTerminate:(UIApplication*)application { 72 | // Called when the application is about to terminate. Save data if 73 | // appropriate. See also applicationDidEnterBackground:. 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webmproject/webm-tools/bd26e6efb52c03453e36d2e93e6fd5065e62440d/vpx_ios/IosPlayer/Default-568h@2x.png -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.google.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | NSAppTransportSecurity 43 | 44 | NSAllowsArbitraryLoads 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IosPlayer.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IosPlayerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.google.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | NSAppTransportSecurity 24 | 25 | NSAllowsArbitraryLoads 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IosPlayerTests/IxoDASHManifestTestData.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | #import "IxoMutableDASHManifest.h" 11 | 12 | @interface IxoDASHManifestTestData : NSObject 13 | + (IxoMutableDASHManifest*)getExpectedManifestForURLString:(NSString*)string; 14 | @end 15 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IosPlayerTests/IxoMutableDASHManifest.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IxoDASHManifestParser.h" 9 | 10 | // 11 | // Mutable versions of the IxoDASHManifestParser data classes for testing. 12 | // 13 | 14 | @interface IxoMutableDASHRepresentation : NSObject 15 | @property(nonatomic, strong) NSString* repID; 16 | @property(nonatomic) int bandwidth; 17 | @property(nonatomic) int width; 18 | @property(nonatomic) int height; 19 | @property(nonatomic) int audioSamplingRate; 20 | @property(nonatomic) int audioChannelConfig; 21 | @property(nonatomic) int startWithSAP; 22 | @property(nonatomic, strong) NSString* baseURL; 23 | @property(nonatomic, strong) NSString* codecs; 24 | @property(nonatomic, strong) NSArray* segmentBaseIndexRange; 25 | @property(nonatomic, strong) NSArray* initializationRange; 26 | 27 | - (id)init; 28 | @end 29 | 30 | @interface IxoMutableDASHAdaptationSet : NSObject 31 | @property(nonatomic, strong) NSString* setID; 32 | @property(nonatomic, strong) NSString* mimeType; 33 | @property(nonatomic, strong) NSString* codecs; 34 | @property(nonatomic) bool subsegmentAlignment; 35 | @property(nonatomic) bool bitstreamSwitching; 36 | @property(nonatomic) int subsegmentStartsWithSAP; 37 | @property(nonatomic) int width; 38 | @property(nonatomic) int height; 39 | @property(nonatomic) int audioSamplingRate; 40 | @property(nonatomic, strong) 41 | NSMutableArray* representations; 42 | 43 | - (id)init; 44 | @end 45 | 46 | @interface IxoMutableDASHPeriod : NSObject 47 | @property(nonatomic, strong) NSString* periodID; 48 | @property(nonatomic, strong) NSString* start; 49 | @property(nonatomic, strong) NSString* duration; 50 | @property(nonatomic, strong) 51 | NSMutableArray* audioAdaptationSets; 52 | @property(nonatomic, strong) 53 | NSMutableArray* videoAdaptationSets; 54 | 55 | - (id)init; 56 | @end 57 | 58 | @interface IxoMutableDASHManifest : NSObject 59 | @property(nonatomic, strong) NSString* mediaPresentationDuration; 60 | @property(nonatomic, strong) NSString* minBufferTime; 61 | @property(nonatomic) bool staticPresentation; 62 | @property(nonatomic, strong) IxoMutableDASHPeriod* period; 63 | - (id)init; 64 | @end 65 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IosPlayerTests/IxoMutableDASHManifest.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IxoMutableDASHManifest.h" 9 | 10 | // 11 | // IxoMutableDASHRepresentation 12 | // 13 | @implementation IxoMutableDASHRepresentation 14 | @synthesize repID = _repID; 15 | @synthesize bandwidth = _bandwidth; 16 | @synthesize width = _width; 17 | @synthesize height = _height; 18 | @synthesize audioSamplingRate = _audioSamplingRate; 19 | @synthesize audioChannelConfig = _audioChannelConfig; 20 | @synthesize startWithSAP = _startWithSAP; 21 | @synthesize codecs = _codecs; 22 | @synthesize baseURL = _baseURL; 23 | @synthesize segmentBaseIndexRange = _segmentBaseIndexRange; 24 | @synthesize initializationRange = _initializationRange; 25 | 26 | - (id)init { 27 | self = [super init]; 28 | if (self) { 29 | self.repID = nil; 30 | self.bandwidth = 0; 31 | self.width = 0; 32 | self.height = 0; 33 | self.audioSamplingRate = 0; 34 | self.audioChannelConfig = 0; 35 | self.startWithSAP = 0; 36 | self.codecs = nil; 37 | self.baseURL = nil; 38 | self.segmentBaseIndexRange = nil; 39 | self.initializationRange = nil; 40 | } 41 | return self; 42 | } 43 | 44 | - (id)copyWithZone:(NSZone*)zone { 45 | IxoMutableDASHRepresentation* copy = 46 | [[IxoMutableDASHRepresentation allocWithZone:zone] init]; 47 | if (copy) { 48 | copy.repID = self.repID; 49 | copy.bandwidth = self.bandwidth; 50 | copy.width = self.width; 51 | copy.height = self.height; 52 | copy.audioSamplingRate = self.audioSamplingRate; 53 | copy.audioChannelConfig = self.audioChannelConfig; 54 | copy.startWithSAP = self.startWithSAP; 55 | copy.codecs = self.codecs; 56 | copy.baseURL = self.baseURL; 57 | copy.segmentBaseIndexRange = self.segmentBaseIndexRange; 58 | copy.initializationRange = self.initializationRange; 59 | } 60 | return copy; 61 | } 62 | @end 63 | 64 | // 65 | // IxoMutableDASHAdaptationSet 66 | // 67 | @implementation IxoMutableDASHAdaptationSet 68 | @synthesize setID = _setID; 69 | @synthesize mimeType = _mimeType; 70 | @synthesize codecs = _codecs; 71 | @synthesize subsegmentAlignment = _subsegmentAlignment; 72 | @synthesize bitstreamSwitching = _bitstreamSwitching; 73 | @synthesize subsegmentStartsWithSAP = _subsegmentStartsWithSAP; 74 | @synthesize width = _width; 75 | @synthesize height = _height; 76 | @synthesize audioSamplingRate = _audioSamplingRate; 77 | @synthesize representations = _representations; 78 | 79 | - (id)init { 80 | self = [super init]; 81 | if (self) { 82 | self.setID = nil; 83 | self.mimeType = nil; 84 | self.codecs = nil; 85 | self.subsegmentAlignment = false; 86 | self.bitstreamSwitching = false; 87 | self.subsegmentStartsWithSAP = 0; 88 | self.width = 0; 89 | self.height = 0; 90 | self.audioSamplingRate = 0; 91 | self.representations = [[NSMutableArray alloc] init]; 92 | 93 | if (self.representations == nil) 94 | return nil; 95 | } 96 | return self; 97 | } 98 | @end 99 | 100 | // 101 | // IxoMutableDASHPeriod 102 | // 103 | @implementation IxoMutableDASHPeriod 104 | @synthesize periodID = _periodID; 105 | @synthesize start = _start; 106 | @synthesize duration = _duration; 107 | @synthesize audioAdaptationSets = _audioAdaptationSets; 108 | @synthesize videoAdaptationSets = _videoAdaptationSets; 109 | 110 | - (id)init { 111 | self = [super init]; 112 | if (self) { 113 | self.periodID = nil; 114 | self.start = nil; 115 | self.duration = nil; 116 | self.audioAdaptationSets = [[NSMutableArray alloc] init]; 117 | self.videoAdaptationSets = [[NSMutableArray alloc] init]; 118 | if (self.audioAdaptationSets == nil || self.videoAdaptationSets == nil) 119 | return nil; 120 | } 121 | return self; 122 | } 123 | @end 124 | 125 | // 126 | // IxoMutableDASHManifest 127 | // 128 | @implementation IxoMutableDASHManifest 129 | @synthesize mediaPresentationDuration = _mediaPresentationDuration; 130 | @synthesize minBufferTime = _minBufferTime; 131 | @synthesize staticPresentation = _staticPresentation; 132 | @synthesize period = _period; 133 | 134 | - (id)init { 135 | self = [super init]; 136 | if (self) { 137 | self.mediaPresentationDuration = nil; 138 | self.minBufferTime = nil; 139 | self.staticPresentation = false; 140 | self.period = nil; 141 | } 142 | return self; 143 | } 144 | @end -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IosPlayerTests/IxoPlayerTestCommon.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | FOUNDATION_EXPORT const int kNumElementsInRangeArray; 11 | 12 | // 13 | // Constants for tests using testdata/manifest_vp9_vorbis.mpd. 14 | // 15 | FOUNDATION_EXPORT NSString* const kVP9VorbisDASHMPD1URLString; 16 | 17 | // Expected values for data length and MD5 checksum (of the entire MPD file). 18 | FOUNDATION_EXPORT const int kVP9VorbisDASHMPD1Length; 19 | FOUNDATION_EXPORT NSString* const kVP9VorbisDASHMPD1MD5; 20 | 21 | // Line lengths, their contents, and their offsets (when non-zero) for ranged 22 | // request tests. 23 | FOUNDATION_EXPORT const int kVP9VorbisDASHMPD1FirstLineLength; 24 | FOUNDATION_EXPORT NSString* const kVP9VorbisDASHMPD1FirstLine; 25 | FOUNDATION_EXPORT const int kVP9VorbisDASHMPD1MiddleLineLength; 26 | FOUNDATION_EXPORT const int kVP9VorbisDASHMPD1MiddleLineOffset; 27 | FOUNDATION_EXPORT NSString* const kVP9VorbisDASHMPD1MiddleLine; 28 | FOUNDATION_EXPORT const int kVP9VorbisDASHMPD1LastLineLength; 29 | FOUNDATION_EXPORT const int kVP9VorbisDASHMPD1LastLineOffset; 30 | FOUNDATION_EXPORT NSString* const kVP9VorbisDASHMPD1LastLine; 31 | 32 | // 33 | // URLs for additional test manifest files. 34 | // 35 | FOUNDATION_EXPORT NSString* const kVP8VorbisDASHMPD1URLString; 36 | FOUNDATION_EXPORT NSString* const kVP9VorbisRepCodecsDASHMPD1URLString; -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IosPlayerTests/IxoPlayerTestCommon.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IosPlayerTestCommon.h" 9 | 10 | #import "IxoDASHManifestParserConstants.h" 11 | #import "IxoDASHManifestTestData.h" 12 | 13 | const int kNumElementsInRangeArray = 2; 14 | 15 | // 16 | // Constants for tests using testdata/manifest_vp9_vorbis.mpd. 17 | // 18 | NSString* const kVP9VorbisDASHMPD1URLString = 19 | @"http://localhost:8000/manifest_vp9_vorbis.mpd"; 20 | 21 | // Expected values for data length and MD5 checksum (of the entire MPD file). 22 | const int kVP9VorbisDASHMPD1Length = 2005; 23 | NSString* const kVP9VorbisDASHMPD1MD5 = @"8ab746aecdc021ef92d9162f4ba5dd89"; 24 | 25 | // Line lengths, their contents, and their offsets (when non-zero) for ranged 26 | // request tests. 27 | const int kVP9VorbisDASHMPD1FirstLineLength = 38; 28 | NSString* const kVP9VorbisDASHMPD1FirstLine = 29 | @""; 30 | 31 | const int kVP9VorbisDASHMPD1MiddleLineLength = 15; 32 | const int kVP9VorbisDASHMPD1MiddleLineOffset = 1108; 33 | NSString* const kVP9VorbisDASHMPD1MiddleLine = @""; 38 | 39 | // 40 | // Constants for tests using testdata/manifest_vp8_vorbis.mpd 41 | // 42 | NSString* const kVP8VorbisDASHMPD1URLString = 43 | @"http://localhost:8000/manifest_vp8_vorbis.mpd"; 44 | 45 | NSString* const kVP9VorbisRepCodecsDASHMPD1URLString = 46 | @"http://localhost:8000/manifest_vp9_vorbis_rep_codecs.mpd"; 47 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDASHChunkIndexer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #import 10 | 11 | #import "IxoDASHStartData.h" 12 | 13 | /// 14 | /// Wrapper class. Stores typed mutable array of arrays. Outer array is chunk 15 | /// index. Inner array is the chunk offsets for use in ranged HTTP requests. 16 | /// 17 | @interface IxoDASHChunkIndex : NSObject 18 | @property(nonatomic, strong) NSMutableArray* chunkRanges; 19 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 20 | @end // @interface IxoDASHChunkIndex : NSObject 21 | 22 | /// 23 | /// Parses the init and index chunks stored within an IxoDASHStartData to yield 24 | /// an array of chunk offset and length arrays. 25 | /// 26 | @interface IxoDASHChunkIndexer : NSObject 27 | 28 | /// Inits indexer for building chunk indexes. 29 | - (instancetype)initWithDASHStartData:(IxoDASHStartData*)startData 30 | NS_DESIGNATED_INITIALIZER; 31 | 32 | - (instancetype)init NS_UNAVAILABLE; 33 | 34 | /// Builds the chunk index and returns it. Returns nil upon failure. 35 | - (IxoDASHChunkIndex*)buildChunkIndex; 36 | 37 | @end // @interface IxoDASHChunkIndexer : NSObject 38 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDASHChunkIndexer.mm: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #import "IxoDASHChunkIndexer.h" 10 | 11 | #include 12 | #include 13 | 14 | #include "mkvparser.hpp" 15 | #include "webm_incremental_reader.h" 16 | 17 | @implementation IxoDASHChunkIndex 18 | @synthesize chunkRanges = _chunkRanges; 19 | 20 | - (instancetype)init { 21 | self = [super init]; 22 | if (self == nil) { 23 | NSLog(@"Out of memory."); 24 | return nil; 25 | } 26 | self.chunkRanges = [[NSMutableArray alloc] init]; 27 | return self; 28 | } 29 | @end // @implementation IxoDASHChunkIndex 30 | 31 | /// 32 | /// Combines the init and index chunks for a DASH presentation, and then 33 | /// supplies the result bytes to mkvparser via WebMFile::WebmIncrementalReader. 34 | /// Walks the cues parsed and stores cluster position and length within an 35 | /// IxoDASHChunkIndex. 36 | /// 37 | @implementation IxoDASHChunkIndexer { 38 | NSMutableData* _webm_buffer; 39 | std::unique_ptr _webm_parser; 40 | webm_tools::WebmIncrementalReader _webm_reader; 41 | NSUInteger _file_length; 42 | } 43 | 44 | - (instancetype)initWithDASHStartData:(IxoDASHStartData*)startData { 45 | self = [super init]; 46 | if (self == nil) { 47 | NSLog(@"Out of memory."); 48 | return nil; 49 | } 50 | 51 | _file_length = startData.fileLength; 52 | _webm_buffer = [NSMutableData dataWithData:startData.initializationChunk]; 53 | if (_webm_buffer == nil) { 54 | NSLog(@"Out of memory."); 55 | return nil; 56 | } 57 | [_webm_buffer appendData:startData.indexChunk]; 58 | 59 | std::int64_t status = _webm_reader.SetBufferWindow( 60 | reinterpret_cast(_webm_buffer.bytes), 61 | static_cast(_webm_buffer.length), 0 /* bytes_consumed */); 62 | if (status != webm_tools::WebmIncrementalReader::kSuccess) { 63 | NSLog(@"cannot set incremental reader buffer window"); 64 | return nil; 65 | } 66 | 67 | if (_webm_reader.SetEndOfSegmentPosition(_webm_buffer.length) != true) { 68 | NSLog(@"cannot set incremental reader segment end position."); 69 | return nil; 70 | } 71 | 72 | using mkvparser::Segment; 73 | Segment* segment = nullptr; 74 | if ((status = Segment::CreateInstance(&_webm_reader, 0 /* pos */, 75 | segment /* Segment*& */)) != 0 || 76 | segment == nullptr) { 77 | NSLog(@"Parser Segment creation failed: %lld", status); 78 | return nil; 79 | } 80 | _webm_parser.reset(segment); 81 | return self; 82 | } 83 | 84 | - (std::int64_t)clusterPosFromCuePoint:(const mkvparser::CuePoint*)cue 85 | andTrack:(const mkvparser::Track*)track { 86 | std::int64_t pos = 0; 87 | if (cue != nullptr && track != nullptr) { 88 | using mkvparser::CuePoint; 89 | const CuePoint::TrackPosition* const track_pos = cue->Find(track); 90 | if (track_pos == nullptr) { 91 | NSLog(@"Chunk indexer can't find cluster position."); 92 | } else { 93 | pos = track_pos->m_pos; 94 | } 95 | } 96 | return pos; 97 | } 98 | 99 | - (IxoDASHChunkIndex*)buildChunkIndex { 100 | if (_webm_buffer == nil || _webm_parser.get() == nullptr) { 101 | NSLog(@"chunk indexer not initialized."); 102 | return nil; 103 | } 104 | 105 | IxoDASHChunkIndex* index = [[IxoDASHChunkIndex alloc] init]; 106 | if (index == nil) { 107 | NSLog(@"Out of memory in chunk indexer."); 108 | return nil; 109 | } 110 | 111 | // Start the parse (mkvparser parses init chunk and inspects index chunk). 112 | const std::int64_t status = _webm_parser->Load(); 113 | if (status != 0) { 114 | NSLog(@"Chunk indexer failed during parse."); 115 | return nil; 116 | } 117 | 118 | const mkvparser::Cues* const cues = _webm_parser->GetCues(); 119 | if (cues == nullptr) { 120 | NSLog(@"Chunk indexer found no cues."); 121 | return nil; 122 | } 123 | 124 | // Parse the index chunk (aka walk/parse cues). 125 | // TODO(tomfinegan): Parse only the first, walk later? This might take too 126 | // much time for a very long presentation. 127 | while (cues->DoneParsing() == false) 128 | cues->LoadCuePoint(); 129 | 130 | const NSInteger num_cue_points = cues->GetCount(); 131 | const mkvparser::CuePoint* cue_point = cues->GetFirst(); 132 | if (cue_point == nullptr || num_cue_points == 0) { 133 | NSLog(@"Chunk indexer found no cues after successful parse"); 134 | return nil; 135 | } 136 | const mkvparser::Track* const track = 137 | _webm_parser->GetTracks()->GetTrackByIndex(0); 138 | if (track == nullptr) { 139 | NSLog(@"Chunk indexer can't find track 0."); 140 | return nil; 141 | } 142 | 143 | for (;;) { 144 | const std::int64_t cluster_start_pos = 145 | [self clusterPosFromCuePoint:cue_point andTrack:track]; 146 | 147 | if (cluster_start_pos == 0) { 148 | NSLog(@"Chunk indexer can't find start pos."); 149 | return nil; 150 | } 151 | 152 | cue_point = cues->GetNext(cue_point); 153 | 154 | std::int64_t cluster_end_pos = 155 | cue_point == nullptr 156 | ? _file_length 157 | : [self clusterPosFromCuePoint:cue_point andTrack:track]; 158 | 159 | NSArray* const range_array = [NSArray 160 | arrayWithObjects:[NSNumber numberWithUnsignedInteger:cluster_start_pos], 161 | [NSNumber numberWithUnsignedInteger:cluster_end_pos], 162 | nil]; 163 | [index.chunkRanges addObject:range_array]; 164 | 165 | if (cue_point == nullptr) 166 | break; 167 | } 168 | return index; 169 | } 170 | 171 | @end // @implementation IxoDASHChunkIndexer 172 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDASHManifestParser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | #import "IxoDataSource.h" 11 | 12 | @interface IxoDASHRepresentation : NSObject 13 | @property(nonatomic, strong, readonly) NSString* repID; 14 | @property(nonatomic, readonly) int bandwidth; 15 | @property(nonatomic, readonly) int width; 16 | @property(nonatomic, readonly) int height; 17 | @property(nonatomic, readonly) int audioSamplingRate; 18 | @property(nonatomic, readonly) int audioChannelConfig; 19 | @property(nonatomic, readonly) int startWithSAP; 20 | @property(nonatomic, strong, readonly) NSString* baseURL; 21 | @property(nonatomic, strong, readonly) NSString* codecs; 22 | @property(nonatomic, strong, readonly) NSArray* segmentBaseIndexRange; 23 | @property(nonatomic, strong, readonly) NSArray* initializationRange; 24 | @end 25 | 26 | @interface IxoDASHAdaptationSet : NSObject 27 | @property(nonatomic, strong, readonly) NSString* setID; 28 | @property(nonatomic, strong, readonly) NSString* mimeType; 29 | @property(nonatomic, strong, readonly) NSString* codecs; 30 | @property(nonatomic, readonly) bool subsegmentAlignment; 31 | @property(nonatomic, readonly) bool bitstreamSwitching; 32 | @property(nonatomic, readonly) int subsegmentStartsWithSAP; 33 | @property(nonatomic, readonly) int width; 34 | @property(nonatomic, readonly) int height; 35 | @property(nonatomic, readonly) int audioSamplingRate; 36 | @property(nonatomic, strong, readonly) 37 | NSMutableArray* representations; 38 | @end 39 | 40 | @interface IxoDASHPeriod : NSObject 41 | @property(nonatomic, strong, readonly) NSString* periodID; 42 | @property(nonatomic, strong, readonly) NSString* start; 43 | @property(nonatomic, strong, readonly) NSString* duration; 44 | @property(nonatomic, strong, readonly) 45 | NSMutableArray* audioAdaptationSets; 46 | @property(nonatomic, strong, readonly) 47 | NSMutableArray* videoAdaptationSets; 48 | @end 49 | 50 | @interface IxoDASHManifest : NSObject 51 | @property(nonatomic, strong, readonly) NSString* mediaPresentationDuration; 52 | @property(nonatomic, strong, readonly) NSString* minBufferTime; 53 | @property(nonatomic, readonly) bool staticPresentation; 54 | @property(nonatomic, strong, readonly) IxoDASHPeriod* period; 55 | @end 56 | 57 | @interface IxoDASHManifestParser : NSObject 58 | @property(nonatomic, strong, readonly) IxoDASHManifest* manifest; 59 | - (instancetype)initWithManifestURL:(NSURL*)manifestURL; 60 | 61 | // Parses the manifest at the URL passed to -initWithManifestURL:manifestURL. 62 | - (bool)parse; 63 | 64 | // Returns the complete URL given the baseURL from an IxoDASHRepresentation. 65 | - (NSString*)absoluteURLStringForBaseURLString:(NSString*)baseURLString; 66 | // Convenience utils for direct access of IxoDASHRepresentations via 67 | // IxoDASHManifestParser. 68 | - (NSMutableArray*)audioRepsForAdaptationSetWithIndex:(int)index; 69 | - (NSMutableArray*)videoRepsForAdaptationSetWithIndex:(int)index; 70 | @end 71 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDASHManifestParserConstants.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | // DASH MPD element names. 11 | FOUNDATION_EXPORT NSString* const kElementMPD; 12 | FOUNDATION_EXPORT NSString* const kElementPeriod; 13 | FOUNDATION_EXPORT NSString* const kElementAdaptationSet; 14 | FOUNDATION_EXPORT NSString* const kElementRepresentation; 15 | FOUNDATION_EXPORT NSString* const kElementBaseURL; 16 | FOUNDATION_EXPORT NSString* const kElementSegmentBase; 17 | FOUNDATION_EXPORT NSString* const kElementInitialization; 18 | FOUNDATION_EXPORT NSString* const kElementAudioChannelConfiguration; 19 | 20 | // DASH MPD element attribute names. 21 | FOUNDATION_EXPORT NSString* const kAttributeType; 22 | FOUNDATION_EXPORT NSString* const kAttributeMediaPresentationDuration; 23 | FOUNDATION_EXPORT NSString* const kAttributeMinBufferTime; 24 | FOUNDATION_EXPORT NSString* const kAttributeID; 25 | FOUNDATION_EXPORT NSString* const kAttributeStart; 26 | FOUNDATION_EXPORT NSString* const kAttributeDuration; 27 | FOUNDATION_EXPORT NSString* const kAttributeMimeType; 28 | FOUNDATION_EXPORT NSString* const kAttributeCodecs; 29 | FOUNDATION_EXPORT NSString* const kAttributeBitstreamSwitching; 30 | FOUNDATION_EXPORT NSString* const kAttributeSubsegmentAlignment; 31 | FOUNDATION_EXPORT NSString* const kAttributeSubsegmentStartsWithSAP; 32 | FOUNDATION_EXPORT NSString* const kAttributeBandwidth; 33 | FOUNDATION_EXPORT NSString* const kAttributeWidth; 34 | FOUNDATION_EXPORT NSString* const kAttributeHeight; 35 | FOUNDATION_EXPORT NSString* const kAttributeRange; 36 | FOUNDATION_EXPORT NSString* const kAttributeIndexRange; 37 | FOUNDATION_EXPORT NSString* const kAttributeAudioSamplingRate; 38 | FOUNDATION_EXPORT NSString* const kAttributeStartWithSAP; 39 | FOUNDATION_EXPORT NSString* const kAttributeValue; 40 | 41 | // Known values for MPD elements and attributes. 42 | FOUNDATION_EXPORT NSString* const kMimeTypeWebmAudio; 43 | FOUNDATION_EXPORT NSString* const kMimeTypeWebmVideo; 44 | 45 | FOUNDATION_EXPORT NSString* const kCodecOpus; 46 | FOUNDATION_EXPORT NSString* const kCodecVorbis; 47 | 48 | FOUNDATION_EXPORT NSString* const kCodecVP8; 49 | FOUNDATION_EXPORT NSString* const kCodecVP9; 50 | 51 | FOUNDATION_EXPORT NSString* const kPresentationTypeDynamic; 52 | FOUNDATION_EXPORT NSString* const kPresentationTypeStatic; 53 | 54 | // TODO(tomfinegan): Not sure if I'll find it useful to have dictionaries of 55 | // expected attributes for each element. That and whether or not a dictionary 56 | // of elements expected as children of the element being parsed are currently 57 | // open questions. 58 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDASHManifestParserConstants.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IxoDASHManifestParserConstants.h" 9 | 10 | // DASH MPD element names. 11 | NSString* const kElementMPD = @"MPD"; 12 | NSString* const kElementPeriod = @"Period"; 13 | NSString* const kElementAdaptationSet = @"AdaptationSet"; 14 | NSString* const kElementRepresentation = @"Representation"; 15 | NSString* const kElementBaseURL = @"BaseURL"; 16 | NSString* const kElementSegmentBase = @"SegmentBase"; 17 | NSString* const kElementInitialization = @"Initialization"; 18 | NSString* const kElementAudioChannelConfiguration = 19 | @"AudioChannelConfiguration"; 20 | 21 | // DASH MPD element attribute names. 22 | NSString* const kAttributeType = @"type"; 23 | NSString* const kAttributeMediaPresentationDuration = 24 | @"mediaPresentationDuration"; 25 | NSString* const kAttributeMinBufferTime = @"minBufferTime"; 26 | NSString* const kAttributeID = @"id"; 27 | NSString* const kAttributeStart = @"start"; 28 | NSString* const kAttributeDuration = @"duration"; 29 | NSString* const kAttributeMimeType = @"mimeType"; 30 | NSString* const kAttributeCodecs = @"codecs"; 31 | NSString* const kAttributeBitstreamSwitching = @"bitstreamSwitching"; 32 | NSString* const kAttributeSubsegmentAlignment = @"subsegmentAlignment"; 33 | NSString* const kAttributeSubsegmentStartsWithSAP = @"subsegmentStartsWithSAP"; 34 | NSString* const kAttributeBandwidth = @"bandwidth"; 35 | NSString* const kAttributeWidth = @"width"; 36 | NSString* const kAttributeHeight = @"height"; 37 | NSString* const kAttributeRange = @"range"; 38 | NSString* const kAttributeIndexRange = @"indexRange"; 39 | NSString* const kAttributeAudioSamplingRate = @"audioSamplingRate"; 40 | NSString* const kAttributeStartWithSAP = @"startWithSAP"; 41 | NSString* const kAttributeValue = @"value"; 42 | 43 | // Known values for MPD elements and attributes. 44 | NSString* const kMimeTypeWebmAudio = @"audio/webm"; 45 | NSString* const kMimeTypeWebmVideo = @"video/webm"; 46 | NSString* const kCodecVP8 = @"vp8"; 47 | NSString* const kCodecVP9 = @"vp9"; 48 | NSString* const kCodecOpus = @"opus"; 49 | NSString* const kCodecVorbis = @"vorbis"; 50 | NSString* const kPresentationTypeDynamic = @"dynamic"; 51 | NSString* const kPresentationTypeStatic = @"static"; 52 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDASHStartData.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | #import "IxoDASHManifestParser.h" 11 | 12 | /// 13 | /// Storage class for holding DASH start data. 14 | /// 15 | /// Start data means the initialization and index chunks. These two pieces of 16 | /// data are required for parsing and requesting chunks. 17 | /// 18 | @interface IxoDASHStartData : NSObject 19 | @property(strong) IxoDASHRepresentation* representation; 20 | @property(strong) NSData* initializationChunk; 21 | @property(strong) NSData* indexChunk; 22 | @property(nonatomic) NSUInteger fileLength; 23 | 24 | - (instancetype)init NS_UNAVAILABLE; 25 | - (instancetype)initWithRepresentation:(IxoDASHRepresentation*)rep 26 | NS_DESIGNATED_INITIALIZER; 27 | 28 | @end // @interface IxoDASHStartData : NSObject 29 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDASHStartData.mm: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IxoDASHStartData.h" 9 | 10 | @implementation IxoDASHStartData 11 | 12 | @synthesize initializationChunk; 13 | @synthesize indexChunk; 14 | @synthesize fileLength = _fileLength; 15 | 16 | - (id)initWithRepresentation:(IxoDASHRepresentation *)rep { 17 | if (rep == nil) { 18 | NSLog(@"Can't init rep record with nil representation."); 19 | return nil; 20 | } 21 | 22 | self = [super init]; 23 | if (self == nil) { 24 | NSLog(@"Out of memory"); 25 | return self; 26 | } 27 | 28 | self.representation = rep; 29 | self.initializationChunk = nil; 30 | self.indexChunk = nil; 31 | self.fileLength = 0; 32 | return self; 33 | } 34 | 35 | @end // @implementation IxoDASHStartData 36 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDataSource.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #import 10 | 11 | @class IxoDownloadRecord; 12 | 13 | /// 14 | /// Listener protocol for asynchronous downloads. 15 | /// 16 | @protocol IxoDataSourceListener 17 | /// Called upon download completion or failure. Status contained within 18 | /// |downloadRecord|. 19 | - (void)receiveData:(IxoDownloadRecord*)downloadRecord; 20 | @end // @protocol IxoDataSourceListener 21 | 22 | /// 23 | /// Downloader class. Provides synchronous and asynchronous download support. 24 | /// 25 | @interface IxoDataSource : NSObject 26 | - (instancetype) init NS_DESIGNATED_INITIALIZER; 27 | 28 | /// Returns all bytes from |URL|. Synchronous. Returns nil or the data from 29 | /// |URL|. 30 | - (IxoDownloadRecord*)downloadFromURL:(NSURL*)URL; 31 | 32 | /// Returns |range| bytes from |URL|. Synchronous. Returns nil or the data from 33 | /// |URL|. 34 | - (IxoDownloadRecord*)downloadFromURL:(NSURL*)URL withRange:(NSArray*)range; 35 | 36 | /// Downloads bytes specified by |range| and sends them to |listener|. This 37 | /// method is asynchronous; the download has started when it returns any 38 | /// non-negative number. Non-negative return values are the identifier for the 39 | /// download started by the successful 40 | /// -downloadDataFromURL:withRange:toListener call. 41 | /// The |listener| is notified after completion of download; not while it is in 42 | /// progress. 43 | - (int)downloadDataFromURL:(NSURL*)URL 44 | withRange:(NSArray*)range 45 | toListener:(id)listener; 46 | 47 | /// Receives notification of complete asynchronous download via 48 | /// listener stored within IxoDownloadRecord. 49 | - (void)downloadCompleteForDownloadRecord:(IxoDownloadRecord*)record; 50 | 51 | @end // @interface IxoDataSource : NSObject -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDataSource.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IxoDataSource.h" 9 | #import "IxoDownloadOperation.h" 10 | #import "IxoDownloadQueue.h" 11 | #import "IxoDownloadRecord.h" 12 | 13 | @implementation IxoDataSource { 14 | int _downloadID; 15 | IxoDownloadQueue* _downloadQueue; 16 | NSLock* _lock; 17 | } 18 | 19 | - (id)init { 20 | self = [super init]; 21 | 22 | if (self) { 23 | _downloadID = 0; 24 | _downloadQueue = [[IxoDownloadQueue alloc] init]; 25 | _lock = [[NSLock alloc] init]; 26 | if (_downloadQueue == nil || _lock == nil) 27 | return nil; 28 | _lock.name = NSStringFromClass([self class]); 29 | } 30 | 31 | return self; 32 | } 33 | 34 | - (IxoDownloadRecord*)downloadFromURL:(NSURL*)URL { 35 | return [self downloadFromURL:URL withRange:nil]; 36 | } 37 | 38 | - (IxoDownloadRecord*)downloadFromURL:(NSURL*)URL withRange:(NSArray*)range { 39 | IxoDownloadRecord* record = [[IxoDownloadRecord alloc] init]; 40 | if (record == nil) { 41 | NSLog(@"downloadFromURL: out of memory."); 42 | return nil; 43 | } 44 | 45 | record.URL = URL; 46 | record.requestedRange = range; 47 | IxoDownloadOperation* download_op = 48 | [[IxoDownloadOperation alloc] initWithDownloadRecord:record]; 49 | 50 | if (download_op == nil) { 51 | NSLog(@"downloadFromURL: out of memory."); 52 | return nil; 53 | } 54 | 55 | [download_op start]; 56 | if (record.failed) { 57 | NSLog(@"downloadFromURL: failed, error=%@", record.error); 58 | return nil; 59 | } 60 | 61 | return record; 62 | } 63 | 64 | - (int)downloadDataFromURL:(NSURL*)URL 65 | withRange:(NSArray*)range 66 | toListener:(id)listener { 67 | int download_id = -1; 68 | 69 | [_lock lock]; 70 | download_id = _downloadID++; 71 | [_lock unlock]; 72 | 73 | IxoDownloadRecord* record = [[IxoDownloadRecord alloc] init]; 74 | if (record == nil) { 75 | NSLog(@"downloadDataFromURL: out of memory."); 76 | return -1; 77 | } 78 | 79 | record.URL = URL; 80 | record.requestedRange = range; 81 | record.listener = listener; 82 | record.downloadID = download_id; 83 | record.dataSource = self; 84 | 85 | IxoDownloadOperation* download_op = 86 | [[IxoDownloadOperation alloc] initWithDownloadRecord:record]; 87 | if (download_op == nil) { 88 | NSLog(@"downloadDataFromURL: out of memory."); 89 | return -1; 90 | } 91 | 92 | [_lock lock]; 93 | [_downloadQueue.activeDownloads 94 | setObject:record 95 | forKey:[NSNumber numberWithInt:download_id]]; 96 | [_downloadQueue.downloadQueue addOperation:download_op]; 97 | [_lock unlock]; 98 | 99 | return download_id; 100 | } 101 | 102 | - (void)downloadCompleteForDownloadRecord:(IxoDownloadRecord*)record { 103 | NSLog(@"Download complete for %d:%@", record.downloadID, 104 | [record.URL absoluteString]); 105 | [_lock lock]; 106 | [_downloadQueue.activeDownloads 107 | removeObjectForKey:[NSNumber numberWithInt:record.downloadID]]; 108 | [_lock unlock]; 109 | NSLog(@"%d:%@ removed from activeDownloads.", record.downloadID, 110 | [record.URL absoluteString]); 111 | if (record.listener != nil) 112 | [record.listener receiveData:record]; 113 | } 114 | 115 | @end // @implementation IxoDataSource 116 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDownloadOperation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | #import "IxoDataSource.h" 11 | 12 | /// 13 | /// Downloader class that supports synchronous or asynchronous operation. 14 | /// Stores downloaded data in IxoDownloadRecord. 15 | /// 16 | @interface IxoDownloadOperation : NSOperation 17 | 18 | /// Convenience property for diagnosing errors. All HTTP request and response 19 | /// headers will be NSLog()'d when this flag is true. 20 | @property(nonatomic) bool logAllHeaders; 21 | 22 | /// Prepares the download operation. 23 | - (instancetype)initWithDownloadRecord:(IxoDownloadRecord*)record 24 | NS_DESIGNATED_INITIALIZER; 25 | - (instancetype)init NS_UNAVAILABLE; 26 | @end 27 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDownloadOperation.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IxoDownloadOperation.h" 9 | 10 | #import "AFNetworking/AFNetworking.h" 11 | 12 | #import "IxoDownloadRecord.h" 13 | 14 | @implementation IxoDownloadOperation { 15 | IxoDownloadRecord* _record; 16 | } 17 | 18 | @synthesize logAllHeaders = _logAllHeaders; 19 | 20 | - (instancetype)initWithDownloadRecord:(IxoDownloadRecord*)record { 21 | if ((self = [super init])) { 22 | _record = record; 23 | } 24 | return self; 25 | } 26 | 27 | /// Builds an AFHTTPRequestOperation from an IxoDownloadRecord. The |record| 28 | /// must outlive the download operation. This method is asynchronous. Success 29 | /// and failure are reported via the |listener| stored in |record| via call to 30 | /// -forwardResponseRecordToDataSource:. 31 | - (AFHTTPRequestOperation*)createHTTPRequestFromDownloadRecord: 32 | (IxoDownloadRecord*)record { 33 | NSMutableURLRequest* request = 34 | [NSMutableURLRequest requestWithURL:record.URL]; 35 | 36 | // NO LOCAL CACHING! Why: 37 | // the NSURL* family of classes supports caching of data. Normally this would 38 | // be an excellent feature, but the NSURL* caching mechanism ignores range 39 | // headers. When sending successive requests for the same resource, the data 40 | // requested in the first request will be returned for all subsequent 41 | // requests. Users of this class need the real data from the source, so 42 | // disable caching entirely. 43 | // Some additional info here: 44 | // https://github.com/lionheart/openradar-mirror/issues/1840 45 | [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; 46 | 47 | if (record.requestedRange != nil) { 48 | const NSNumber* const range_begin = record.requestedRange[0]; 49 | const NSNumber* const range_end = record.requestedRange[1]; 50 | 51 | NSString* const rangeString = 52 | [NSString stringWithFormat:@"bytes=%d-%d", [range_begin intValue], 53 | [range_end intValue]]; 54 | [request setValue:rangeString forHTTPHeaderField:@"range"]; 55 | } 56 | 57 | AFHTTPRequestOperation* request_op = 58 | [[AFHTTPRequestOperation alloc] initWithRequest:request]; 59 | return request_op; 60 | } 61 | 62 | /// Sends |record| to IxoDataSource awaiting the download. 63 | - (void)forwardResponseRecordToDataSource:(IxoDownloadRecord*)record { 64 | if (record.dataSource != nil) 65 | [record.dataSource downloadCompleteForDownloadRecord:record]; 66 | } 67 | 68 | 69 | /// Attempts download of data from URL stored in IxoDownloadRecord. 70 | - (void)main { 71 | if (_record == nil || self.isCancelled) { 72 | return; 73 | } 74 | 75 | AFHTTPRequestOperation* const download_operation = 76 | [self createHTTPRequestFromDownloadRecord:_record]; 77 | [download_operation start]; 78 | 79 | if (self.isCancelled) { 80 | return; 81 | } 82 | 83 | [download_operation waitUntilFinished]; 84 | 85 | if (self.isCancelled) { 86 | return; 87 | } 88 | 89 | _record.data = download_operation.responseData; 90 | _record.error = download_operation.error; 91 | _record.failed = (download_operation.error != nil || 92 | download_operation.responseData == nil); 93 | if (download_operation.response != nil) 94 | _record.responseCode = download_operation.response.statusCode; 95 | 96 | if (_record.requestedRange != nil && !_record.failed) { 97 | const NSNumber* const range_begin = _record.requestedRange[0]; 98 | const NSNumber* const range_end = _record.requestedRange[1]; 99 | const int expected_length = 100 | 1 + [range_end intValue] - [range_begin intValue]; 101 | 102 | if (_record.data.length > expected_length) { 103 | // More data returned than requested. This is likely due to local caching, 104 | // but the main point is that the data that's actually been requested must 105 | // be extracted from the blob returned. 106 | const uint8_t* const data = (uint8_t*)[_record.data bytes]; 107 | const uint8_t* const requested_data = data + [range_begin intValue]; 108 | 109 | NSData* const response = 110 | [NSData dataWithBytes:requested_data length:expected_length]; 111 | _record.data = response; 112 | } 113 | _record.failed = _record.data.length != expected_length; 114 | } 115 | 116 | if (self.logAllHeaders) { 117 | // Debugging/test failure helper code. 118 | NSDictionary* request_dictionary = 119 | download_operation.request.allHTTPHeaderFields; 120 | NSDictionary* response_dictionary = 121 | download_operation.response.allHeaderFields; 122 | NSLog(@"All Request Headers\n%@\n", [request_dictionary description]); 123 | NSLog(@"All Response Headers\n%@\n", [response_dictionary description]); 124 | } 125 | 126 | if (_record.requestedRange != nil) { 127 | NSString* const content_range = [download_operation.response.allHeaderFields 128 | objectForKey:@"content-range"]; 129 | if (content_range != nil) { 130 | NSString* length_string = 131 | [[content_range componentsSeparatedByString:@"/"] lastObject]; 132 | _record.resourceLength = 133 | [[NSNumber numberWithLongLong: 134 | [length_string longLongValue]] unsignedIntegerValue]; 135 | } 136 | } 137 | 138 | [self forwardResponseRecordToDataSource:_record]; 139 | } 140 | 141 | @end // @implementation IxoDownloadOperation 142 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDownloadQueue.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | @interface IxoDownloadQueue : NSObject 11 | 12 | @property(nonatomic, strong) NSOperationQueue* downloadQueue; 13 | @property(nonatomic, strong) NSMutableDictionary* activeDownloads; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDownloadQueue.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IxoDownloadQueue.h" 9 | 10 | NSString* const kDownloadQueueName = @"IxoDownloadQueue"; 11 | const int kMaxConcurrentDownloads = 3; 12 | 13 | @implementation IxoDownloadQueue 14 | 15 | @synthesize downloadQueue = _downloadQueue; 16 | @synthesize activeDownloads = _activeDownloads; 17 | 18 | - (NSOperationQueue*)downloadQueue { 19 | if (_downloadQueue == nil) { 20 | _downloadQueue = [[NSOperationQueue alloc] init]; 21 | if (_downloadQueue == nil) 22 | return nil; 23 | 24 | _downloadQueue.name = kDownloadQueueName; 25 | _downloadQueue.maxConcurrentOperationCount = kMaxConcurrentDownloads; 26 | } 27 | return _downloadQueue; 28 | } 29 | 30 | - (NSMutableDictionary*)activeDownloads { 31 | if (_activeDownloads == nil) { 32 | _activeDownloads = [[NSMutableDictionary alloc] init]; 33 | } 34 | return _activeDownloads; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDownloadRecord.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | #import "IxoDataSource.h" 11 | 12 | /// 13 | /// Simple storage class for handling downloaded data. 14 | /// 15 | @interface IxoDownloadRecord : NSObject 16 | 17 | /// Download URL. 18 | @property(nonatomic, copy) NSURL* URL; 19 | 20 | /// Byte range to request from |URL|. 21 | @property(nonatomic, copy) NSArray* requestedRange; 22 | 23 | /// Data returned from |URL|. 24 | @property(nonatomic, strong) NSData* data; 25 | 26 | /// Listener to be notified when asynchronous download completes. 27 | @property(nonatomic) id listener; 28 | 29 | /// Download identifier for tracking results from asynchronous downloads. 30 | @property(nonatomic) int downloadID; 31 | 32 | /// Download status flag. 33 | @property(nonatomic) bool failed; 34 | 35 | /// Download error, if provided by underlying transport. 36 | @property(nonatomic, strong) NSError* error; 37 | 38 | /// IxoDataSource that owns this IxoDownloadRecord and is observing the 39 | /// download. Non-mandatory. Notification of |listener| is performed by 40 | /// |dataSource| when present and a listener has been provided. 41 | @property(nonatomic) IxoDataSource* dataSource; 42 | 43 | /// The response code returned in response to the request sent to |URL|. 44 | @property(nonatomic) NSInteger responseCode; 45 | 46 | /// The length of the complete resource located at |URL|. Set only for 47 | /// ranged/partial downloads. 0 when |requestedRange| is nil. 48 | @property(nonatomic) NSUInteger resourceLength; 49 | 50 | /// Returns an empty record. 51 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 52 | 53 | @end // @interface IxoDownloadRecord 54 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/IxoDownloadRecord.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "IxoDownloadRecord.h" 9 | 10 | @implementation IxoDownloadRecord 11 | 12 | @synthesize URL = _URL; 13 | @synthesize requestedRange = _requestedRange; 14 | @synthesize downloadID = _downloadID; 15 | @synthesize listener = _listener; 16 | @synthesize data = _data; 17 | @synthesize failed = _failed; 18 | @synthesize error = _error; 19 | @synthesize dataSource = _dataSource; 20 | @synthesize responseCode = _responseCode; 21 | @synthesize resourceLength = _resourceLength; 22 | 23 | - (instancetype)init { 24 | self = [super init]; 25 | if (self != nil) { 26 | self.URL = nil; 27 | self.requestedRange = nil; 28 | self.downloadID = 0; 29 | self.listener = nil; 30 | self.data = nil; 31 | self.failed = false; 32 | self.error = nil; 33 | self.dataSource = nil; 34 | self.responseCode = 0; 35 | self.resourceLength = 0; 36 | } 37 | return self; 38 | } 39 | 40 | @end // @implementation IxoDownloadRecord 41 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/Podfile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | # 3 | # Use of this source code is governed by a BSD-style license 4 | # that can be found in the LICENSE file in the root of the source 5 | # tree. An additional intellectual property rights grant can be found 6 | # in the file PATENTS. All contributing project authors may 7 | # be found in the AUTHORS file in the root of the source tree. 8 | 9 | platform :ios, '7.0' 10 | 11 | pod 'AFNetworking' 12 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/TextViewController.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | @interface TextViewController : UIViewController 11 | 12 | @property(nonatomic, strong, readonly) UITextView* textView; 13 | 14 | - (void)appendText:(NSString*)theText; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/TextViewController.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "TextViewController.h" 9 | 10 | @interface TextViewController () 11 | @property(nonatomic, strong, readwrite) UITextView* textView; 12 | @property(nonatomic, readwrite) bool touched; 13 | @end 14 | 15 | @implementation TextViewController 16 | 17 | @synthesize textView; 18 | @synthesize touched; 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | } 23 | 24 | - (void)didReceiveMemoryWarning { 25 | [super didReceiveMemoryWarning]; 26 | // Dispose of any resources that can be recreated. 27 | } 28 | 29 | - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { 30 | touched = true; 31 | } 32 | 33 | - (void)appendText:(NSString*)theText { 34 | // Lazy init. 35 | if (textView == nil) { 36 | UIWindow* main_window = [[UIApplication sharedApplication] delegate].window; 37 | textView = [[UITextView alloc] initWithFrame:[main_window bounds]]; 38 | if (textView == nil) 39 | return; 40 | 41 | textView.editable = NO; 42 | textView.backgroundColor = [UIColor blackColor]; 43 | textView.textColor = [UIColor whiteColor]; 44 | [self.view addSubview:textView]; 45 | } 46 | 47 | // Disable scrolling while updating; this prevents the view from jumping to 48 | // the bottom because of the update. 49 | textView.scrollEnabled = NO; 50 | textView.text = [textView.text stringByAppendingString:theText]; 51 | textView.scrollEnabled = YES; 52 | } 53 | @end 54 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/main.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | #import "AppDelegate.h" 10 | 11 | int main(int argc, char* argv[]) { 12 | @autoreleasepool { 13 | return UIApplicationMain(argc, argv, nil, 14 | NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/testdata/download_webm_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## 3 | ## Copyright (c) 2015 The WebM project authors. All Rights Reserved. 4 | ## 5 | ## Use of this source code is governed by a BSD-style license 6 | ## that can be found in the LICENSE file in the root of the source 7 | ## tree. An additional intellectual property rights grant can be found 8 | ## in the file PATENTS. All contributing project authors may 9 | ## be found in the AUTHORS file in the root of the source tree. 10 | ## 11 | . ../../../shared/common.sh 12 | 13 | readonly BASE_URL="http://demos.webmproject.org/dash/201410/vp9_files" 14 | 15 | # File names and their checksums. 16 | readonly FILES=(feelings_vp9-20130806-171.webm 17 | feelings_vp9-20130806-172.webm 18 | feelings_vp9-20130806-242.webm 19 | feelings_vp9-20130806-243.webm 20 | feelings_vp9-20130806-244.webm 21 | feelings_vp9-20130806-245.webm 22 | feelings_vp9-20130806-246.webm 23 | feelings_vp9-20130806-247.webm) 24 | readonly CHECKSUMS=(ce3e7a2e72bf291850492d104c7cb1e8 25 | 84a01fd3706db778f954fcb36b0a28ea 26 | 67d99a812352ba73b2b2493517b1f4e5 27 | aeb0ef893cc470211d4edcb27731c114 28 | b42feafeaabbbb17a60b7d1b0bcfb385 29 | 00ca4625c541a7bc69003ad900a2986b 30 | bab04a396855d339a607d13a7ee2ea7a 31 | 937da5127417cfe5ea03cf001f7a8c77) 32 | 33 | check_tool curl --version 34 | check_dir testdata 35 | 36 | if [[ "${#FILES[@]}" -ne "${#CHECKSUMS[@]}" ]]; then 37 | elog "Number of files and checksums do not match, doing nothing." 38 | exit 1 39 | fi 40 | 41 | download_and_verify_webm_files() { 42 | local file="" 43 | local expected_checksum="" 44 | local actual_checksum="" 45 | for (( i = 0; i < ${#FILES[@]}; ++i )); do 46 | file="${FILES[$i]}" 47 | expected_checksum="${CHECKSUMS[$i]}" 48 | 49 | vlog "Downloading ${file}..." 50 | eval curl -O ${BASE_URL}/${FILES[$i]} ${devnull} 51 | 52 | vlog "Verifying ${file}..." 53 | actual_checksum=$(md5 -q "${file}") 54 | if [[ "${actual_checksum}" != "${expected_checksum}" ]]; then 55 | elog "Checksum mismatch for ${file}." 56 | elog " expected: ${expected_checksum} actual: ${actual_checksum}" 57 | exit 1 58 | fi 59 | 60 | vlog "Done." 61 | done 62 | } 63 | 64 | download_and_verify_webm_files 65 | 66 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/testdata/manifest_vp8_vorbis.mpd: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | ChromeSpeedTestsBTS_YouTubeSpecs_enc_640x360_subseg-150_0250K.webm 14 | 15 | 16 | 17 | 18 | 19 | ChromeSpeedTestsBTS_YouTubeSpecs_enc_640x360_subseg-150_0500K.webm 20 | 21 | 22 | 23 | 24 | 25 | ChromeSpeedTestsBTS_YouTubeSpecs_enc_640x360_subseg-150_0750K.webm 26 | 27 | 28 | 29 | 30 | 31 | ChromeSpeedTestsBTS_YouTubeSpecs_enc_640x360_subseg-150_1000K.webm 32 | 33 | 34 | 35 | 36 | 37 | ChromeSpeedTestsBTS_YouTubeSpecs_enc_640x360_subseg-150_1500K.webm 38 | 39 | 40 | 41 | 42 | 43 | ChromeSpeedTestsBTS_YouTubeSpecs_enc_640x360_subseg-150_2000K.webm 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | ChromeSpeedTestsBTS_YouTubeSpecs_vorbis_128kbps_cues-5sec_tracks-2.webm 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/testdata/manifest_vp9_vorbis.mpd: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | glass_242.webm 14 | 16 | 18 | 19 | 20 | 21 | glass_243.webm 22 | 24 | 26 | 27 | 28 | 29 | glass_244.webm 30 | 32 | 34 | 35 | 36 | 37 | glass_247.webm 38 | 40 | 42 | 43 | 44 | 45 | 46 | 47 | glass_171.webm 48 | 50 | 52 | 53 | 54 | 55 | glass_172.webm 56 | 58 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/testdata/manifest_vp9_vorbis_rep_codecs.mpd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | feelings_vp9-20130806-171.webm 8 | 9 | 10 | 11 | 12 | 13 | 14 | feelings_vp9-20130806-172.webm 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | feelings_vp9-20130806-242.webm 23 | 24 | 25 | 26 | 27 | 28 | feelings_vp9-20130806-243.webm 29 | 30 | 31 | 32 | 33 | 34 | feelings_vp9-20130806-244.webm 35 | 36 | 37 | 38 | 39 | 40 | feelings_vp9-20130806-245.webm 41 | 42 | 43 | 44 | 45 | 46 | feelings_vp9-20130806-246.webm 47 | 48 | 49 | 50 | 51 | 52 | feelings_vp9-20130806-247.webm 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /vpx_ios/IosPlayer/testdata/print_cluster_pos_array.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## 3 | ## Copyright (c) 2015 The WebM project authors. All Rights Reserved. 4 | ## 5 | ## Use of this source code is governed by a BSD-style license 6 | ## that can be found in the LICENSE file in the root of the source 7 | ## tree. An additional intellectual property rights grant can be found 8 | ## in the file PATENTS. All contributing project authors may 9 | ## be found in the AUTHORS file in the root of the source tree. 10 | ## 11 | . ../../../shared/common.sh 12 | 13 | check_tool webm_info -h 14 | check_dir testdata 15 | 16 | if [[ -z "$1" ]]; then 17 | elog "Usage: $0 " 18 | exit 1 19 | fi 20 | 21 | if [[ ! -f "$1" ]]; then 22 | elog "Unable to open $1" 23 | exit 1 24 | fi 25 | 26 | print_cluster_pos_array() { 27 | local file="$1" 28 | local cluster_start_pos_str=$(webm_info -all -i "$file" \ 29 | | grep "Cue Point" \ 30 | | awk -F ':' '{print $NF}') 31 | local cluster_start_pos_array=(${cluster_start_pos_str}) 32 | local last_array_index=0 33 | local file_size=$(wc -c < "${file}" | tr -d [:space:]) 34 | local num_clusters=${#cluster_start_pos_array[@]} 35 | for (( i=1; i < ${num_clusters}; i++ )); do 36 | last_array_index=$(( $i - 1 )) 37 | echo @\[@${cluster_start_pos_array[${last_array_index}]}, \ 38 | @${cluster_start_pos_array[$i]}\], 39 | done 40 | local last_cluster_index=$(( ${num_clusters} - 1 )) 41 | echo @\[@${cluster_start_pos_array[${last_cluster_index}]}, @${file_size}\], 42 | } 43 | 44 | print_cluster_pos_array "$1" 45 | -------------------------------------------------------------------------------- /vpx_ios/README.IxoPlayer: -------------------------------------------------------------------------------- 1 | IosPlayer README 2 | 3 | 4 | Prerequisites 5 | ------------- 6 | Cocoapods 7 | - Cocoapods getting started guide: 8 | https://guides.cocoapods.org/using/getting-started.html 9 | Xcode 6 (IosPlayer was built using Xcode 6) 10 | 11 | 12 | Setup 13 | ----- 14 | Before doing anything else, read the contents of README.VPXExample, and follow 15 | all of the instructions in the Prerequisites and Getting Started sections. Any 16 | instructions referring to VPXExample.xcodeproj also apply to 17 | IosPlayer.xcodeproj, but those changes should be made after the xcworkspace is 18 | created by the pod command described below. 19 | 20 | From within the IosPlayer directory, before opening the project: 21 | 1. (First time ever cloning the repo and opening the project) run 'pod install' 22 | to fetch pod dependencies. 23 | 2. (Upon pulling new source code) run 'pod update' 24 | 25 | Note: Do only one of the above steps. Doing both is not required. 26 | 27 | 3. Open the xcworkspace created by the pod command. 28 | 29 | 30 | Testing 31 | ------- 32 | Tests can be run within Xcode via the IosPlayerTests target. 33 | 34 | A web server is required, and is expected to be reachable on localhost:8000. 35 | RangeHTTPServer (the Python module) is recommended (localhost and port 8000 are 36 | its defaults), but any HTTP server that supports ranged HTTP requests should be 37 | adequate. 38 | 39 | To use RangeHTTPServer, run it in the testdata directory that resides in the 40 | IosPlayer directory. 41 | $ cd path/to/IosPlayer/testdata 42 | $ python -m RangeHTTPServer 43 | 44 | -------------------------------------------------------------------------------- /vpx_ios/README.VPXExample: -------------------------------------------------------------------------------- 1 | README.VPXExample 2 | 3 | 4 | Introduction 5 | ------------ 6 | VPXExample.app is an example application that supports playback of IVF and WebM 7 | container files containing VP8 or VP9 bitstreams. In terms of a player 8 | application it's about as simple as it gets: 9 | 10 | - There is no audio playback. This is a video only player. 11 | - There are no playback controls; you cannot pause, stop, fast forward, rewind 12 | or seek. 13 | 14 | 15 | Prerequisites 16 | ------------- 17 | To build VPXExample.app you must have the following installed: 18 | - A recent version of Xcode (this project was built using Xcode v5.1). 19 | - Apple iOS developer program membership. 20 | - git 21 | - yasm (required for libvpx) 22 | - Really. Don't attempt to use nasm. It most likely will not work. 23 | - The easiest way to obtain yasm is using a package manager like homebrew. 24 | - To build yasm: 25 | 1. Clone it via git using the command: 26 | $ git clone git://github.com/yasm/yasm.git 27 | Or download a source archive from http://yasm.tortall.net/Download.html. 28 | 2. Change into the yasm directory and run the following commands 29 | a. ./configure 30 | b. make 31 | - Using yasm: 32 | After building yasm, move the yasm binary to a directory in your path, or 33 | add the build directory to your path. Alternatively, you can run make with 34 | the install target, but you'll need to '$ sudo make install' it, or 35 | modify the default install location via updating DESTDIR, i.e.: 36 | $ make install DESTDIR=/some/writable/directory/ 37 | - Note: /some/writable/directory will need to be in your PATH for libvpx 38 | to access yasm. 39 | 40 | 41 | Getting Started 42 | --------------- 43 | To begin with, you must clone the libvpx, libwebm, and webm-tools git 44 | repositories. 45 | 46 | To do so, open a terminal window, and enter the following commands: 47 | 48 | $ git clone https://chromium.googlesource.com/webm/libvpx 49 | $ git clone https://chromium.googlesource.com/webm/libwebm 50 | $ git clone https://chromium.googlesource.com/webm/webm-tools 51 | 52 | The next step is to build VPX.framework. This contains the include files and 53 | the multi-target fat library required to build VPXExample.app for all targets. 54 | 55 | Note: You can change the location of VPX.framework, but doing so will require 56 | you to make changes to VPXExample.xcodeproj. 57 | 58 | $ mkdir frameworks 59 | $ cd frameworks 60 | $ ../libvpx/build/make/iosbuild.sh 61 | 62 | Notes: 63 | - Run iosbuild.sh with the --help argument for additional command line options. 64 | - On slower machines iosbuild.sh will take a very long time (it configures and 65 | builds libvpx for 5 target platforms). 66 | - If iosbuild.sh fails, clean the directory you ran it from, and then rerun it 67 | with --show-build-output to see the actual error, i.e.: 68 | $ ../libvpx/build/make/iosbuild.sh --show-build-output 69 | Deeper diagnosis of problems can be had via preserving the build artifacts in 70 | addition to showing the output from their creation: 71 | $ ../libvpx/build/make/iosbuild.sh --show-build-output --preserve-build-output 72 | 73 | Now WebM.framework must be built: 74 | 75 | $ cd ../libwebm 76 | $ ./iosbuild.sh --out-dir ../frameworks 77 | 78 | 79 | Building VPXExample.app 80 | ----------------------- 81 | Open VPXExample.xcodeproj in Xcode and build it. That's it. There is no step 82 | two. 83 | 84 | Notes: 85 | - VPXExample includes two target schemes. Using the Debug scheme will result 86 | in severely degraded playback performance (the higher the input video 87 | resolution, the worse this will be). 88 | - See vpx_example_common.h for instructions on toggling between local playback 89 | mode and using a remote server to download files for playback. 90 | 91 | 92 | Playing files with VPXExample.app 93 | --------------------------------- 94 | Whether built with only local playback mode support, or built with download 95 | support, the application functions the same. When the application opens a 96 | list view is displayed that contains files available for playback. The first 97 | step is tapping a file. 98 | 99 | When downloading support is built in, tapping a file will enable the download 100 | button-- at this point the user must tap the download button, and then tap the 101 | play button. 102 | 103 | When built with local playback support, the user needs only to tap the play 104 | button after tapping a file to play. 105 | 106 | Once play has been tapped, the player will play the file. Once input frames 107 | have been exhausted, the application returns to the file selection screen. 108 | 109 | 110 | A guide to the source files in VPXExample.xcodeproj 111 | --------------------------------------------------- 112 | The contents of the project groups (folders) Frameworks, Products, Supporting 113 | Files, and VPXExampleTests and its Supporting Files subgroup are not documented 114 | here. The same is true for iOS basics like AppDelegate.m, AppDelegate.h, and 115 | main.m. VPXExample.xcodeproj uses the generated versions of these files as 116 | produced by Xcode (excluding minor style related edits). 117 | 118 | Everything in the libwebm group can be safely ignored. It's simply support code 119 | for parsing WebM input. Libwebm source files have been included only because no 120 | framework exists for libwebm. 121 | 122 | Scripts/download_file.sh 123 | A shell script that downloads the VP8 and VP9 versions of the Sintel trailer. 124 | 125 | testdata/ 126 | sintel_trailer_vp8.webm 127 | sintel_trailer_vp9.webm 128 | The testdata group contains the input files built into VPXExample.app when 129 | it's built in local playback only mode. 130 | 131 | ivf_frame_parser.* 132 | Implements IVF container parsing support via the class IvfFrameParser. 133 | 134 | GlkVideoViewController.* 135 | This is the renderer used to display video. 136 | 137 | *.storyboard 138 | These files contain the UI used in the application. 139 | 140 | *.glsl 141 | These are shaders that are responsible for converting video pixels from YUV to 142 | RGB for display on the device and simulator screen. 143 | 144 | video_buffer_pool.* 145 | A thread safe buffer pool used to manage handling the movement of video frame 146 | buffers from VpxPlayer to GlkVideoViewController. 147 | 148 | ViewController.* 149 | The main view controller for the application. This file supports the main UI. 150 | 151 | vpx_example_common.h 152 | Contains project wide settings and objects. 153 | 154 | vpx_frame_parser.h 155 | Defines the base interface class used by IvfFrameParser and WebmFrameParser. 156 | 157 | vpx_player.* 158 | The player class: VpxPlayer. Handles decoding of video via libvpx and 159 | conversion of libvpx video buffer output from the YV12 format to the NV12 160 | format. 161 | 162 | webm_frame_parser.* 163 | Implements WebM container parsing support via the class WebmFrameParser. 164 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/.gitignore: -------------------------------------------------------------------------------- 1 | !VPXExample-Prefix.pch 2 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_APPDELEGATE_H_ 9 | #define VPX_IOS_VPXEXAMPLE_APPDELEGATE_H_ 10 | 11 | #import 12 | 13 | @interface AppDelegate : UIResponder 14 | @property(strong, nonatomic) UIWindow *window; 15 | @end 16 | 17 | #endif // VPX_IOS_VPXEXAMPLE_APPDELEGATE_H_ 18 | 19 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "AppDelegate.h" 9 | #import "ViewController.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application 14 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 15 | return YES; 16 | } 17 | 18 | - (void)applicationWillResignActive:(UIApplication *)application { 19 | } 20 | 21 | - (void)applicationDidEnterBackground:(UIApplication *)application { 22 | } 23 | 24 | - (void)applicationWillEnterForeground:(UIApplication *)application { 25 | } 26 | 27 | - (void)applicationDidBecomeActive:(UIApplication *)application { 28 | } 29 | 30 | - (void)applicationWillTerminate:(UIApplication *)application { 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/GlkVideoViewController.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_GLKVIDEOVIEWCONTROLLER_H_ 9 | #define VPX_IOS_VPXEXAMPLE_GLKVIDEOVIEWCONTROLLER_H_ 10 | 11 | #include 12 | #import 13 | 14 | @protocol GlkVideoViewControllerDelegate 15 | - (void) playbackComplete:(BOOL)status statusString:(NSString *)string; 16 | @end 17 | 18 | @class ViewController; 19 | 20 | @interface GlkVideoViewController : GLKViewController 21 | @property(nonatomic, weak) 22 | id vpxtestViewController; 23 | @property(nonatomic, strong) NSString *fileToPlay; 24 | @property(readonly) NSInteger rendererFrameRate; 25 | 26 | - (void)receiveVideoBuffer:(const void*)videoBuffer 27 | withTimestampInMilliseconds:(int64_t)timestamp; 28 | @end 29 | 30 | #endif // VPX_IOS_VPXEXAMPLE_GLKVIDEOVIEWCONTROLLER_H_ 31 | 32 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /vpx_ios/VPXExample/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /vpx_ios/VPXExample/VPXExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.google.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | Main_iPhone 29 | UIMainStoryboardFile~ipad 30 | Main_iPad 31 | UIMainStoryboardFile~iphone 32 | Main_iPhone 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/VPXExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/VPXExample.xcodeproj/xcshareddata/xcschemes/VPXExample Debug.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/VPXExample.xcodeproj/xcshareddata/xcschemes/VPXExample Release.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/VPXExampleTests/VPXExampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.google.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/VPXExampleTests/VPXExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // VPXTestTests.m 3 | // VPXTestTests 4 | // 5 | // Created by Tom Finegan on 6/26/14. 6 | // Copyright (c) 2014 Google. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface VPXTestTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation VPXTestTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each 20 | // test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of 25 | // each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample { 30 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/VPXExampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/ViewController.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_VIEWCONTROLLER_H_ 9 | #define VPX_IOS_VPXEXAMPLE_VIEWCONTROLLER_H_ 10 | 11 | #import 12 | #import 13 | 14 | #import "GlkVideoViewController.h" 15 | 16 | @interface ViewController : UIViewController { 18 | @private 19 | NSInteger downloadFileIndex_; 20 | NSInteger playFileIndex_; 21 | NSInteger selectedFileIndex_; 22 | NSArray *testFiles_; 23 | NSURL *testFileDownloadURL_; 24 | NSURL *cacheDirectoryPath_; 25 | NSURL *downloadedFilePath_; 26 | } 27 | 28 | @property(nonatomic, weak) IBOutlet UIButton *downloadButton; 29 | @property(nonatomic, weak) IBOutlet UIButton *playButton; 30 | @property(nonatomic, weak) IBOutlet UILabel *progressLabel; 31 | @property(nonatomic, weak) IBOutlet UIProgressView *progressView; 32 | @property(nonatomic, weak) IBOutlet UITableView *fileList; 33 | @property(nonatomic, weak) IBOutlet UITextView *outputTextView; 34 | @end 35 | 36 | #endif // VPX_IOS_VPXEXAMPLE_VIEWCONTROLLER_H_ 37 | 38 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/ivf_frame_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_IVF_FRAME_PARSER_H_ 9 | #define VPX_IOS_VPXEXAMPLE_IVF_FRAME_PARSER_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "./vpx_example_common.h" 17 | #include "./vpx_frame_parser.h" 18 | 19 | namespace VpxExample { 20 | 21 | // Returns frames from the IVF file when the IVF file contains a four character 22 | // code known to be a VPx format. 23 | class IvfFrameParser : public VpxFrameParserInterface { 24 | public: 25 | IvfFrameParser() : frame_count_(0) {} 26 | virtual ~IvfFrameParser() {} 27 | bool HasVpxFrames(const std::string &file_path, 28 | VpxFormat *vpx_format) override; 29 | bool ReadFrame(VpxFrame *frame) override; 30 | 31 | private: 32 | struct FileCloser { 33 | void operator()(FILE* file); 34 | }; 35 | 36 | std::unique_ptr file_; 37 | VpxFormat vpx_format_; 38 | VpxTimeBase timebase_; 39 | uint32_t frame_count_; 40 | }; 41 | 42 | } // namespace VpxExample 43 | 44 | #endif // VPX_IOS_VPXEXAMPLE_IVF_FRAME_PARSER_H_ 45 | 46 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/ivf_frame_parser.mm: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import "./ivf_frame_parser.h" 9 | 10 | #import 11 | 12 | #include 13 | #include 14 | 15 | namespace VpxExample { 16 | 17 | namespace { 18 | const int kIvfFormatVersion = 0; 19 | 20 | // IVF file "signature" string. 21 | const char *kIvfSignature = "DKIF"; 22 | 23 | // IVF file size constants. 24 | const int kIvfSignatureSize = 4; 25 | const int kIvfFileHeaderSize = 32; 26 | const int kIvfFrameHeaderSize = 12; 27 | 28 | // IVF file header field offset constants. 29 | // Offsets taken from http://wiki.multimedia.cx/index.php?title=IVF 30 | // Offsets are in position order. The IVF signature offset, which is 31 | // 0, has been omitted. Field value size is inferred by the difference between 32 | // each offset, with the exception of the frame count, the size of which is 4. 33 | const int kIvfVersionOffset = 4; 34 | const int kIvfHeaderSizeOffset = 6; 35 | const int kIvfCodecFourCcOffset = 8; 36 | const int kIvfWidthOffset = 12; 37 | const int kIvfHeightOffset = 14; 38 | const int kIvfRateOffset = 16; 39 | const int kIvfScaleOffset = 20; 40 | const int kIvfFrameCountOffset = 24; 41 | 42 | // IVF frame header offset constants. 43 | const int kIvfFrameSizeOffset = 0; 44 | const int kIvfFrameTimestampOffset = 4; 45 | 46 | // VPx four CC constants. 47 | const uint32_t kVp8FourCc = 0x30385056; 48 | const uint32_t kVp9FourCc = 0x30395056; 49 | 50 | uint16_t ReadIvfHeaderUint16(const std::string &ivf_header, int offset) { 51 | const void *read_head = reinterpret_cast(&ivf_header[offset]); 52 | return CFSwapInt16LittleToHost(*reinterpret_cast(read_head)); 53 | } 54 | 55 | uint32_t ReadIvfHeaderUint32(const std::string &ivf_header, int offset) { 56 | const void *read_head = reinterpret_cast(&ivf_header[offset]); 57 | return CFSwapInt32LittleToHost(*reinterpret_cast(read_head)); 58 | } 59 | 60 | int64_t ReadIvfHeaderInt64(const std::string &ivf_header, int offset) { 61 | const void *read_head = reinterpret_cast(&ivf_header[offset]); 62 | return CFSwapInt64LittleToHost(*reinterpret_cast(read_head)); 63 | } 64 | } // namespace 65 | 66 | void IvfFrameParser::FileCloser::operator()(FILE* file) { 67 | fclose(file); 68 | } 69 | 70 | // Processes the 32-byte IVF file header and returns true when the IVF file 71 | // appears to contain VPx video. 72 | bool IvfFrameParser::HasVpxFrames(const std::string &file_path, 73 | VpxFormat *vpx_format) { 74 | file_.reset(fopen(file_path.c_str(), "rb")); 75 | if (!file_.get()) { 76 | NSLog(@"Unable to open %s", file_path.c_str()); 77 | return false; 78 | } 79 | 80 | std::string ivf_header; 81 | ivf_header.reserve(kIvfFileHeaderSize); 82 | 83 | const size_t read_count = fread(reinterpret_cast(&ivf_header[0]), 84 | 1, 85 | kIvfFileHeaderSize, 86 | file_.get()); 87 | if (read_count != kIvfFileHeaderSize) { 88 | NSLog(@"Read failure after %zu bytes", read_count); 89 | return false; 90 | } 91 | 92 | const void *read_head = reinterpret_cast(&ivf_header[0]); 93 | if (memcmp(read_head, kIvfSignature, kIvfSignatureSize) != 0) { 94 | NSLog(@"%s is not an IVF file.", file_path.c_str()); 95 | return false; 96 | } 97 | 98 | const uint16_t version = ReadIvfHeaderUint16(ivf_header, kIvfVersionOffset); 99 | if (version != kIvfFormatVersion) { 100 | NSLog(@"%s has an invalid IVF file version (%hu).", 101 | file_path.c_str(), version); 102 | return false; 103 | } 104 | 105 | const uint16_t header_size = ReadIvfHeaderUint16(ivf_header, 106 | kIvfHeaderSizeOffset); 107 | if (header_size != kIvfFileHeaderSize) { 108 | NSLog(@"%s has an invalid IVF header size (%hu).", 109 | file_path.c_str(), header_size); 110 | return false; 111 | } 112 | 113 | const uint32_t fourcc = ReadIvfHeaderUint32(ivf_header, 114 | kIvfCodecFourCcOffset); 115 | if (fourcc == kVp8FourCc) { 116 | vpx_format_.codec = VP8; 117 | } else if (fourcc == kVp9FourCc) { 118 | vpx_format_.codec = VP9; 119 | } else { 120 | NSLog(@"Invalid codec four CC (%4s) in %s", 121 | reinterpret_cast(&fourcc), file_path.c_str()); 122 | return false; 123 | } 124 | 125 | vpx_format_.width = ReadIvfHeaderUint16(ivf_header, kIvfWidthOffset); 126 | vpx_format_.height = ReadIvfHeaderUint16(ivf_header, kIvfHeightOffset); 127 | *vpx_format = vpx_format_; 128 | 129 | timebase_.numerator = ReadIvfHeaderUint32(ivf_header, kIvfScaleOffset); 130 | timebase_.denominator = ReadIvfHeaderUint32(ivf_header, kIvfRateOffset); 131 | 132 | // TODO(tomfinegan): Move timebase refactoring to a common location. 133 | if (timebase_.numerator > 1 && 134 | timebase_.denominator > timebase_.numerator && 135 | timebase_.denominator % timebase_.numerator == 0) { 136 | timebase_.denominator /= timebase_.numerator; 137 | timebase_.numerator = 1; 138 | } 139 | 140 | // TODO(tomfinegan): Decide if it's ever worth it to read this value. 141 | frame_count_ = ReadIvfHeaderUint32(ivf_header, kIvfFrameCountOffset); 142 | 143 | NSLog(@"IVF timebase %lld / %lld", 144 | timebase_.numerator, timebase_.denominator); 145 | 146 | return true; 147 | } 148 | 149 | bool IvfFrameParser::ReadFrame(VpxFrame *frame) { 150 | if (frame == NULL || frame->data == NULL) { 151 | return false; 152 | } 153 | 154 | std::string ivf_frame_header; 155 | ivf_frame_header.reserve(kIvfFrameHeaderSize); 156 | 157 | size_t read_count = fread(reinterpret_cast(&ivf_frame_header[0]), 158 | 1, 159 | kIvfFrameHeaderSize, 160 | file_.get()); 161 | if (feof(file_.get())) { 162 | NSLog(@"End of file."); 163 | return false; 164 | } 165 | if (read_count != kIvfFrameHeaderSize) { 166 | NSLog(@"Read failure after %zu frame header bytes", read_count); 167 | return false; 168 | } 169 | 170 | const uint32_t frame_payload_size = 171 | ReadIvfHeaderUint32(ivf_frame_header, kIvfFrameSizeOffset); 172 | 173 | if (frame->data->capacity() < frame_payload_size) { 174 | frame->data->reserve(frame_payload_size * 2); 175 | } 176 | 177 | frame->timebase = timebase_; 178 | frame->timestamp = ReadIvfHeaderInt64(ivf_frame_header, 179 | kIvfFrameTimestampOffset); 180 | 181 | read_count = fread(reinterpret_cast(&(*frame->data)[0]), 182 | 1, 183 | frame_payload_size, 184 | file_.get()); 185 | if (read_count != frame_payload_size) { 186 | NSLog(@"Read failure, file truncated? (expected: %u got: %zu)", 187 | frame_payload_size, read_count); 188 | } 189 | 190 | frame->length = frame_payload_size; 191 | return true; 192 | } 193 | 194 | } // namespace VpxExample 195 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/main.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #import 9 | 10 | #import "./AppDelegate.h" 11 | 12 | int main(int argc, char *argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, 15 | NSStringFromClass([AppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/nv12_fragment_shader.glsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | uniform sampler2D SamplerY; 9 | uniform sampler2D SamplerUV; 10 | 11 | varying highp vec2 texCoordVarying; 12 | 13 | void main() { 14 | mediump vec3 yuv; 15 | lowp vec3 rgb; 16 | 17 | yuv.x = texture2D(SamplerY, texCoordVarying).r; 18 | yuv.yz = texture2D(SamplerUV, texCoordVarying).rg - vec2(0.5, 0.5); 19 | 20 | // Using BT.709 which is the standard for HDTV 21 | rgb = mat3(1, 1, 1, 22 | 0, -.18732, 1.8556, 23 | 1.57481, -.46813, 0) * yuv; 24 | 25 | gl_FragColor = vec4(rgb, 1); 26 | } 27 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/nv12_vertex_shader.glsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | attribute vec4 position; 9 | attribute vec2 texCoord; 10 | 11 | varying vec2 texCoordVarying; 12 | 13 | void main() { 14 | gl_Position = position; 15 | texCoordVarying = texCoord; 16 | } 17 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/video_buffer_pool.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_VIDEO_BUFFER_POOL_H_ 9 | #define VPX_IOS_VPXEXAMPLE_VIDEO_BUFFER_POOL_H_ 10 | 11 | #include 12 | 13 | #include "./vpx_example_common.h" 14 | 15 | namespace VpxExample { 16 | 17 | // Creates and manages a buffer pool containing kNumVideoBuffers VideoBuffers. 18 | class VideoBufferPool { 19 | public: 20 | struct VideoBuffer { 21 | VideoBuffer() : buffer(NULL), in_use(false), slot(0) {} 22 | CVPixelBufferRef buffer; 23 | bool in_use; 24 | size_t slot; 25 | }; 26 | 27 | VideoBufferPool() : lock_(NULL) {} 28 | ~VideoBufferPool(); 29 | 30 | // Allocates buffers stored in |buffer_pool_|. Returns true when successful. 31 | bool Init(size_t width, size_t height); 32 | 33 | // Finds an unused buffer in |buffer_pool_| and returns it. Returns NULL when 34 | // all buffers are in use. 35 | // This call blocks until |lock_| is obtained. 36 | const VideoBuffer *GetBuffer(); 37 | 38 | // Releases |buffer| and returns it to the pool. 39 | // This call blocks until |lock_| is obtained. 40 | void ReleaseBuffer(const VideoBuffer *buffer); 41 | 42 | private: 43 | NSLock *lock_; 44 | VideoBuffer buffer_pool_[kNumVideoBuffers]; 45 | }; 46 | 47 | } // namespace VpxExample 48 | 49 | #endif // VPX_IOS_VPXEXAMPLE_VIDEO_BUFFER_POOL_H_ 50 | 51 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/video_buffer_pool.mm: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #include "./video_buffer_pool.h" 9 | 10 | namespace VpxExample { 11 | 12 | class AutoLock { 13 | public: 14 | explicit AutoLock(NSLock *lock) : lock_(lock) { [lock_ lock]; } 15 | ~AutoLock() { [lock_ unlock]; } 16 | 17 | private: 18 | NSLock *lock_; 19 | }; 20 | 21 | VideoBufferPool::~VideoBufferPool() { 22 | AutoLock lock(lock_); 23 | for (int i = 0; i < kNumVideoBuffers; ++i) { 24 | if (buffer_pool_[i].buffer != NULL) { 25 | CVPixelBufferRelease(buffer_pool_[i].buffer); 26 | } 27 | } 28 | } 29 | 30 | bool VideoBufferPool::Init(size_t width, size_t height) { 31 | lock_ = [[NSLock alloc] init]; 32 | 33 | // Note: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange is NV12. 34 | const OSType pixel_fmt = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; 35 | 36 | const NSDictionary *pixelBufferAttributes = 37 | [NSDictionary dictionaryWithObjectsAndKeys:[NSDictionary dictionary], 38 | kCVPixelBufferIOSurfacePropertiesKey, nil]; 39 | const CFDictionaryRef cfPixelBufferAttributes = 40 | (__bridge CFDictionaryRef)pixelBufferAttributes; 41 | 42 | for (int i = 0; i < kNumVideoBuffers; ++i) { 43 | CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, 44 | width, height, 45 | pixel_fmt, 46 | cfPixelBufferAttributes, 47 | &buffer_pool_[i].buffer); 48 | if (status != kCVReturnSuccess) { 49 | NSLog(@"CVPixelBufferRef creation failed %d", status); 50 | return false; 51 | } 52 | buffer_pool_[i].slot = i; 53 | } 54 | return true; 55 | } 56 | 57 | const VideoBufferPool::VideoBuffer *VideoBufferPool::GetBuffer() { 58 | AutoLock lock(lock_); 59 | const VideoBuffer *buffer = NULL; 60 | for (int i = 0; i < kNumVideoBuffers; ++i) { 61 | if (!buffer_pool_[i].in_use) { 62 | buffer_pool_[i].in_use = true; 63 | buffer = &buffer_pool_[i]; 64 | break; 65 | } 66 | } 67 | return buffer; 68 | } 69 | 70 | void VideoBufferPool::ReleaseBuffer( 71 | const VideoBufferPool::VideoBuffer *buffer) { 72 | AutoLock lock(lock_); 73 | buffer_pool_[buffer->slot].in_use = false; 74 | } 75 | 76 | } // namespace VpxExample 77 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/vpx_example_common.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_VPX_EXAMPLE_COMMON_H_ 9 | #define VPX_IOS_VPXEXAMPLE_VPX_EXAMPLE_COMMON_H_ 10 | 11 | // Comment the following line to enable usage of the basic webserver available 12 | // in vpx_ios/testserver/server.py via python, i.e.: 13 | // $ python path/to/webm-tools/vpx_ios/testserver/server.py 14 | // 15 | // Note: The above command must be run from a directory that contains IVF and/or 16 | // WebM files, and those files must contain VP8 or VP9 video streams. 17 | #define VPXEXAMPLE_LOCAL_PLAYBACK_ONLY 18 | 19 | #ifdef VPXEXAMPLE_LOCAL_PLAYBACK_ONLY 20 | #define kVp8File @"sintel_trailer_vp8.webm" 21 | #define kVp9File @"sintel_trailer_vp9.webm" 22 | #else 23 | // These values must be adjusted when running on an iOS device. localhost is not 24 | // the address you want on the device. 25 | #define TEST_SERVER @"http://localhost:8000" 26 | 27 | // Change allvpx to ivf to list only IVF files. 28 | // Change allvpx to webm to list only WebM files. 29 | #define TEST_FILE_LIST @"http://localhost:8000/allvpx" 30 | #endif 31 | 32 | namespace VpxExample { 33 | 34 | const int kNumVideoBuffers = 8; 35 | const int64_t kNanosecondsPerSecond = 1000000000; 36 | const int64_t kMillisecondsPerSecond = 1000; 37 | 38 | enum VpxCodec { 39 | UNKNOWN, 40 | VP8, 41 | VP9, 42 | }; 43 | 44 | struct VpxFormat { 45 | VpxFormat() : codec(UNKNOWN), width(0), height(0) {} 46 | VpxCodec codec; 47 | int width; 48 | int height; 49 | }; 50 | 51 | struct VpxTimeBase { 52 | VpxTimeBase() : numerator(1), denominator(1) {} 53 | int64_t numerator; 54 | int64_t denominator; 55 | }; 56 | 57 | } // namespace VpxExample 58 | 59 | #endif // VPX_IOS_VPXEXAMPLE_VPX_EXAMPLE_COMMON_H_ 60 | 61 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/vpx_frame_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_VPX_FRAME_PARSER_H_ 9 | #define VPX_IOS_VPXEXAMPLE_VPX_FRAME_PARSER_H_ 10 | 11 | #include 12 | #include 13 | 14 | #include "./vpx_example_common.h" 15 | 16 | namespace VpxExample { 17 | 18 | // A generic interface for reading frames of VP8 or VP9 video from a data source 19 | // that supports synchronous reads. 20 | class VpxFrameParserInterface { 21 | public: 22 | 23 | // VPX frame data ready for decoding by Libvpx. 24 | struct VpxFrame { 25 | VpxFrame() : data(NULL), length(0), timestamp(0) {} 26 | 27 | // Existing, user owned, vector* used by the 28 | // VpxFrameParserInterface implementation to store compressed VPx bitstream 29 | // data. 30 | std::vector *data; 31 | 32 | // Length of VPx bitstream data contained in |data|. 33 | uint32_t length; 34 | 35 | // Timestamp of |data|. 36 | int64_t timestamp; 37 | 38 | // Timebase of |timestamp|. 39 | VpxTimeBase timebase; 40 | }; 41 | 42 | virtual ~VpxFrameParserInterface() {} 43 | 44 | // Implementations return true when the container file contains a VP8 or VP9 45 | // bitstream. 46 | virtual bool HasVpxFrames(const std::string &file_path, 47 | VpxFormat *vpx_format) = 0; 48 | 49 | // Implementations read frames into the std::vector* stored within 50 | // the VpxFrame*. The user owns the vector. The implementation MUST 51 | // return false when the vector* is NULL. 52 | virtual bool ReadFrame(VpxFrame *frame) = 0; 53 | }; 54 | 55 | } // namespace VpxExample 56 | 57 | #endif // VPX_IOS_VPXEXAMPLE_VPX_FRAME_PARSER_H_ 58 | 59 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/vpx_player.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_VPX_PLAYER_H_ 9 | #define VPX_IOS_VPXEXAMPLE_VPX_PLAYER_H_ 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #import "./GlkVideoViewController.h" 17 | #include "./video_buffer_pool.h" 18 | #include "./vpx_example_common.h" 19 | #include "./vpx_frame_parser.h" 20 | 21 | struct vpx_codec_ctx; 22 | struct vpx_image; 23 | 24 | namespace VpxExample { 25 | 26 | class VpxPlayer { 27 | public: 28 | VpxPlayer(); 29 | ~VpxPlayer(); 30 | 31 | void Init(GlkVideoViewController *target_view); 32 | bool LoadFile(const char *file_path); 33 | bool Play(); 34 | void ReleaseVideoBuffer(const VideoBufferPool::VideoBuffer *buffer); 35 | 36 | NSString *playback_result() const { return playback_result_; } 37 | 38 | VpxFormat vpx_format() const { return format_; } 39 | 40 | private: 41 | bool InitParser(); 42 | bool InitBufferPool(); 43 | bool InitVpxDecoder(); 44 | bool DeliverVideoBuffer(const vpx_image *image, 45 | const VideoBufferPool::VideoBuffer *buffer, 46 | int64_t timestamp); 47 | bool DecodeAllVideoFrames(); 48 | 49 | GlkVideoViewController *target_view_; 50 | NSString *playback_result_; 51 | std::unique_ptr parser_; 52 | std::string file_path_; 53 | uint32_t frames_decoded_; 54 | VpxFormat format_; 55 | vpx_codec_ctx *vpx_codec_ctx_; 56 | VideoBufferPool buffer_pool_; 57 | NSLock *buffer_lock_; 58 | }; 59 | 60 | } // namespace VpxExample 61 | 62 | #endif // VPX_IOS_VPXEXAMPLE_VPX_PLAYER_H_ 63 | 64 | -------------------------------------------------------------------------------- /vpx_ios/VPXExample/webm_frame_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | #ifndef VPX_IOS_VPXEXAMPLE_WEBM_FRAME_PARSER_H_ 9 | #define VPX_IOS_VPXEXAMPLE_WEBM_FRAME_PARSER_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "./vpx_example_common.h" 16 | #include "./vpx_frame_parser.h" 17 | 18 | namespace mkvparser { 19 | class Block; 20 | class BlockEntry; 21 | class Cluster; 22 | class MkvReader; 23 | class Segment; 24 | } 25 | 26 | namespace VpxExample { 27 | 28 | // Tracks frame index when a block has multiple frames. 29 | struct WebmBlockHead { 30 | WebmBlockHead() : frames_in_block(0), frame_index(0) {} 31 | void Reset() { frames_in_block = 0; frame_index = 0; } 32 | 33 | int32_t frames_in_block; 34 | int32_t frame_index; 35 | }; 36 | 37 | // Tracks parser position. All pointer members unowned. 38 | struct WebmFrameHead { 39 | WebmFrameHead() : block(NULL), block_entry(NULL), cluster(NULL) {} 40 | void Reset() { 41 | block = NULL; 42 | block_entry = NULL; 43 | cluster = NULL; 44 | block_head.Reset(); 45 | } 46 | 47 | const mkvparser::Block *block; 48 | const mkvparser::BlockEntry *block_entry; 49 | const mkvparser::Cluster *cluster; 50 | 51 | WebmBlockHead block_head; 52 | }; 53 | 54 | // Provides VPX frames from the first video track found in the file passed to 55 | // HasVpxFrames(). 56 | class WebmFrameParser : public VpxFrameParserInterface { 57 | public: 58 | WebmFrameParser() : video_track_num_(0) {} 59 | virtual ~WebmFrameParser() {} 60 | bool HasVpxFrames(const std::string &file_path, 61 | VpxFormat *vpx_format) override; 62 | bool ReadFrame(VpxFrame *frame) override; 63 | 64 | private: 65 | uint64_t video_track_num_; 66 | VpxFormat vpx_format_; 67 | WebmFrameHead frame_head_; 68 | VpxTimeBase timebase_; 69 | 70 | std::unique_ptr reader_; 71 | std::unique_ptr segment_; 72 | }; 73 | 74 | } // namespace VpxExample 75 | 76 | #endif // VPX_IOS_VPXEXAMPLE_WEBM_FRAME_PARSER_H_ 77 | 78 | -------------------------------------------------------------------------------- /vpx_ios/build/download_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ## 3 | ## Copyright (c) 2014 The WebM project authors. All Rights Reserved. 4 | ## 5 | ## Use of this source code is governed by a BSD-style license 6 | ## that can be found in the LICENSE file in the root of the source 7 | ## tree. An additional intellectual property rights grant can be found 8 | ## in the file PATENTS. All contributing project authors may 9 | ## be found in the AUTHORS file in the root of the source tree. 10 | ## 11 | set -e 12 | trap cleanup EXIT 13 | 14 | readonly FILES="sintel_trailer_vp8.webm sintel_trailer_vp9.webm" 15 | readonly HTTP_PATH="http://downloads.webmproject.org/tomfinegan" 16 | readonly DOWNLOAD_PATH="${PROJECT_DIR}/../testdata" 17 | 18 | cleanup() { 19 | if [ $? -ne 0 ]; then 20 | for f in ${FILES}; do 21 | OUTPUT_FILE="${DOWNLOAD_PATH}/$f" 22 | if [ -e "${OUTPUT_FILE}" ]; then 23 | rm "${OUTPUT_FILE}" 24 | fi 25 | done 26 | fi 27 | exit $1 28 | } 29 | 30 | if [ ! -d "${DOWNLOAD_PATH}" ]; then 31 | mkdir -p "${DOWNLOAD_PATH}" 32 | fi 33 | 34 | for f in ${FILES}; do 35 | OUTPUT_FILE="${DOWNLOAD_PATH}/$f" 36 | if [ ! -e "${OUTPUT_FILE}" ]; then 37 | curl -o "${OUTPUT_FILE}" "${HTTP_PATH}/$f" 38 | else 39 | touch "${OUTPUT_FILE}" 40 | fi 41 | done 42 | -------------------------------------------------------------------------------- /vpx_ios/testserver/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | ## 3 | ## Copyright (c) 2014 The WebM project authors. All Rights Reserved. 4 | ## 5 | ## Use of this source code is governed by a BSD-style license 6 | ## that can be found in the LICENSE file in the root of the source 7 | ## tree. An additional intellectual property rights grant can be found 8 | ## in the file PATENTS. All contributing project authors may 9 | ## be found in the AUTHORS file in the root of the source tree. 10 | ## 11 | """ 12 | VPXTestServer - A SimpleHTTPServer based web server which provides file listings 13 | in JSON to clients, and allows download of those files. 14 | """ 15 | import BaseHTTPServer 16 | import json 17 | import os 18 | import SimpleHTTPServer 19 | import SocketServer 20 | import sys 21 | 22 | def list_files_with_suffix_as_json(file_suffixes): 23 | """ 24 | Returns JSON object containing all filenames ending with the specified 25 | suffix in the current directory. 26 | """ 27 | raw_dir_list = [] 28 | for (top, _, files) in os.walk('./'): 29 | for name in files: 30 | raw_dir_list.append(os.path.join(top, name)) 31 | 32 | dir_list = [] 33 | for path in raw_dir_list: 34 | if path.endswith(file_suffixes): 35 | dir_list.append(path.replace('./', '')) 36 | 37 | json_dir_list = json.dumps(dir_list) 38 | return json_dir_list 39 | 40 | 41 | class ThreadedHTTPServer(BaseHTTPServer.HTTPServer, 42 | SocketServer.ThreadingMixIn): 43 | """ 44 | BaseHTTPServer with concurrency support. 45 | """ 46 | pass 47 | 48 | class VPXTestServer(SimpleHTTPServer.SimpleHTTPRequestHandler): 49 | """ 50 | VPXTestServer - SimpleHTTPRequestHandler that implements do_GET to provide 51 | file listings and the files in the listings to clients. 52 | """ 53 | def do_GET(self): 54 | if self.path == '/ivf': 55 | json_dir_list = list_files_with_suffix_as_json('ivf') 56 | elif self.path == '/webm': 57 | json_dir_list = list_files_with_suffix_as_json('webm') 58 | elif self.path == '/allvpx': 59 | json_dir_list = list_files_with_suffix_as_json(('ivf', 'webm')) 60 | else: 61 | SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) 62 | return 63 | 64 | self.send_response(200) 65 | self.send_header('Content-type', 'application/json') 66 | self.end_headers() 67 | self.wfile.write(json_dir_list) 68 | 69 | 70 | def main(): 71 | """ 72 | Parses command line for a single argument: The port on which the HTTP server 73 | will listen for incoming requests. Then kicks off the server and runs until 74 | it dies or there's a keyboard interrupt. 75 | """ 76 | try: 77 | if len(sys.argv) > 1: 78 | port = int(sys.argv[1]) 79 | else: 80 | port = 8000 81 | 82 | httpd = ThreadedHTTPServer(('', port), VPXTestServer) 83 | print 'Started VPXTestServer on port {}.'.format(port) 84 | httpd.serve_forever() 85 | except KeyboardInterrupt: 86 | print 'stopping server.' 87 | httpd.socket.close() 88 | 89 | 90 | if __name__ == '__main__': 91 | main() 92 | -------------------------------------------------------------------------------- /webm_crypt/AUTHORS: -------------------------------------------------------------------------------- 1 | Frank Galligan 2 | -------------------------------------------------------------------------------- /webm_crypt/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011, Google Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | * Neither the name of Google nor the names of its contributors may 16 | be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | -------------------------------------------------------------------------------- /webm_crypt/Makefile: -------------------------------------------------------------------------------- 1 | LIBWEBM = ../../libwebm 2 | OBJECTS = webm_crypt.o 3 | EXE = webm_crypt 4 | INCLUDES = -I$(LIBWEBM) -I../shared 5 | ALL_CXXFLAGS = $(INCLUDES) -W -Wall -g -std=c++11 $(CXXFLAGS) 6 | 7 | $(EXE): $(OBJECTS) 8 | $(CXX) $(OBJECTS) -L$(LIBWEBM) \ 9 | -lwebm -lcrypto -ldl -o $@ 10 | 11 | %.o: %.cc 12 | $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ 13 | 14 | clean: 15 | $(RM) -r $(OBJECTS) $(EXE) Makefile.bak 16 | 17 | .PHONY: clean 18 | -------------------------------------------------------------------------------- /webm_crypt/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | ------------------------------------ 3 | 4 | "These implementations" means the copyrightable works that implement the WebM 5 | codecs distributed by Google as part of the WebM Project. 6 | 7 | Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, 8 | royalty-free, irrevocable (except as stated in this section) patent license to 9 | make, have made, use, offer to sell, sell, import, transfer, and otherwise 10 | run, modify and propagate the contents of these implementations of WebM, where 11 | such license applies only to those patent claims, both currently owned by 12 | Google and acquired in the future, licensable by Google that are necessarily 13 | infringed by these implementations of WebM. This grant does not include claims 14 | that would be infringed only as a consequence of further modification of these 15 | implementations. If you or your agent or exclusive licensee institute or order 16 | or agree to the institution of patent litigation or any other patent 17 | enforcement activity against any entity (including a cross-claim or 18 | counterclaim in a lawsuit) alleging that any of these implementations of WebM 19 | or any code incorporated within any of these implementations of WebM 20 | constitute direct or contributory patent infringement, or inducement of 21 | patent infringement, then any patent rights granted to you under this License 22 | for these implementations of WebM shall terminate as of the date such 23 | litigation is filed. 24 | -------------------------------------------------------------------------------- /webm_crypt/Readme.txt: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | // This application uses the webm library from the libwebm project. 10 | 11 | // Build instructions for Windows: 12 | 1. Install cygwin. 13 | Note: These instructions were written using cygwin 14 | x86_64, but should work with the x86 version. 15 | 2. Using the cygwin package manager, make sure make and g++ 16 | are installed. 17 | 3. Clone libwebm into the same directory as webm-tools. The libwebm and 18 | webm-tools directories must be siblings in the same root directory. 19 | 4. In the libwebm repository, run: 20 | $ make -f Makefile.unix 21 | 5. Back in the webm_crypt source directory, run: 22 | $ make 23 | 6. To confirm webm_crypt works, run: 24 | $ webm_crypt -test 25 | 26 | // Build instructions for Linux and Mac: 27 | 1. Clone libwebm into the same directory as webm-tools. The libwebm and 28 | webm-tools directories must be siblings in the same root directory. 29 | 2. In the libwebm repository, run: 30 | $ make -f Makefile.unix 31 | 3. Back in the webm_crypt source directory, run: 32 | $ make 33 | 4. To confirm webm_crypt works, run: 34 | $ webm_crypt -test 35 | -------------------------------------------------------------------------------- /webm_crypt/aes_ctr.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The WebM project authors. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace std; 24 | 25 | // This class implements AES-CTR encryption. Only 128-bits Initialization 26 | // Vector is supported in this class. 27 | class AesCtr128Encryptor { 28 | public: 29 | AesCtr128Encryptor() {} 30 | ~AesCtr128Encryptor() {} 31 | 32 | bool InitKey(const string& key) { 33 | if (AES_set_encrypt_key(reinterpret_cast(key.c_str()), 34 | 128, &aes_key_) != 0) { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | bool SetCounter(const string& counter) { 41 | if (counter.size() != AES_BLOCK_SIZE) 42 | return false; 43 | counter_ = counter; 44 | return true; 45 | } 46 | 47 | bool Encrypt(const uint8_t* input, size_t size, uint8_t* output) { 48 | if (counter_.size() != AES_BLOCK_SIZE) { 49 | return false; 50 | } 51 | 52 | uint8_t ivec[AES_BLOCK_SIZE] = { 0 }; 53 | uint8_t ecount_buf[AES_BLOCK_SIZE] = { 0 }; 54 | unsigned int block_offset = 0; 55 | 56 | memcpy(ivec, counter_.c_str(), AES_BLOCK_SIZE); 57 | AES_ctr128_encrypt(input, output, size, &aes_key_, ivec, ecount_buf, 58 | &block_offset); 59 | 60 | return true; 61 | } 62 | 63 | private: 64 | string counter_; 65 | AES_KEY aes_key_; 66 | }; 67 | -------------------------------------------------------------------------------- /webm_crypt/environment.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | D:\src\Chromium\Src 6 | 7 | 8 | 9 | 10 | 11 | $(CHROMIUM_INC) 12 | true 13 | 14 | 15 | -------------------------------------------------------------------------------- /webm_crypt/webm_crypt_2010.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webm_crypt_2010", "webm_crypt_2010.vcxproj", "{7A216236-33B9-4CD8-B78F-23169A2E7B09}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug DLL|Win32 = Debug DLL|Win32 9 | Debug|Win32 = Debug|Win32 10 | Release DLL|Win32 = Release DLL|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {7A216236-33B9-4CD8-B78F-23169A2E7B09}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 15 | {7A216236-33B9-4CD8-B78F-23169A2E7B09}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 16 | {7A216236-33B9-4CD8-B78F-23169A2E7B09}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {7A216236-33B9-4CD8-B78F-23169A2E7B09}.Debug|Win32.Build.0 = Debug|Win32 18 | {7A216236-33B9-4CD8-B78F-23169A2E7B09}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 19 | {7A216236-33B9-4CD8-B78F-23169A2E7B09}.Release DLL|Win32.Build.0 = Release DLL|Win32 20 | {7A216236-33B9-4CD8-B78F-23169A2E7B09}.Release|Win32.ActiveCfg = Release|Win32 21 | {7A216236-33B9-4CD8-B78F-23169A2E7B09}.Release|Win32.Build.0 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /webm_dash_manifest/Makefile: -------------------------------------------------------------------------------- 1 | LIBWEBM := ../../libwebm 2 | OBJECTS := ../shared/indent.o dash_model.o representation.o adaptation_set.o 3 | OBJECTS += period.o webm_dash_manifest.o ../shared/webm_file.o 4 | OBJECTS += ../shared/webm_incremental_reader.o 5 | EXE := webm_dash_manifest 6 | INCLUDES = -I$(LIBWEBM) -I../shared 7 | DEBUG := -g 8 | CXXFLAGS = -W -Wall -O2 $(DEBUG) 9 | 10 | $(EXE): $(OBJECTS) 11 | $(CXX) $(OBJECTS) -L$(LIBWEBM) -lwebm -o $(EXE) 12 | 13 | %.o: %.cc 14 | $(CXX) -c $(CXXFLAGS) $(INCLUDES) $< -o $@ 15 | 16 | all: $(EXE) 17 | 18 | clean: 19 | $(RM) $(OBJECTS) $(EXE) Makefile.bak 20 | 21 | .PHONY: all clean 22 | 23 | -------------------------------------------------------------------------------- /webm_dash_manifest/adaptation_set.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef WEBM_DASH_MANIFEST_ADAPTATION_SET_H_ 12 | #define WEBM_DASH_MANIFEST_ADAPTATION_SET_H_ 13 | 14 | #include 15 | #include 16 | 17 | #include "webm_tools_types.h" 18 | 19 | namespace webm_tools { 20 | class Indent; 21 | } // namespace webm_tools 22 | 23 | namespace webm_dash { 24 | 25 | class DashModel; 26 | class Representation; 27 | 28 | class AdaptationSet { 29 | public: 30 | AdaptationSet(const std::string& id, const DashModel& dash); 31 | ~AdaptationSet(); 32 | 33 | // Inits all of the files within this adaptation set. Checks to make sure all 34 | // of the codecs in the files match. Calculates max duration. 35 | bool Init(); 36 | 37 | // Adds a new Representation that is controlled by the AdaptationSet. If 38 | // successful the current Representation will point to the newly added 39 | // Representation. 40 | void AddRepresentation(); 41 | 42 | // Returns the current Representation. If no Representation has been added 43 | // then returns NULL. 44 | Representation* CurrentRepresentation() const; 45 | 46 | // Search the Representation list for |id|. If not found return NULL 47 | const Representation* FindRepresentation(const std::string& id) const; 48 | 49 | // Outputs AdaptationSet in the WebM Dash format. 50 | void OutputDashManifest(FILE* o, webm_tools::Indent* indent) const; 51 | 52 | double duration() const { return duration_; } 53 | 54 | std::string id() const { return id_; } 55 | void set_id(const std::string& id) { id_ = id; } 56 | 57 | std::string lang() const { return lang_; } 58 | void set_lang(const std::string& lang) { lang_ = lang; } 59 | 60 | void set_profile(const std::string& profile) { profile_ = profile; } 61 | 62 | private: 63 | // Check all the files within the AdaptationSet to see if they conform to 64 | // the bitstreamSwitching attribute. 65 | bool BitstreamSwitching() const; 66 | 67 | // Check all the Representations within the AdaptationSet to see if they 68 | // have the same sample rate. Returns the sample rate if all the 69 | // Representations have a matching sample rate. Returns 0 if the sample 70 | // rates do not match or the Representations do not contain audio. 71 | int MatchingAudioSamplingRate() const; 72 | 73 | // Check all the Representations within the AdaptationSet to see if they 74 | // have the same height. Returns the height if all the Representations have 75 | // a matching height. Returns 0 if the heights do not match or the 76 | // Representations do not contain video. 77 | int MatchingHeight() const; 78 | 79 | // Check all the Representations within the AdaptationSet to see if they 80 | // have the same width. Returns the width if all the Representations have 81 | // a matching width. Returns 0 if the widths do not match or the 82 | // Representations do not contain video. 83 | int MatchingWidth() const; 84 | 85 | // Check all the files within the AdaptationSet to see if they conform to 86 | // the subsegmentAlignment attribute. 87 | bool SubsegmentAlignment() const; 88 | 89 | // Check all the files within the AdaptationSet to see if they conform to 90 | // the subsegmentStartsWithSAP attribute. 91 | bool SubsegmentStartsWithSAP() const; 92 | 93 | // Codec string of all the files. 94 | std::string codec_; 95 | 96 | // The main class for the manifest. 97 | const DashModel& dash_model_; 98 | 99 | // Used to differentiate between different media groups within a 100 | // presentation. 101 | std::string id_; 102 | 103 | // Language attribute. 104 | std::string lang_; 105 | 106 | // Mimetype attribute. 107 | std::string mimetype_; 108 | 109 | // WebM Dash profile. 110 | std::string profile_; 111 | 112 | // Maximum duration of all |media_|. 113 | double duration_; 114 | 115 | // TODO(fgalligan): Think about changing representations_ to a map with rep 116 | // id as the key. 117 | // Media list for this media group. 118 | std::vector representations_; 119 | 120 | WEBM_TOOLS_DISALLOW_COPY_AND_ASSIGN(AdaptationSet); 121 | }; 122 | 123 | } // namespace webm_dash 124 | 125 | #endif // WEBM_DASH_MANIFEST_ADAPTATION_SET_H_ 126 | -------------------------------------------------------------------------------- /webm_dash_manifest/dash_model.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "dash_model.h" 12 | 13 | #include 14 | 15 | #include "adaptation_set.h" 16 | #include "indent.h" 17 | #include "period.h" 18 | #include "webm_file.h" 19 | 20 | using std::string; 21 | using std::vector; 22 | using webm_tools::WebMFile; 23 | 24 | namespace webm_dash { 25 | 26 | typedef vector::iterator AdaptationSetIterator; 27 | typedef vector::const_iterator AdaptationSetConstIterator; 28 | typedef vector::iterator PeriodIterator; 29 | typedef vector::const_iterator PeriodConstIterator; 30 | typedef vector::iterator WebMFileIterator; 31 | typedef vector::const_iterator WebMFileConstIterator; 32 | 33 | const char DashModel::webm_on_demand[] = 34 | "urn:webm:dash:profile:webm-on-demand:2012"; 35 | const char DashModel::xml_schema_location[] = 36 | "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""; 37 | const char DashModel::xml_namespace[] = 38 | "xmlns=\"urn:mpeg:DASH:schema:MPD:2011\""; 39 | const char DashModel::xml_namespace_location[] = 40 | "xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011\""; 41 | 42 | DashModel::DashModel() 43 | : type_("static"), 44 | duration_(0.0), 45 | min_buffer_time_(1.0), 46 | profile_(DashModel::webm_on_demand), 47 | output_filename_("manifest.mpd") { 48 | } 49 | 50 | DashModel::~DashModel() { 51 | for (AdaptationSetIterator iter = adaptation_sets_.begin(); 52 | iter != adaptation_sets_.end(); 53 | ++iter) { 54 | const AdaptationSet* const as = *iter; 55 | delete as; 56 | } 57 | 58 | for (PeriodIterator period_iter = periods_.begin(); 59 | period_iter != periods_.end(); 60 | ++period_iter) { 61 | const Period* const period = *period_iter; 62 | delete period; 63 | } 64 | 65 | for (WebMFileIterator webm_iter = webm_files_.begin(); 66 | webm_iter != webm_files_.end(); 67 | ++webm_iter) { 68 | const WebMFile* const webm = *webm_iter; 69 | delete webm; 70 | } 71 | } 72 | 73 | bool DashModel::Init() { 74 | for (vector::const_iterator file_iter = webm_filenames_.begin(); 75 | file_iter != webm_filenames_.end(); 76 | ++file_iter) { 77 | std::unique_ptr webm(new (std::nothrow) WebMFile()); // NOLINT 78 | if (!webm.get()) 79 | return false; 80 | if (!webm->ParseFile(*file_iter)) 81 | return false; 82 | 83 | if (profile_ == DashModel::webm_on_demand) { 84 | if (!webm->OnlyOneStream()) { 85 | return false; 86 | } 87 | } 88 | 89 | webm_files_.push_back(webm.release()); 90 | } 91 | 92 | AdaptationSetIterator as_iter; 93 | for (as_iter = adaptation_sets_.begin(); 94 | as_iter != adaptation_sets_.end(); 95 | ++as_iter) { 96 | (*as_iter)->set_profile(profile_); 97 | if ((*as_iter)->Init() == false) 98 | return false; 99 | } 100 | 101 | // If no periods have been added on the command line add one by default. 102 | if (periods_.empty()) 103 | AddPeriod(); 104 | Period* period = CurrentPeriod(); 105 | if (!period) 106 | return false; 107 | 108 | for (as_iter = adaptation_sets_.begin(); 109 | as_iter != adaptation_sets_.end(); 110 | ++as_iter) { 111 | period->AddAdaptationSetID((*as_iter)->id()); 112 | } 113 | 114 | // Set the media group pointers 115 | PeriodIterator period_iter; 116 | for (period_iter = periods_.begin(); 117 | period_iter != periods_.end(); 118 | ++period_iter) { 119 | period = *period_iter; 120 | for (int i = 0; i < period->AdaptationSetIDSize(); ++i) { 121 | string id; 122 | if (!period->AdaptationSetID(i, &id)) 123 | return false; 124 | 125 | const AdaptationSet* const as = FindAdaptationSet(id); 126 | if (!as) 127 | return false; 128 | 129 | period->AddAdaptationSet(as); 130 | } 131 | } 132 | 133 | for (period_iter = periods_.begin(); 134 | period_iter != periods_.end(); 135 | ++period_iter) { 136 | if ((*period_iter)->Init() == false) 137 | return false; 138 | } 139 | 140 | for (period_iter = periods_.begin(); 141 | period_iter != periods_.end(); 142 | ++period_iter) { 143 | if (duration_ < (*period_iter)->duration()) 144 | duration_ = (*period_iter)->duration(); 145 | } 146 | 147 | return true; 148 | } 149 | 150 | void DashModel::AddAdaptationSet() { 151 | char str[128]; 152 | snprintf(str, sizeof(str), "%d", static_cast(adaptation_sets_.size())); 153 | const string id = str; 154 | adaptation_sets_.push_back(new AdaptationSet(id, *this)); 155 | } 156 | 157 | void DashModel::AppendBaseUrl(const string& url) { 158 | base_urls_.push_back(url); 159 | } 160 | 161 | void DashModel::AppendInputFile(const string& filename) { 162 | webm_filenames_.push_back(filename); 163 | } 164 | 165 | void DashModel::AddPeriod() { 166 | char str[128]; 167 | snprintf(str, sizeof(str), "%d", static_cast(periods_.size())); 168 | const string id = str; 169 | periods_.push_back(new Period(id)); 170 | } 171 | 172 | AdaptationSet* DashModel::CurrentAdaptationSet() const { 173 | AdaptationSetConstIterator iter_curr(adaptation_sets_.end()); 174 | if (iter_curr == adaptation_sets_.begin()) 175 | return NULL; 176 | 177 | --iter_curr; 178 | return *iter_curr; 179 | } 180 | 181 | Period* DashModel::CurrentPeriod() const { 182 | PeriodConstIterator iter_curr(periods_.end()); 183 | if (iter_curr == periods_.begin()) 184 | return NULL; 185 | 186 | --iter_curr; 187 | return *iter_curr; 188 | } 189 | 190 | const AdaptationSet* DashModel::FindAdaptationSet(const string& id) const { 191 | for (AdaptationSetConstIterator iter = adaptation_sets_.begin(); 192 | iter != adaptation_sets_.end(); 193 | ++iter) { 194 | if ((*iter)->id() == id) 195 | return *iter; 196 | } 197 | 198 | return NULL; 199 | } 200 | 201 | const WebMFile* DashModel::FindWebMFile(const string& filename) const { 202 | for (WebMFileConstIterator iter = webm_files_.begin(); 203 | iter != webm_files_.end(); 204 | ++iter) { 205 | if ((*iter)->filename() == filename) 206 | return *iter; 207 | } 208 | 209 | return NULL; 210 | } 211 | 212 | bool DashModel::OutputDashManifestFile() const { 213 | if (output_filename_.empty()) 214 | return false; 215 | 216 | FILE* const o = fopen(output_filename_.c_str(), "w"); 217 | if (!o) 218 | return false; 219 | 220 | fprintf(o, "\n"); 221 | fprintf(o, "\n"); 233 | 234 | for (vector::const_iterator stri = base_urls_.begin(); 235 | stri != base_urls_.end(); 236 | ++stri) { 237 | fprintf(o, " %s\n", (*stri).c_str()); 238 | } 239 | 240 | webm_tools::Indent indent(0); 241 | for (PeriodConstIterator iter = periods_.begin(); 242 | iter != periods_.end(); 243 | ++iter) { 244 | (*iter)->OutputDashManifest(o, &indent); 245 | } 246 | 247 | fprintf(o, "\n"); 248 | fclose(o); 249 | 250 | return true; 251 | } 252 | 253 | } // namespace webm_dash 254 | -------------------------------------------------------------------------------- /webm_dash_manifest/dash_model.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef WEBM_DASH_MANIFEST_DASH_MODEL_H_ 12 | #define WEBM_DASH_MANIFEST_DASH_MODEL_H_ 13 | 14 | #include 15 | #include 16 | 17 | #include "webm_tools_types.h" 18 | 19 | namespace webm_tools { 20 | class WebMFile; 21 | } // namespace webm_tools 22 | 23 | namespace webm_dash { 24 | 25 | class AdaptationSet; 26 | class Period; 27 | 28 | // This class models how the manifest should be laid out. 29 | class DashModel { 30 | public: 31 | // WebM On-Demand profile. 32 | static const char webm_on_demand[]; 33 | 34 | DashModel(); 35 | ~DashModel(); 36 | 37 | // Inits all of the media groups. 38 | bool Init(); 39 | 40 | // Adds a new AdaptationSet that is controlled by the DashModel. If 41 | // successful the current AdaptationSet will point to the newly added 42 | // AdaptationSet. 43 | void AddAdaptationSet(); 44 | 45 | // Adds another base url to the manifest at the end of the list. 46 | void AppendBaseUrl(const std::string& url); 47 | 48 | // Adds another input file at the end of the list. 49 | void AppendInputFile(const std::string& filename); 50 | 51 | // Adds a new Period that is controlled by the DashModel. If 52 | // successful the current Period will point to the newly added 53 | // Period. 54 | void AddPeriod(); 55 | 56 | // Returns the current AdaptationSet. If no AdaptationSets have been added 57 | // then returns NULL. 58 | AdaptationSet* CurrentAdaptationSet() const; 59 | 60 | // Returns the current Period. If no Periods have been added 61 | // then returns NULL. 62 | Period* CurrentPeriod() const; 63 | 64 | // Search the AdaptationSet list for |id|. If not found return NULL. 65 | const AdaptationSet* FindAdaptationSet(const std::string& id) const; 66 | 67 | // Search the webm file list for |filename|. If not found return NULL. 68 | const webm_tools::WebMFile* FindWebMFile(const std::string& filename) const; 69 | 70 | // Write out the manifest file to |output_filename_|. 71 | bool OutputDashManifestFile() const; 72 | 73 | double min_buffer_time() const { return min_buffer_time_; } 74 | 75 | std::string output_filename() const { return output_filename_; } 76 | void set_output_filename(const std::string& file) { 77 | output_filename_ = file; 78 | } 79 | 80 | void set_profile(const std::string& profile) { profile_ = profile; } 81 | 82 | private: 83 | // XML Schema location. 84 | static const char xml_schema_location[]; 85 | 86 | // Dash namespace. 87 | static const char xml_namespace[]; 88 | 89 | // Dash namespace location. 90 | static const char xml_namespace_location[]; 91 | 92 | // File type. Either static or live. 93 | std::string type_; 94 | 95 | // Maximum duration of all |periods_|. 96 | double duration_; 97 | 98 | // Minimum buffer time in seconds. 99 | double min_buffer_time_; 100 | 101 | // WebM Dash profile. 102 | std::string profile_; 103 | 104 | // List of base urls for the mpd. 105 | std::vector base_urls_; 106 | 107 | // List of input WebM filenames. 108 | std::vector webm_filenames_; 109 | 110 | // List of input WebM files. 111 | std::vector webm_files_; 112 | 113 | // Adaptation set list for a presentation. 114 | std::vector adaptation_sets_; 115 | 116 | // Period list for a presentation. 117 | std::vector periods_; 118 | 119 | // Path to output the manifest. 120 | std::string output_filename_; 121 | 122 | WEBM_TOOLS_DISALLOW_COPY_AND_ASSIGN(DashModel); 123 | }; 124 | 125 | } // namespace webm_dash 126 | 127 | #endif // WEBM_DASH_MANIFEST_DASH_MODEL_H_ 128 | -------------------------------------------------------------------------------- /webm_dash_manifest/period.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "period.h" 12 | 13 | #include 14 | 15 | #include "adaptation_set.h" 16 | #include "indent.h" 17 | 18 | using std::string; 19 | using std::vector; 20 | using webm_tools::Indent; 21 | 22 | namespace webm_dash { 23 | 24 | typedef vector::const_iterator 25 | AdaptationSetConstIterator; 26 | 27 | Period::Period(const string& id) 28 | : duration_(0.0), 29 | id_(id), 30 | start_(0.0) { 31 | } 32 | 33 | Period::~Period() { 34 | } 35 | 36 | bool Period::Init() { 37 | for (AdaptationSetConstIterator iter = adaptation_sets_.begin(); 38 | iter != adaptation_sets_.end(); 39 | ++iter) { 40 | const double duration = (*iter)->duration(); 41 | if (duration > duration_) 42 | duration_ = duration; 43 | } 44 | return true; 45 | } 46 | 47 | void Period::AddAdaptationSetID(const string& id) { 48 | adaptation_set_ids_.push_back(id); 49 | } 50 | 51 | int Period::AdaptationSetIDSize() const { 52 | return adaptation_set_ids_.size(); 53 | } 54 | 55 | bool Period::AdaptationSetID(unsigned int index, string* id) const { 56 | if (!id) 57 | return false; 58 | 59 | if (index >= adaptation_set_ids_.size()) 60 | return false; 61 | 62 | *id = adaptation_set_ids_.at(index); 63 | return true; 64 | } 65 | 66 | void Period::AddAdaptationSet(const AdaptationSet* as) { 67 | adaptation_sets_.push_back(as); 68 | } 69 | 70 | void Period::OutputDashManifest(FILE* o, Indent* indent) const { 71 | indent->Adjust(webm_tools::kIncreaseIndent); 72 | fprintf(o, "%sindent_str().c_str(), id_.c_str()); 73 | 74 | fprintf(o, " start=\"PT%gS\"", start_); 75 | fprintf(o, " duration=\"PT%gS\"", duration_); 76 | fprintf(o, " >\n"); 77 | 78 | for (AdaptationSetConstIterator iter = adaptation_sets_.begin(); 79 | iter != adaptation_sets_.end(); 80 | ++iter) { 81 | (*iter)->OutputDashManifest(o, indent); 82 | } 83 | 84 | fprintf(o, "%s\n", indent->indent_str().c_str()); 85 | indent->Adjust(webm_tools::kDecreaseIndent); 86 | } 87 | 88 | } // namespace adaptive_manifest 89 | -------------------------------------------------------------------------------- /webm_dash_manifest/period.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef WEBM_DASH_MANIFEST_PERIOD_H_ 12 | #define WEBM_DASH_MANIFEST_PERIOD_H_ 13 | 14 | #include 15 | #include 16 | 17 | #include "webm_tools_types.h" 18 | 19 | namespace webm_tools { 20 | class Indent; 21 | } // namespace webm_tools 22 | 23 | namespace webm_dash { 24 | 25 | class AdaptationSet; 26 | 27 | class Period { 28 | public: 29 | explicit Period(const std::string& id); 30 | ~Period(); 31 | 32 | // Calculates max duration. 33 | bool Init(); 34 | 35 | // Add the AdaptationSet ids that will be contained within the Period. 36 | void AddAdaptationSetID(const std::string& id); 37 | 38 | // Returns the number of AdaptationSet ids. 39 | int AdaptationSetIDSize() const; 40 | 41 | // Returns AdaptationSet |id| referenced by |index|. Returns true if |id| is 42 | // assigned. 43 | bool AdaptationSetID(unsigned int index, std::string* id) const; 44 | 45 | // Adds a AdaptationSet that is controlled by another object. 46 | void AddAdaptationSet(const AdaptationSet* as); 47 | 48 | // Outputs AdaptationSet in the prototype format. 49 | void OutputDashManifest(FILE* o, webm_tools::Indent* indent) const; 50 | 51 | double duration() const { return duration_; } 52 | void set_duration(double duration) { duration_ = duration; } 53 | 54 | std::string id() const { return id_; } 55 | void set_id(const std::string& id) { id_ = id; } 56 | 57 | double start() const { return start_; } 58 | void set_start(double start) { start_ = start; } 59 | 60 | private: 61 | // Maximum duration of all |adaptation_sets_|. 62 | double duration_; 63 | 64 | // Used to differentiate between different Period within a MPD. 65 | std::string id_; 66 | 67 | // Start time in seconds for all of the AdaptationSets within this Period. 68 | double start_; 69 | 70 | // List of AdaptationSets for this Period. 71 | std::vector adaptation_sets_; 72 | 73 | std::vector adaptation_set_ids_; 74 | 75 | WEBM_TOOLS_DISALLOW_COPY_AND_ASSIGN(Period); 76 | }; 77 | 78 | } // namespace webm_dash 79 | 80 | #endif // WEBM_DASH_MANIFEST_PERIOD_H_ 81 | -------------------------------------------------------------------------------- /webm_dash_manifest/representation.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "representation.h" 12 | 13 | #include "mkvparser/mkvreader.h" 14 | 15 | #include "dash_model.h" 16 | #include "indent.h" 17 | #include "webm_constants.h" 18 | #include "webm_file.h" 19 | 20 | using std::string; 21 | using webm_tools::Indent; 22 | using webm_tools::int64; 23 | using webm_tools::kNanosecondsPerSecond; 24 | using webm_tools::WebMFile; 25 | 26 | namespace webm_dash { 27 | 28 | Representation::Representation(const string& id, const DashModel& dash) 29 | : dash_model_(dash), 30 | id_(id), 31 | output_audio_sample_rate_(true), 32 | output_header_(true), 33 | output_index_(true), 34 | output_video_height_(true), 35 | output_video_width_(true), 36 | webm_file_(NULL), 37 | webm_filename_() { 38 | } 39 | 40 | Representation::~Representation() { 41 | } 42 | 43 | bool Representation::SetWebMFile() { 44 | if (webm_filename_.empty()) { 45 | fprintf(stderr, "WebM filename is empty.\n"); 46 | return false; 47 | } 48 | 49 | webm_file_ = dash_model_.FindWebMFile(webm_filename_); 50 | if (!webm_file_) { 51 | fprintf(stderr, "Could not find WebM file:%s\n", webm_filename_.c_str()); 52 | return false; 53 | } 54 | 55 | return true; 56 | } 57 | 58 | bool Representation::BitstreamSwitching( 59 | const Representation& representation) const { 60 | const WebMFile* const webm = representation.webm_file(); 61 | if (!webm) { 62 | fprintf(stderr, "WebM file is NULL.\n"); 63 | return false; 64 | } 65 | 66 | if (!webm_file_) { 67 | fprintf(stderr, "WebM file is NULL.\n"); 68 | return false; 69 | } 70 | 71 | return webm_file_->CheckBitstreamSwitching(*webm); 72 | } 73 | 74 | bool Representation::CheckCuesAlignment( 75 | const Representation& representation) const { 76 | const WebMFile* const webm = representation.webm_file(); 77 | if (!webm) { 78 | fprintf(stderr, "WebM file is NULL.\n"); 79 | return false; 80 | } 81 | 82 | if (!webm_file_) { 83 | fprintf(stderr, "WebM file is NULL.\n"); 84 | return false; 85 | } 86 | 87 | return webm_file_->CheckCuesAlignment(*webm); 88 | } 89 | 90 | int Representation::GetAudioSampleRate() const { 91 | return webm_file_->AudioSampleRate(); 92 | } 93 | 94 | double Representation::GetVideoFramerate() const { 95 | return webm_file_->VideoFramerate(); 96 | } 97 | 98 | int Representation::GetVideoHeight() const { 99 | return webm_file_->VideoHeight(); 100 | } 101 | 102 | int Representation::GetVideoWidth() const { 103 | return webm_file_->VideoWidth(); 104 | } 105 | 106 | bool Representation::OutputDashManifest(FILE* o, Indent* indent) const { 107 | indent->Adjust(webm_tools::kIncreaseIndent); 108 | fprintf(o, "%sindent_str().c_str(), 109 | id_.c_str()); 110 | 111 | const int64 prebuffer_ns = 112 | static_cast(dash_model_.min_buffer_time() * 113 | kNanosecondsPerSecond); 114 | fprintf(o, " bandwidth=\"%lld\"", 115 | webm_file_->PeakBitsPerSecondOverFile(prebuffer_ns)); 116 | 117 | // Video 118 | if (output_video_width_) { 119 | const int width = webm_file_->VideoWidth(); 120 | if (width > 0) { 121 | fprintf(o, " width=\"%d\"", width); 122 | } 123 | } 124 | if (output_video_height_) { 125 | const int height = webm_file_->VideoHeight(); 126 | if (height > 0) { 127 | fprintf(o, " height=\"%d\"", height); 128 | } 129 | } 130 | 131 | // TODO(fgalligan): webm_file_->CalculateVideoFrameRate can take a relatively 132 | // long time as it must go through every block in the file. For now only 133 | // output the framerate if the FrameRate element is set in the file. This 134 | // will most likely need to change later. 135 | const double rate = webm_file_->VideoFramerate(); 136 | if (rate > 0.0) { 137 | fprintf(o, " framerate=\"%g\"", rate); 138 | } 139 | 140 | if (output_audio_sample_rate_) { 141 | const int sample_rate = webm_file_->AudioSampleRate(); 142 | if (sample_rate > 0) { 143 | fprintf(o, " audioSamplingRate=\"%d\"", sample_rate); 144 | } 145 | } 146 | fprintf(o, ">\n"); 147 | 148 | indent->Adjust(webm_tools::kIncreaseIndent); 149 | fprintf(o, "%s%s\n", indent->indent_str().c_str(), 150 | webm_file_->filename().c_str()); 151 | indent->Adjust(webm_tools::kDecreaseIndent); 152 | 153 | const bool b = OutputSegmentBase(o, indent); 154 | if (!b) 155 | return false; 156 | 157 | fprintf(o, "%s\n", indent->indent_str().c_str()); 158 | indent->Adjust(webm_tools::kDecreaseIndent); 159 | 160 | return true; 161 | } 162 | 163 | bool Representation::SubsegmentStartsWithSAP() const { 164 | if (!webm_file_) { 165 | fprintf(stderr, "WebM file is NULL.\n"); 166 | return false; 167 | } 168 | 169 | return webm_file_->CuesFirstInCluster(WebMFile::kUnknown); 170 | } 171 | 172 | bool Representation::OutputSegmentBase(FILE* o, Indent* indent) const { 173 | if (!output_header_ && !output_index_) 174 | return true; 175 | if (!webm_file_) 176 | return true; 177 | 178 | indent->Adjust(webm_tools::kIncreaseIndent); 179 | fprintf(o, "%sindent_str().c_str()); 180 | 181 | if (output_index_) { 182 | if (!webm_file_->CheckForCues()) 183 | return false; 184 | 185 | // Output the entire Cues element. 186 | const mkvparser::Cues* const cues = webm_file_->GetCues(); 187 | const int64 start = cues->m_element_start; 188 | const int64 end = start + cues->m_element_size; 189 | 190 | // Range is based off RFC 2616. All byte positions are inclusive. 191 | fprintf(o, " indexRange=\"%lld-%lld\"", start, end - 1); 192 | } 193 | 194 | if (output_header_) { 195 | fprintf(o, ">\n"); 196 | 197 | int64 start; 198 | int64 end; 199 | webm_file_->GetHeaderRange(&start, &end); 200 | 201 | indent->Adjust(webm_tools::kIncreaseIndent); 202 | fprintf(o, "%sindent_str().c_str()); 203 | 204 | // Range is based off RFC 2616. All byte positions are inclusive. 205 | fprintf(o, " range=\"%lld-%lld\" />\n", start, end - 1); 206 | indent->Adjust(webm_tools::kDecreaseIndent); 207 | 208 | fprintf(o, "%s\n", indent->indent_str().c_str()); 209 | } else { 210 | fprintf(o, " />\n"); 211 | } 212 | indent->Adjust(webm_tools::kDecreaseIndent); 213 | 214 | return true; 215 | } 216 | 217 | } // namespace webm_dash 218 | -------------------------------------------------------------------------------- /webm_dash_manifest/representation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef WEBM_DASH_MANIFEST_REPRESENTATION_H_ 12 | #define WEBM_DASH_MANIFEST_REPRESENTATION_H_ 13 | 14 | #include 15 | #include 16 | 17 | #include "webm_tools_types.h" 18 | 19 | namespace webm_tools { 20 | class Indent; 21 | class WebMFile; 22 | } // namespace webm_tools 23 | 24 | namespace mkvparser { 25 | class AudioTrack; 26 | class Cues; 27 | struct EBMLHeader; 28 | class MkvReader; 29 | class Segment; 30 | class Track; 31 | class VideoTrack; 32 | } // namespace mkvparser 33 | 34 | namespace webm_dash { 35 | 36 | class DashModel; 37 | 38 | class Representation { 39 | public: 40 | Representation(const std::string& id, const DashModel& dash); 41 | ~Representation(); 42 | 43 | // Finds the WebM file from the dash model. Returns true if the file has 44 | // been found and set. 45 | bool SetWebMFile(); 46 | 47 | // Returns true if the TrackNumber, CodecID, and CodecPrivate values match 48 | // the values in |representation|. 49 | bool BitstreamSwitching(const Representation& representation) const; 50 | 51 | // Returns true if the start time and the block number of all the cue 52 | // points in the representation are equal to all of the cue points in 53 | // |representation|. 54 | bool CheckCuesAlignment(const Representation& representation) const; 55 | 56 | // Returns the sample rate in the first audio track. Returns 0 if there is 57 | // no audio track. 58 | int GetAudioSampleRate() const; 59 | 60 | // Returns the average framerate of the first video track. Returns 0.0 if 61 | // there is no video track or there is no FrameRate element. 62 | double GetVideoFramerate() const; 63 | 64 | // Returns the height in pixels of the first video track. Returns 0 if there 65 | // is no video track. 66 | int GetVideoHeight() const; 67 | 68 | // Returns the width in pixels of the first video track. Returns 0 if there 69 | // is no video track. 70 | int GetVideoWidth() const; 71 | 72 | // Outputs Representation in the Dash format. Returns true if there were no 73 | // errors with the output. 74 | bool OutputDashManifest(FILE* o, webm_tools::Indent* indent) const; 75 | 76 | // Check all the subsegments within the Representation to see if they 77 | // conform to the subsegmentStartsWithSAP attribute. 78 | bool SubsegmentStartsWithSAP() const; 79 | 80 | std::string id() const { return id_; } 81 | void set_id(const std::string& id) { id_ = id; } 82 | 83 | void set_output_audio_sample_rate(bool output) { 84 | output_audio_sample_rate_ = output; 85 | } 86 | 87 | bool output_header() const { return output_header_; } 88 | void set_output_header(bool output) { output_header_ = output; } 89 | 90 | bool output_index() const { return output_index_; } 91 | void set_output_index(bool output) { output_index_ = output; } 92 | 93 | void set_output_video_height(bool output) { output_video_height_ = output; } 94 | 95 | void set_output_video_width(bool output) { output_video_width_ = output; } 96 | 97 | const webm_tools::WebMFile* webm_file() const { return webm_file_; } 98 | 99 | std::string webm_filename() const { return webm_filename_; } 100 | void set_webm_filename(const std::string& file) { webm_filename_ = file; } 101 | 102 | private: 103 | // Outputs SegmentBase in the Dash format. Returns true if there were no 104 | // errors with the output. 105 | bool OutputSegmentBase(FILE* o, webm_tools::Indent* indent) const; 106 | 107 | // The main class for the manifest. 108 | const DashModel& dash_model_; 109 | 110 | // TODO(fgalligan): Add code to make sure id is unique within the Period. 111 | // Used to differentiate between different representation within an 112 | // adaptation set. 113 | std::string id_; 114 | 115 | // Flag telling if the class should output audio sample rate. 116 | bool output_audio_sample_rate_; 117 | 118 | // Flag telling if the class should output the header information. 119 | bool output_header_; 120 | 121 | // Flag telling if the class should output the header information. 122 | bool output_index_; 123 | 124 | // Flag telling if the class should output video height. 125 | bool output_video_height_; 126 | 127 | // Flag telling if the class should output video width. 128 | bool output_video_width_; 129 | 130 | // WebM file. This class does not own the pointer. 131 | const webm_tools::WebMFile* webm_file_; 132 | 133 | // Path to WebM file. 134 | std::string webm_filename_; 135 | 136 | WEBM_TOOLS_DISALLOW_COPY_AND_ASSIGN(Representation); 137 | }; 138 | 139 | } // namespace webm_dash 140 | 141 | #endif // WEBM_DASH_MANIFEST_REPRESENTATION_H_ 142 | -------------------------------------------------------------------------------- /webm_dash_manifest/webm_dash_manifest.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "adaptation_set.h" 17 | #include "dash_model.h" 18 | #include "period.h" 19 | #include "representation.h" 20 | 21 | using std::string; 22 | using webm_dash::DashModel; 23 | using webm_dash::AdaptationSet; 24 | using webm_dash::Period; 25 | using webm_dash::Representation; 26 | 27 | static const char VERSION_STRING[] = "1.0.3.0"; 28 | 29 | static void Usage() { 30 | printf("Usage: webm_dash_manifest [-o output_file] [-p options] "); 31 | printf("<-as [as options] <-r [r options]>... >...\n"); 32 | printf("\n"); 33 | printf("Main options:\n"); 34 | printf("-h | -? show help\n"); 35 | printf("-v show version\n"); 36 | printf("-url [...] Base URL list\n"); 37 | printf("-profile Set profile.\n"); 38 | printf("\n"); 39 | printf("Period (-p) options:\n"); 40 | printf("-duration duration in seconds\n"); 41 | printf("-id id of the Period\n"); 42 | printf("-start start time in seconds\n"); 43 | printf("\n"); 44 | printf("AdaptationSet (-as) options:\n"); 45 | printf("-id id of the AdaptationSet\n"); 46 | printf("-lang lang of the AdaptationSet\n"); 47 | printf("\n"); 48 | printf("Representation (-r) options:\n"); 49 | printf("-id id of the Media\n"); 50 | printf("-file Input file\n"); 51 | printf("\n"); 52 | } 53 | 54 | static bool ParseOption(const string& option, string* name, string* value) { 55 | if (!name || !value) 56 | return false; 57 | 58 | const size_t equal_sign = option.find_first_of('='); 59 | if (equal_sign == string::npos) 60 | return false; 61 | 62 | *name = option.substr(0, equal_sign); 63 | *value = option.substr(equal_sign + 1, string::npos); 64 | return true; 65 | } 66 | 67 | static void ParseAdaptationSetOptions(const string& option_list, 68 | AdaptationSet* as) { 69 | size_t start = 0; 70 | size_t end = option_list.find_first_of(','); 71 | for (;;) { 72 | const string option = option_list.substr(start, end - start); 73 | string name; 74 | string value; 75 | if (ParseOption(option, &name, &value)) { 76 | if (name == "id") { 77 | as->set_id(value); 78 | } else if (name == "lang") { 79 | as->set_lang(value); 80 | } 81 | } 82 | 83 | if (end == string::npos) 84 | break; 85 | start = end + 1; 86 | end = option_list.find_first_of(',', start); 87 | } 88 | } 89 | 90 | static double StringToDouble(const std::string& s) { 91 | return strtod(s.c_str(), NULL); 92 | } 93 | 94 | static void ParsePeriodOptions(const string& option_list, Period* period) { 95 | size_t start = 0; 96 | size_t end = option_list.find_first_of(','); 97 | for (;;) { 98 | const string option = option_list.substr(start, end - start); 99 | string name; 100 | string value; 101 | if (ParseOption(option, &name, &value)) { 102 | if (name == "id") { 103 | period->set_id(value); 104 | } else if (name == "duration") { 105 | period->set_duration(StringToDouble(value)); 106 | } else if (name == "start") { 107 | period->set_start(StringToDouble(value)); 108 | } 109 | } 110 | 111 | if (end == string::npos) 112 | break; 113 | start = end + 1; 114 | end = option_list.find_first_of(',', start); 115 | } 116 | } 117 | 118 | static void ParseRepresentationOptions(const string& option_list, 119 | DashModel* model, 120 | Representation* r) { 121 | size_t start = 0; 122 | size_t end = option_list.find_first_of(','); 123 | for (;;) { 124 | const string option = option_list.substr(start, end - start); 125 | string name; 126 | string value; 127 | if (ParseOption(option, &name, &value)) { 128 | if (name == "id") { 129 | r->set_id(value); 130 | } else if (name == "file") { 131 | model->AppendInputFile(value); 132 | r->set_webm_filename(value); 133 | } 134 | } 135 | 136 | if (end == string::npos) 137 | break; 138 | start = end + 1; 139 | end = option_list.find_first_of(',', start); 140 | } 141 | } 142 | 143 | static bool ParseMainCommandLine(int argc, 144 | char* argv[], 145 | DashModel* model) { 146 | if (argc < 2) { 147 | Usage(); 148 | return false; 149 | } 150 | 151 | if (!model) { 152 | fprintf(stderr, "model parameter is NULL.\n"); 153 | return EXIT_FAILURE; 154 | } 155 | 156 | const int argc_check = argc - 1; 157 | for (int i = 1; i < argc; ++i) { 158 | if (!strcmp("-p", argv[i]) && i < argc_check) { 159 | model->AddPeriod(); 160 | Period* const p = model->CurrentPeriod(); 161 | const string option_list(argv[++i]); 162 | ParsePeriodOptions(option_list, p); 163 | } else if (!strcmp("-as", argv[i]) && i < argc_check) { 164 | model->AddAdaptationSet(); 165 | AdaptationSet* const as = model->CurrentAdaptationSet(); 166 | const string option_list(argv[++i]); 167 | ParseAdaptationSetOptions(option_list, as); 168 | } else if (!strcmp("-r", argv[i]) && i < argc_check) { 169 | AdaptationSet* const as = model->CurrentAdaptationSet(); 170 | if (as) { 171 | as->AddRepresentation(); 172 | Representation* const rep = as->CurrentRepresentation(); 173 | const string option_list(argv[++i]); 174 | ParseRepresentationOptions(option_list, model, rep); 175 | } 176 | } else if (!strcmp("-o", argv[i]) && i < argc_check) { 177 | model->set_output_filename(argv[++i]); 178 | } else if (!strcmp("-v", argv[i])) { 179 | printf("version: %s\n", VERSION_STRING); 180 | } else if ( (!strcmp("-h", argv[i])) || (!strcmp("-?", argv[i])) ) { 181 | Usage(); 182 | return false; 183 | } else if (!strcmp("-url", argv[i]) && i < argc_check) { 184 | model->AppendBaseUrl(argv[++i]); 185 | } else if (!strcmp("-profile", argv[i]) && i < argc_check) { 186 | model->set_profile(argv[++i]); 187 | } 188 | } 189 | 190 | return true; 191 | } 192 | 193 | int main(int argc, char* argv[]) { 194 | DashModel model; 195 | 196 | if (!ParseMainCommandLine(argc, argv, &model)) { 197 | return EXIT_FAILURE; 198 | } 199 | 200 | if (!model.Init()) { 201 | fprintf(stderr, "Manifest Model Init() Failed.\n"); 202 | return EXIT_FAILURE; 203 | } 204 | 205 | if (!model.OutputDashManifestFile()) { 206 | fprintf(stderr, "OutputDashManifestFile() Failed.\n"); 207 | return EXIT_FAILURE; 208 | } 209 | 210 | return EXIT_SUCCESS; 211 | } 212 | -------------------------------------------------------------------------------- /webm_dash_manifest/webm_dash_manifest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webm_dash_manifest", "webm_dash_manifest.vcproj", "{7215F679-8138-429F-8FD9-192335C52412}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {7215F679-8138-429F-8FD9-192335C52412}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {7215F679-8138-429F-8FD9-192335C52412}.Debug|Win32.Build.0 = Debug|Win32 14 | {7215F679-8138-429F-8FD9-192335C52412}.Release|Win32.ActiveCfg = Release|Win32 15 | {7215F679-8138-429F-8FD9-192335C52412}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /webm_dash_manifest/webm_dash_manifest.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 27 | 30 | 33 | 36 | 39 | 42 | 55 | 58 | 61 | 64 | 73 | 76 | 79 | 82 | 85 | 88 | 91 | 94 | 95 | 104 | 107 | 110 | 113 | 116 | 119 | 132 | 135 | 138 | 141 | 152 | 155 | 158 | 161 | 164 | 167 | 170 | 173 | 174 | 175 | 176 | 177 | 178 | 183 | 186 | 187 | 190 | 191 | 194 | 195 | 198 | 199 | 202 | 203 | 206 | 207 | 210 | 211 | 214 | 215 | 218 | 219 | 220 | 225 | 228 | 229 | 232 | 233 | 236 | 237 | 240 | 241 | 244 | 245 | 248 | 249 | 252 | 253 | 256 | 257 | 258 | 263 | 264 | 265 | 266 | 267 | 268 | --------------------------------------------------------------------------------