mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 16:14:38 +00:00
Initial commit
added libraries: opus flac libsndfile updated: libvorbis libogg openal - Everything works as expected for now. Bare in mind libsndfile needed the check for whether or not it could find the xiph libraries removed in order for this to work.
This commit is contained in:
parent
05a083ca6f
commit
a745fc3757
1954 changed files with 431332 additions and 21037 deletions
340
Engine/lib/opus/doc/Doxyfile.in
Normal file
340
Engine/lib/opus/doc/Doxyfile.in
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
# Doxyfile 1.8.18
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project.
|
||||
#
|
||||
# All text after a double hash (##) is considered a comment and is placed in
|
||||
# front of the TAG it is preceding.
|
||||
#
|
||||
# All text after a single hash (#) is considered a comment and will be ignored.
|
||||
# The format is:
|
||||
# TAG = value [value, ...]
|
||||
# For lists, items can also be appended using:
|
||||
# TAG += value [value, ...]
|
||||
# Values that contain spaces should be placed between quotes (\" \").
|
||||
|
||||
# Only non-default options are included below to improve portability
|
||||
# between doxygen versions.
|
||||
#
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
|
||||
# double-quotes, unless you are using Doxywizard) that should identify the
|
||||
# project for which the documentation is generated. This name is used in the
|
||||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = Opus
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = @VERSION@
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
# quick idea about the purpose of the project. Keep the description short.
|
||||
|
||||
PROJECT_BRIEF = "Opus audio codec (RFC 6716): API and operations manual"
|
||||
|
||||
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
|
||||
# in the documentation. The maximum height of the logo should not exceed 55
|
||||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
||||
# the logo to the output directory.
|
||||
|
||||
PROJECT_LOGO =
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
|
||||
# before files name in the file list and in the header files. If set to NO the
|
||||
# shortest path that makes the file name unique will be used
|
||||
# The default value is: YES.
|
||||
|
||||
FULL_PATH_NAMES = NO
|
||||
|
||||
# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
|
||||
# first line (until the first dot) of a Javadoc-style comment as the brief
|
||||
# description. If set to NO, the Javadoc-style will behave just like regular Qt-
|
||||
# style comments (thus requiring an explicit @brief command for a brief
|
||||
# description.)
|
||||
# The default value is: NO.
|
||||
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
|
||||
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
|
||||
# uses this value to replace tabs by spaces in code fragments.
|
||||
# Minimum value: 1, maximum value: 16, default value: 4.
|
||||
|
||||
TAB_SIZE = 8
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
# instance, some of the names that are used will be different. The list of all
|
||||
# members will be omitted, etc.
|
||||
# The default value is: NO.
|
||||
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
|
||||
# documentation are documented, even if no documentation was available. Private
|
||||
# class members and static file members will be hidden unless the
|
||||
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
|
||||
# Note: This will also disable the warnings about undocumented members that are
|
||||
# normally produced when WARNINGS is set to YES.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_ALL = YES
|
||||
|
||||
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
|
||||
# be included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_PRIVATE = NO
|
||||
|
||||
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
|
||||
# names in lower-case letters. If set to YES, upper-case letters are also
|
||||
# allowed. This is useful if you have classes or files whose names only differ
|
||||
# in case and if your file system supports case sensitive file names. Windows
|
||||
# (including Cygwin) ands Mac users are advised to set this option to NO.
|
||||
# The default value is: system dependent.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
|
||||
# The ENABLED_SECTIONS tag can be used to enable conditional documentation
|
||||
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
|
||||
# ... \endcond blocks.
|
||||
|
||||
ENABLED_SECTIONS =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The QUIET tag can be used to turn on/off the messages that are generated to
|
||||
# standard output by doxygen. If QUIET is set to YES this implies that the
|
||||
# messages are off.
|
||||
# The default value is: NO.
|
||||
|
||||
QUIET = YES
|
||||
|
||||
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
||||
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
|
||||
# this implies that the warnings are on.
|
||||
#
|
||||
# Tip: Turn warnings on while writing the documentation.
|
||||
# The default value is: YES.
|
||||
|
||||
WARNINGS = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The INPUT tag is used to specify the files and/or directories that contain
|
||||
# documented source files. You may enter file names like myfile.cpp or
|
||||
# directories like /usr/src/myproject. Separate the files or directories with
|
||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = @top_srcdir@/include/opus.h \
|
||||
@top_srcdir@/include/opus_types.h \
|
||||
@top_srcdir@/include/opus_defines.h \
|
||||
@top_srcdir@/include/opus_multistream.h \
|
||||
@top_srcdir@/include/opus_custom.h
|
||||
|
||||
# The EXCLUDE tag can be used to specify files and/or directories that should be
|
||||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||
#
|
||||
# Note that relative paths are relative to the directory from which doxygen is
|
||||
# run.
|
||||
|
||||
EXCLUDE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
|
||||
# compounds will be generated. Enable this if the project contains a lot of
|
||||
# classes, structs, unions or interfaces.
|
||||
# The default value is: YES.
|
||||
|
||||
ALPHABETICAL_INDEX = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
|
||||
# each generated HTML page. If the tag is left blank doxygen will generate a
|
||||
# standard header.
|
||||
#
|
||||
# To get valid HTML the header file that includes any scripts and style sheets
|
||||
# that doxygen needs, which is dependent on the configuration options used (e.g.
|
||||
# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
|
||||
# default header using
|
||||
# doxygen -w html new_header.html new_footer.html new_stylesheet.css
|
||||
# YourConfigFile
|
||||
# and then modify the file new_header.html. See also section "Doxygen usage"
|
||||
# for information on how to generate the default header that doxygen normally
|
||||
# uses.
|
||||
# Note: The header is subject to change so you typically have to regenerate the
|
||||
# default header when upgrading to a newer version of doxygen. For a description
|
||||
# of the possible markers and block names see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_HEADER = @top_srcdir@/doc/header.html
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
||||
# generated HTML page. If the tag is left blank doxygen will generate a standard
|
||||
# footer. See HTML_HEADER for more information on how to generate a default
|
||||
# footer and what special commands can be used inside the footer. See also
|
||||
# section "Doxygen usage" for information on how to generate the default footer
|
||||
# that doxygen normally uses.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FOOTER = @top_srcdir@/doc/footer.html
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
||||
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
||||
# the HTML output. If left blank doxygen will generate a default style sheet.
|
||||
# See also section "Doxygen usage" for information on how to generate the style
|
||||
# sheet that doxygen normally uses.
|
||||
# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
|
||||
# it is more robust and this tag (HTML_STYLESHEET) will in the future become
|
||||
# obsolete.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_STYLESHEET = @top_srcdir@/doc/customdoxygen.css
|
||||
|
||||
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||
# other source files which should be copied to the HTML output directory. Note
|
||||
# that these files will be copied to the base HTML output directory. Use the
|
||||
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
|
||||
# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
|
||||
# files will be copied as-is; there are no commands or markers available.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_FILES = @top_srcdir@/doc/opus_logo.svg
|
||||
|
||||
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
|
||||
# in the HTML output. For a value of 0 the output will use grayscales only. A
|
||||
# value of 255 will produce the most vivid colors.
|
||||
# Minimum value: 0, maximum value: 255, default value: 100.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_COLORSTYLE_SAT = 0
|
||||
|
||||
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
|
||||
# page will contain the date and time when the page was generated. Setting this
|
||||
# to YES can help to show when doxygen was last run and thus if the
|
||||
# documentation is up to date.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_TIMESTAMP = YES
|
||||
|
||||
# When MathJax is enabled you need to specify the location relative to the HTML
|
||||
# output directory using the MATHJAX_RELPATH option. The destination directory
|
||||
# should contain the MathJax.js script. For instance, if the mathjax directory
|
||||
# is located at the same level as the HTML output directory, then
|
||||
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
|
||||
# Content Delivery Network so you can quickly see the result without installing
|
||||
# MathJax. However, it is strongly recommended to install a local copy of
|
||||
# MathJax from https://www.mathjax.org before deployment.
|
||||
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_RELPATH = https://www.mathjax.org/mathjax
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The PAPER_TYPE tag can be used to set the paper type that is used by the
|
||||
# printer.
|
||||
# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
|
||||
# 14 inches) and executive (7.25 x 10.5 inches).
|
||||
# The default value is: a4.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
PAPER_TYPE = letter
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
|
||||
# classes and files.
|
||||
# The default value is: NO.
|
||||
|
||||
GENERATE_MAN = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
|
||||
# in the source code. If set to NO, only conditional compilation will be
|
||||
# performed. Macro expansion can be done in a controlled way by setting
|
||||
# EXPAND_ONLY_PREDEF to YES.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
MACRO_EXPANSION = YES
|
||||
|
||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
|
||||
# the macro expansion is limited to the macros specified with the PREDEFINED and
|
||||
# EXPAND_AS_DEFINED tags.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
|
||||
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||
# contain include files that are not input files but should be processed by the
|
||||
# preprocessor.
|
||||
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
|
||||
|
||||
INCLUDE_PATH =
|
||||
|
||||
# The PREDEFINED tag can be used to specify one or more macro names that are
|
||||
# defined before the preprocessor is started (similar to the -D option of e.g.
|
||||
# gcc). The argument of the tag is a list of macros of the form: name or
|
||||
# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
|
||||
# is assumed. To prevent a macro definition from being undefined via #undef or
|
||||
# recursively expanded use the := operator instead of the = operator.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED = OPUS_EXPORT= \
|
||||
OPUS_CUSTOM_EXPORT= \
|
||||
OPUS_CUSTOM_EXPORT_STATIC= \
|
||||
OPUS_WARN_UNUSED_RESULT= \
|
||||
OPUS_ARG_NONNULL(_x)=
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||
# available from the path. This tool is part of Graphviz (see:
|
||||
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||
# Bell Labs. The other options in this section have no effect if this option is
|
||||
# set to NO
|
||||
# The default value is: NO.
|
||||
|
||||
# Debian defaults to YES here, while Fedora and Homebrew default to NO.
|
||||
# So we set this based on whether the graphviz package is available at
|
||||
# configure time.
|
||||
#
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
|
||||
# move docs to the correct place
|
||||
OUTPUT_DIRECTORY = @top_builddir@/doc
|
||||
45
Engine/lib/opus/doc/Makefile.am
Normal file
45
Engine/lib/opus/doc/Makefile.am
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
DOCINPUTS = $(top_srcdir)/include/opus.h \
|
||||
$(top_srcdir)/include/opus_multistream.h \
|
||||
$(top_srcdir)/include/opus_defines.h \
|
||||
$(top_srcdir)/include/opus_types.h \
|
||||
$(top_srcdir)/include/opus_custom.h \
|
||||
$(top_srcdir)/doc/header.html \
|
||||
$(top_srcdir)/doc/footer.html \
|
||||
$(top_srcdir)/doc/customdoxygen.css
|
||||
|
||||
EXTRA_DIST = customdoxygen.css Doxyfile.in footer.html header.html \
|
||||
opus_logo.svg trivial_example.c
|
||||
|
||||
|
||||
if HAVE_DOXYGEN
|
||||
|
||||
all-local: doxygen-build.stamp
|
||||
|
||||
doxygen-build.stamp: Doxyfile $(DOCINPUTS)
|
||||
doxygen
|
||||
touch $@
|
||||
|
||||
install-data-local:
|
||||
$(INSTALL) -d $(DESTDIR)$(docdir)/html/search
|
||||
for f in `find html -type f \! -name "installdox"`; do \
|
||||
$(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f; \
|
||||
done
|
||||
|
||||
$(INSTALL) -d $(DESTDIR)$(mandir)/man3
|
||||
cd man && find man3 -type f -name opus_*.3 \
|
||||
-exec $(INSTALL_DATA) \{} $(DESTDIR)$(mandir)/man3 \;
|
||||
|
||||
clean-local:
|
||||
$(RM) -r html
|
||||
$(RM) -r latex
|
||||
$(RM) -r man
|
||||
$(RM) doxygen-build.stamp
|
||||
$(RM) doxygen_sqlite3.db
|
||||
|
||||
uninstall-local:
|
||||
$(RM) -r $(DESTDIR)$(docdir)/html
|
||||
$(RM) $(DESTDIR)$(mandir)/man3/opus_*.3 $(DESTDIR)$(mandir)/man3/opus.h.3
|
||||
|
||||
endif
|
||||
113
Engine/lib/opus/doc/build_draft.sh
Normal file
113
Engine/lib/opus/doc/build_draft.sh
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2011-2012 Xiph.Org Foundation and Mozilla Corporation
|
||||
#
|
||||
# This file is extracted from RFC6716. Please see that RFC for additional
|
||||
# information.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# - Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||
# names of specific contributors, may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#Stop on errors
|
||||
set -e
|
||||
#Set the CWD to the location of this script
|
||||
[ -n "${0%/*}" ] && cd "${0%/*}"
|
||||
|
||||
toplevel=".."
|
||||
destdir="opus_source"
|
||||
|
||||
echo packaging source code
|
||||
rm -rf "${destdir}"
|
||||
mkdir "${destdir}"
|
||||
mkdir "${destdir}/src"
|
||||
mkdir "${destdir}/silk"
|
||||
mkdir "${destdir}/silk/float"
|
||||
mkdir "${destdir}/silk/fixed"
|
||||
mkdir "${destdir}/silk/fixed/x86"
|
||||
mkdir "${destdir}/silk/fixed/arm"
|
||||
mkdir "${destdir}/silk/fixed/mips"
|
||||
mkdir "${destdir}/silk/x86"
|
||||
mkdir "${destdir}/silk/arm"
|
||||
mkdir "${destdir}/silk/mips"
|
||||
mkdir "${destdir}/celt"
|
||||
mkdir "${destdir}/celt/x86"
|
||||
mkdir "${destdir}/celt/arm"
|
||||
mkdir "${destdir}/celt/mips"
|
||||
mkdir "${destdir}/include"
|
||||
for f in `cat "${toplevel}"/opus_sources.mk "${toplevel}"/celt_sources.mk \
|
||||
"${toplevel}"/silk_sources.mk "${toplevel}"/opus_headers.mk \
|
||||
"${toplevel}"/celt_headers.mk "${toplevel}"/silk_headers.mk \
|
||||
| grep '\.[ch]' | sed -e 's/^.*=//' -e 's/\\\\//'` ; do
|
||||
cp -a "${toplevel}/${f}" "${destdir}/${f}"
|
||||
done
|
||||
cp -a "${toplevel}"/src/opus_demo.c "${destdir}"/src/
|
||||
cp -a "${toplevel}"/src/opus_compare.c "${destdir}"/src/
|
||||
cp -a "${toplevel}"/celt/opus_custom_demo.c "${destdir}"/celt/
|
||||
cp -a "${toplevel}"/Makefile.unix "${destdir}"/Makefile
|
||||
cp -a "${toplevel}"/opus_sources.mk "${destdir}"/
|
||||
cp -a "${toplevel}"/celt_sources.mk "${destdir}"/
|
||||
cp -a "${toplevel}"/silk_sources.mk "${destdir}"/
|
||||
cp -a "${toplevel}"/README.draft "${destdir}"/README
|
||||
cp -a "${toplevel}"/COPYING "${destdir}"/COPYING
|
||||
cp -a "${toplevel}"/tests/run_vectors.sh "${destdir}"/
|
||||
|
||||
GZIP=-9 tar --owner=root --group=root --format=v7 -czf opus_source.tar.gz "${destdir}"
|
||||
echo building base64 version
|
||||
cat opus_source.tar.gz| base64 | tr -d '\n' | fold -w 64 | \
|
||||
sed -e 's/^/\<spanx style="vbare"\>###/' -e 's/$/\<\/spanx\>\<vspace\/\>/' > \
|
||||
opus_source.base64
|
||||
|
||||
|
||||
#echo '<figure>' > opus_compare_escaped.c
|
||||
#echo '<artwork>' >> opus_compare_escaped.c
|
||||
#echo '<![CDATA[' >> opus_compare_escaped.c
|
||||
#cat opus_compare.c >> opus_compare_escaped.c
|
||||
#echo ']]>' >> opus_compare_escaped.c
|
||||
#echo '</artwork>' >> opus_compare_escaped.c
|
||||
#echo '</figure>' >> opus_compare_escaped.c
|
||||
|
||||
if [ ! -d ../opus_testvectors ] ; then
|
||||
echo "Downloading test vectors..."
|
||||
wget 'http://opus-codec.org/testvectors/opus_testvectors.tar.gz'
|
||||
tar -C .. -xvzf opus_testvectors.tar.gz
|
||||
fi
|
||||
echo '<figure>' > testvectors_sha1
|
||||
echo '<artwork>' >> testvectors_sha1
|
||||
echo '<![CDATA[' >> testvectors_sha1
|
||||
(cd ../opus_testvectors; sha1sum *.bit *.dec) >> testvectors_sha1
|
||||
#cd opus_testvectors
|
||||
#sha1sum *.bit *.dec >> ../testvectors_sha1
|
||||
#cd ..
|
||||
echo ']]>' >> testvectors_sha1
|
||||
echo '</artwork>' >> testvectors_sha1
|
||||
echo '</figure>' >> testvectors_sha1
|
||||
|
||||
echo running xml2rfc
|
||||
xml2rfc draft-ietf-codec-opus.xml draft-ietf-codec-opus.html &
|
||||
xml2rfc draft-ietf-codec-opus.xml
|
||||
wait
|
||||
50
Engine/lib/opus/doc/build_isobmff.sh
Normal file
50
Engine/lib/opus/doc/build_isobmff.sh
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2014 Xiph.Org Foundation and Mozilla Foundation
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# - Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#Stop on errors
|
||||
set -e
|
||||
#Set the CWD to the location of this script
|
||||
[ -n "${0%/*}" ] && cd "${0%/*}"
|
||||
|
||||
HTML=opus_in_isobmff.html
|
||||
|
||||
echo downloading updates...
|
||||
CSS=${HTML%%.html}.css
|
||||
wget -q http://vfrmaniac.fushizen.eu/contents/${HTML} -O ${HTML}
|
||||
wget -q http://vfrmaniac.fushizen.eu/style.css -O ${CSS}
|
||||
|
||||
echo updating links...
|
||||
cat ${HTML} | sed -e "s/\\.\\.\\/style.css/${CSS}/" > ${HTML}+ && mv ${HTML}+ ${HTML}
|
||||
|
||||
echo stripping...
|
||||
cat ${HTML} | sed -e 's/<!--.*-->//g' > ${HTML}+ && mv ${HTML}+ ${HTML}
|
||||
cat ${HTML} | sed -e 's/ *$//g' > ${HTML}+ && mv ${HTML}+ ${HTML}
|
||||
cat ${CSS} | sed -e 's/ *$//g' > ${CSS}+ && mv ${CSS}+ ${CSS}
|
||||
|
||||
|
||||
VERSION=$(fgrep Version ${HTML} | sed 's/.*Version \([0-9]\.[0-9]\.[0-9]\).*/\1/')
|
||||
echo Now at version ${VERSION}
|
||||
52
Engine/lib/opus/doc/build_oggdraft.sh
Normal file
52
Engine/lib/opus/doc/build_oggdraft.sh
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2012 Xiph.Org Foundation and Mozilla Corporation
|
||||
#
|
||||
# This file is extracted from RFC6716. Please see that RFC for additional
|
||||
# information.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# - Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||
# names of specific contributors, may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#Stop on errors
|
||||
set -e
|
||||
#Set the CWD to the location of this script
|
||||
[ -n "${0%/*}" ] && cd "${0%/*}"
|
||||
|
||||
if test -z `which xml2rfc 2> /dev/null`; then
|
||||
echo "Error: couldn't find xml2rfc."
|
||||
echo
|
||||
echo "Please install xml2rfc version 2 or later."
|
||||
echo "E.g. 'pip install xml2rfc' or follow the instructions"
|
||||
echo "on http://pypi.python.org/pypi/xml2rfc/ or tools.ietf.org."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo running xml2rfc
|
||||
# version 2 syntax
|
||||
xml2rfc draft-ietf-codec-oggopus.xml --text --html
|
||||
1011
Engine/lib/opus/doc/customdoxygen.css
Normal file
1011
Engine/lib/opus/doc/customdoxygen.css
Normal file
File diff suppressed because it is too large
Load diff
1873
Engine/lib/opus/doc/draft-ietf-codec-oggopus.xml
Normal file
1873
Engine/lib/opus/doc/draft-ietf-codec-oggopus.xml
Normal file
File diff suppressed because it is too large
Load diff
513
Engine/lib/opus/doc/draft-ietf-codec-opus-update.xml
Normal file
513
Engine/lib/opus/doc/draft-ietf-codec-opus-update.xml
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
|
||||
<?rfc toc="yes"?>
|
||||
<?rfc tocompact="yes"?>
|
||||
<?rfc tocdepth="3"?>
|
||||
<?rfc tocindent="yes"?>
|
||||
<?rfc symrefs="yes"?>
|
||||
<?rfc sortrefs="yes"?>
|
||||
<?rfc comments="yes"?>
|
||||
<?rfc inline="yes"?>
|
||||
<?rfc compact="yes"?>
|
||||
<?rfc subcompact="no"?>
|
||||
<rfc category="std" docName="draft-ietf-codec-opus-update-10"
|
||||
ipr="trust200902" updates="6716">
|
||||
<front>
|
||||
<title abbrev="Opus Update">Updates to the Opus Audio Codec</title>
|
||||
|
||||
<author initials="JM" surname="Valin" fullname="Jean-Marc Valin">
|
||||
<organization>Mozilla Corporation</organization>
|
||||
<address>
|
||||
<postal>
|
||||
<street>331 E. Evelyn Avenue</street>
|
||||
<city>Mountain View</city>
|
||||
<region>CA</region>
|
||||
<code>94041</code>
|
||||
<country>USA</country>
|
||||
</postal>
|
||||
<phone>+1 650 903-0800</phone>
|
||||
<email>jmvalin@jmvalin.ca</email>
|
||||
</address>
|
||||
</author>
|
||||
|
||||
<author initials="K." surname="Vos" fullname="Koen Vos">
|
||||
<organization>vocTone</organization>
|
||||
<address>
|
||||
<postal>
|
||||
<street></street>
|
||||
<city></city>
|
||||
<region></region>
|
||||
<code></code>
|
||||
<country></country>
|
||||
</postal>
|
||||
<phone></phone>
|
||||
<email>koenvos74@gmail.com</email>
|
||||
</address>
|
||||
</author>
|
||||
|
||||
|
||||
|
||||
<date day="24" month="August" year="2017" />
|
||||
|
||||
<abstract>
|
||||
<t>This document addresses minor issues that were found in the specification
|
||||
of the Opus audio codec in RFC 6716. It updates the normative decoder implementation
|
||||
included in the appendix of RFC 6716. The changes fixes real and potential security-related
|
||||
issues, as well minor quality-related issues.</t>
|
||||
</abstract>
|
||||
</front>
|
||||
|
||||
<middle>
|
||||
<section title="Introduction">
|
||||
<t>This document addresses minor issues that were discovered in the reference
|
||||
implementation of the Opus codec. Unlike most IETF specifications, Opus is defined
|
||||
in <xref target="RFC6716">RFC 6716</xref> in terms of a normative reference
|
||||
decoder implementation rather than from the associated text description.
|
||||
That RFC includes the reference decoder implementation as Appendix A.
|
||||
That's why only issues affecting the decoder are
|
||||
listed here. An up-to-date implementation of the Opus encoder can be found at
|
||||
<eref target="https://opus-codec.org/"/>.</t>
|
||||
<t>
|
||||
Some of the changes in this document update normative behaviour in a way that requires
|
||||
new test vectors. The English text of the specification is unaffected, only
|
||||
the C implementation is. The updated specification remains fully compatible with
|
||||
the original specification.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
Note: due to RFC formatting conventions, lines exceeding the column width
|
||||
in the patch are split using a backslash character. The backslashes
|
||||
at the end of a line and the white space at the beginning
|
||||
of the following line are not part of the patch. A properly formatted patch
|
||||
including all changes is available at
|
||||
<eref target="https://www.ietf.org/proceedings/98/slides/materials-98-codec-opus-update-00.patch"/>
|
||||
and has a SHA-1 hash of 029e3aa88fc342c91e67a21e7bfbc9458661cd5f.
|
||||
</t>
|
||||
|
||||
</section>
|
||||
|
||||
<section title="Terminology">
|
||||
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||
document are to be interpreted as described in <xref
|
||||
target="RFC2119">RFC 2119</xref>.</t>
|
||||
</section>
|
||||
|
||||
<section title="Stereo State Reset in SILK">
|
||||
<t>The reference implementation does not reinitialize the stereo state
|
||||
during a mode switch. The old stereo memory can produce a brief impulse
|
||||
(i.e. single sample) in the decoded audio. This can be fixed by changing
|
||||
silk/dec_API.c at line 72:
|
||||
</t>
|
||||
<figure>
|
||||
<artwork><![CDATA[
|
||||
<CODE BEGINS>
|
||||
for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {
|
||||
ret = silk_init_decoder( &channel_state[ n ] );
|
||||
}
|
||||
+ silk_memset(&((silk_decoder *)decState)->sStereo, 0,
|
||||
+ sizeof(((silk_decoder *)decState)->sStereo));
|
||||
+ /* Not strictly needed, but it's cleaner that way */
|
||||
+ ((silk_decoder *)decState)->prev_decode_only_middle = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
<CODE ENDS>
|
||||
]]></artwork>
|
||||
</figure>
|
||||
<t>
|
||||
This change affects the normative output of the decoder, but the
|
||||
amount of change is within the tolerance and too small to make the testvector check fail.
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section anchor="padding" title="Parsing of the Opus Packet Padding">
|
||||
<t>It was discovered that some invalid packets of very large size could trigger
|
||||
an out-of-bounds read in the Opus packet parsing code responsible for padding.
|
||||
This is due to an integer overflow if the signaled padding exceeds 2^31-1 bytes
|
||||
(the actual packet may be smaller). The code can be fixed by decrementing the
|
||||
(signed) len value, instead of incrementing a separate padding counter.
|
||||
This is done by applying the following changes at line 596 of src/opus_decoder.c:
|
||||
</t>
|
||||
<figure>
|
||||
<artwork><![CDATA[
|
||||
<CODE BEGINS>
|
||||
/* Padding flag is bit 6 */
|
||||
if (ch&0x40)
|
||||
{
|
||||
- int padding=0;
|
||||
int p;
|
||||
do {
|
||||
if (len<=0)
|
||||
return OPUS_INVALID_PACKET;
|
||||
p = *data++;
|
||||
len--;
|
||||
- padding += p==255 ? 254: p;
|
||||
+ len -= p==255 ? 254: p;
|
||||
} while (p==255);
|
||||
- len -= padding;
|
||||
}
|
||||
<CODE ENDS>
|
||||
]]></artwork>
|
||||
</figure>
|
||||
<t>This packet parsing issue is limited to reading memory up
|
||||
to about 60 kB beyond the compressed buffer. This can only be triggered
|
||||
by a compressed packet more than about 16 MB long, so it's not a problem
|
||||
for RTP. In theory, it could crash a file
|
||||
decoder (e.g. Opus in Ogg) if the memory just after the incoming packet
|
||||
is out-of-range, but our attempts to trigger such a crash in a production
|
||||
application built using an affected version of the Opus decoder failed.</t>
|
||||
</section>
|
||||
|
||||
<section anchor="resampler" title="Resampler buffer">
|
||||
<t>The SILK resampler had the following issues:
|
||||
<list style="numbers">
|
||||
<t>The calls to memcpy() were using sizeof(opus_int32), but the type of the
|
||||
local buffer was opus_int16.</t>
|
||||
<t>Because the size was wrong, this potentially allowed the source
|
||||
and destination regions of the memcpy() to overlap on the copy from "buf" to "buf".
|
||||
We believe that nSamplesIn (number of input samples) is at least fs_in_khZ (sampling rate in kHz),
|
||||
which is at least 8.
|
||||
Since RESAMPLER_ORDER_FIR_12 is only 8, that should not be a problem once
|
||||
the type size is fixed.</t>
|
||||
<t>The size of the buffer used RESAMPLER_MAX_BATCH_SIZE_IN, but the
|
||||
data stored in it was actually twice the input batch size
|
||||
(nSamplesIn<<1).</t>
|
||||
</list></t>
|
||||
<t>The code can be fixed by applying the following changes to line 78 of silk/resampler_private_IIR_FIR.c:
|
||||
</t>
|
||||
<figure>
|
||||
<artwork><![CDATA[
|
||||
<CODE BEGINS>
|
||||
)
|
||||
{
|
||||
silk_resampler_state_struct *S = \
|
||||
(silk_resampler_state_struct *)SS;
|
||||
opus_int32 nSamplesIn;
|
||||
opus_int32 max_index_Q16, index_increment_Q16;
|
||||
- opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + \
|
||||
RESAMPLER_ORDER_FIR_12 ];
|
||||
+ opus_int16 buf[ 2*RESAMPLER_MAX_BATCH_SIZE_IN + \
|
||||
RESAMPLER_ORDER_FIR_12 ];
|
||||
|
||||
/* Copy buffered samples to start of buffer */
|
||||
- silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 \
|
||||
* sizeof( opus_int32 ) );
|
||||
+ silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 \
|
||||
* sizeof( opus_int16 ) );
|
||||
|
||||
/* Iterate over blocks of frameSizeIn input samples */
|
||||
index_increment_Q16 = S->invRatio_Q16;
|
||||
while( 1 ) {
|
||||
nSamplesIn = silk_min( inLen, S->batchSize );
|
||||
|
||||
/* Upsample 2x */
|
||||
silk_resampler_private_up2_HQ( S->sIIR, &buf[ \
|
||||
RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn );
|
||||
|
||||
max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 \
|
||||
); /* + 1 because 2x upsampling */
|
||||
out = silk_resampler_private_IIR_FIR_INTERPOL( out, \
|
||||
buf, max_index_Q16, index_increment_Q16 );
|
||||
in += nSamplesIn;
|
||||
inLen -= nSamplesIn;
|
||||
|
||||
if( inLen > 0 ) {
|
||||
/* More iterations to do; copy last part of \
|
||||
filtered signal to beginning of buffer */
|
||||
- silk_memcpy( buf, &buf[ nSamplesIn << 1 ], \
|
||||
RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
|
||||
+ silk_memmove( buf, &buf[ nSamplesIn << 1 ], \
|
||||
RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy last part of filtered signal to the state for \
|
||||
the next call */
|
||||
- silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], \
|
||||
RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
|
||||
+ silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], \
|
||||
RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
|
||||
}
|
||||
<CODE ENDS>
|
||||
]]></artwork>
|
||||
</figure>
|
||||
</section>
|
||||
|
||||
<section title="Integer wrap-around in inverse gain computation">
|
||||
<t>
|
||||
It was discovered through decoder fuzzing that some bitstreams could produce
|
||||
integer values exceeding 32-bits in LPC_inverse_pred_gain_QA(), causing
|
||||
a wrap-around. The C standard considers
|
||||
this behavior as undefined. The following patch to line 87 of silk/LPC_inv_pred_gain.c
|
||||
detects values that do not fit in a 32-bit integer and considers the corresponding filters unstable:
|
||||
</t>
|
||||
<figure>
|
||||
<artwork><![CDATA[
|
||||
<CODE BEGINS>
|
||||
/* Update AR coefficient */
|
||||
for( n = 0; n < k; n++ ) {
|
||||
- tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( \
|
||||
Aold_QA[ k - n - 1 ], rc_Q31, 31 );
|
||||
- Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );
|
||||
+ opus_int64 tmp64;
|
||||
+ tmp_QA = silk_SUB_SAT32( Aold_QA[ n ], MUL32_FRAC_Q( \
|
||||
Aold_QA[ k - n - 1 ], rc_Q31, 31 ) );
|
||||
+ tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( tmp_QA, \
|
||||
rc_mult2 ), mult2Q);
|
||||
+ if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ Anew_QA[ n ] = ( opus_int32 )tmp64;
|
||||
}
|
||||
<CODE ENDS>
|
||||
]]></artwork>
|
||||
</figure>
|
||||
</section>
|
||||
|
||||
<section title="Integer wrap-around in LSF decoding" anchor="lsf_overflow">
|
||||
<t>
|
||||
It was discovered -- also from decoder fuzzing -- that an integer wrap-around could
|
||||
occur when decoding bitstreams with extremely large values for the high LSF parameters.
|
||||
The end result of the wrap-around is an illegal read access on the stack, which
|
||||
the authors do not believe is exploitable but should nonetheless be fixed. The following
|
||||
patch to line 137 of silk/NLSF_stabilize.c prevents the problem:
|
||||
</t>
|
||||
<figure>
|
||||
<artwork><![CDATA[
|
||||
<CODE BEGINS>
|
||||
/* Keep delta_min distance between the NLSFs */
|
||||
for( i = 1; i < L; i++ )
|
||||
- NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \
|
||||
NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
|
||||
+ NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \
|
||||
silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
|
||||
|
||||
/* Last NLSF should be no higher than 1 - NDeltaMin[L] */
|
||||
<CODE ENDS>
|
||||
]]></artwork>
|
||||
</figure>
|
||||
|
||||
</section>
|
||||
|
||||
<section title="Cap on Band Energy">
|
||||
<t>On extreme bit-streams, it is possible for log-domain band energy levels
|
||||
to exceed the maximum single-precision floating point value once converted
|
||||
to a linear scale. This would later cause the decoded values to be NaN (not a number),
|
||||
possibly causing problems in the software using the PCM values. This can be
|
||||
avoided with the following patch to line 552 of celt/quant_bands.c:
|
||||
</t>
|
||||
<figure>
|
||||
<artwork><![CDATA[
|
||||
<CODE BEGINS>
|
||||
{
|
||||
opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
|
||||
SHL16((opus_val16)eMeans[i],6));
|
||||
+ lg = MIN32(QCONST32(32.f, 16), lg);
|
||||
eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
|
||||
}
|
||||
for (;i<m->nbEBands;i++)
|
||||
<CODE ENDS>
|
||||
]]></artwork>
|
||||
</figure>
|
||||
</section>
|
||||
|
||||
<section title="Hybrid Folding" anchor="folding">
|
||||
<t>When encoding in hybrid mode at low bitrate, we sometimes only have
|
||||
enough bits to code a single CELT band (8 - 9.6 kHz). When that happens,
|
||||
the second band (CELT band 18, from 9.6 to 12 kHz) cannot use folding
|
||||
because it is wider than the amount already coded, and falls back to
|
||||
white noise. Because it can also happen on transients (e.g. stops), it
|
||||
can cause audible pre-echo.
|
||||
</t>
|
||||
<t>
|
||||
To address the issue, we change the folding behavior so that it is
|
||||
never forced to fall back to LCG due to the first band not containing
|
||||
enough coefficients to fold onto the second band. This
|
||||
is achieved by simply repeating part of the first band in the folding
|
||||
of the second band. This changes the code in celt/bands.c around line 1237:
|
||||
</t>
|
||||
<figure>
|
||||
<artwork><![CDATA[
|
||||
<CODE BEGINS>
|
||||
b = 0;
|
||||
}
|
||||
|
||||
- if (resynth && M*eBands[i]-N >= M*eBands[start] && \
|
||||
(update_lowband || lowband_offset==0))
|
||||
+ if (resynth && (M*eBands[i]-N >= M*eBands[start] || \
|
||||
i==start+1) && (update_lowband || lowband_offset==0))
|
||||
lowband_offset = i;
|
||||
|
||||
+ if (i == start+1)
|
||||
+ {
|
||||
+ int n1, n2;
|
||||
+ int offset;
|
||||
+ n1 = M*(eBands[start+1]-eBands[start]);
|
||||
+ n2 = M*(eBands[start+2]-eBands[start+1]);
|
||||
+ offset = M*eBands[start];
|
||||
+ /* Duplicate enough of the first band folding data to \
|
||||
be able to fold the second band.
|
||||
+ Copies no data for CELT-only mode. */
|
||||
+ OPUS_COPY(&norm[offset+n1], &norm[offset+2*n1 - n2], n2-n1);
|
||||
+ if (C==2)
|
||||
+ OPUS_COPY(&norm2[offset+n1], &norm2[offset+2*n1 - n2], \
|
||||
n2-n1);
|
||||
+ }
|
||||
+
|
||||
tf_change = tf_res[i];
|
||||
if (i>=m->effEBands)
|
||||
{
|
||||
<CODE ENDS>
|
||||
]]></artwork>
|
||||
</figure>
|
||||
|
||||
<t>
|
||||
as well as line 1260:
|
||||
</t>
|
||||
|
||||
<figure>
|
||||
<artwork><![CDATA[
|
||||
<CODE BEGINS>
|
||||
fold_start = lowband_offset;
|
||||
while(M*eBands[--fold_start] > effective_lowband);
|
||||
fold_end = lowband_offset-1;
|
||||
- while(M*eBands[++fold_end] < effective_lowband+N);
|
||||
+ while(++fold_end < i && M*eBands[fold_end] < \
|
||||
effective_lowband+N);
|
||||
x_cm = y_cm = 0;
|
||||
fold_i = fold_start; do {
|
||||
x_cm |= collapse_masks[fold_i*C+0];
|
||||
|
||||
<CODE ENDS>
|
||||
]]></artwork>
|
||||
</figure>
|
||||
<t>
|
||||
The fix does not impact compatibility, because the improvement does
|
||||
not depend on the encoder doing anything special. There is also no
|
||||
reasonable way for an encoder to use the original behavior to
|
||||
improve quality over the proposed change.
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section title="Downmix to Mono" anchor="stereo">
|
||||
<t>The last issue is not strictly a bug, but it is an issue that has been reported
|
||||
when downmixing an Opus decoded stream to mono, whether this is done inside the decoder
|
||||
or as a post-processing step on the stereo decoder output. Opus intensity stereo allows
|
||||
optionally coding the two channels 180-degrees out of phase on a per-band basis.
|
||||
This provides better stereo quality than forcing the two channels to be in phase,
|
||||
but when the output is downmixed to mono, the energy in the affected bands is cancelled
|
||||
sometimes resulting in audible artifacts.
|
||||
</t>
|
||||
<t>As a work-around for this issue, the decoder MAY choose not to apply the 180-degree
|
||||
phase shift. This can be useful when downmixing to mono inside or
|
||||
outside of the decoder (e.g. user-controllable).
|
||||
</t>
|
||||
</section>
|
||||
|
||||
|
||||
<section title="New Test Vectors">
|
||||
<t>Changes in <xref target="folding"/> and <xref target="stereo"/> have
|
||||
sufficient impact on the testvectors to make them fail. For this reason,
|
||||
this document also updates the Opus test vectors. The new test vectors now
|
||||
include two decoded outputs for the same bitstream. The outputs with
|
||||
suffix 'm' do not apply the CELT 180-degree phase shift as allowed in
|
||||
<xref target="stereo"/>, while the outputs without the suffix do. An
|
||||
implementation is compliant as long as it passes either set of vectors.
|
||||
</t>
|
||||
<t>
|
||||
Any Opus implementation
|
||||
that passes either the original test vectors from <xref target="RFC6716">RFC 6716</xref>
|
||||
or one of the new sets of test vectors is compliant with the Opus specification. However, newer implementations
|
||||
SHOULD be based on the new test vectors rather than the old ones.
|
||||
</t>
|
||||
<t>The new test vectors are located at
|
||||
<eref target="https://www.ietf.org/proceedings/98/slides/materials-98-codec-opus-newvectors-00.tar.gz"/>.
|
||||
The SHA-1 hashes of the test vectors are:
|
||||
<figure>
|
||||
<artwork>
|
||||
<![CDATA[
|
||||
e49b2862ceec7324790ed8019eb9744596d5be01 testvector01.bit
|
||||
b809795ae1bcd606049d76de4ad24236257135e0 testvector02.bit
|
||||
e0c4ecaeab44d35a2f5b6575cd996848e5ee2acc testvector03.bit
|
||||
a0f870cbe14ebb71fa9066ef3ee96e59c9a75187 testvector04.bit
|
||||
9b3d92b48b965dfe9edf7b8a85edd4309f8cf7c8 testvector05.bit
|
||||
28e66769ab17e17f72875283c14b19690cbc4e57 testvector06.bit
|
||||
bacf467be3215fc7ec288f29e2477de1192947a6 testvector07.bit
|
||||
ddbe08b688bbf934071f3893cd0030ce48dba12f testvector08.bit
|
||||
3932d9d61944dab1201645b8eeaad595d5705ecb testvector09.bit
|
||||
521eb2a1e0cc9c31b8b740673307c2d3b10c1900 testvector10.bit
|
||||
6bc8f3146fcb96450c901b16c3d464ccdf4d5d96 testvector11.bit
|
||||
338c3f1b4b97226bc60bc41038becbc6de06b28f testvector12.bit
|
||||
f5ef93884da6a814d311027918e9afc6f2e5c2c8 testvector01.dec
|
||||
48ac1ff1995250a756e1e17bd32acefa8cd2b820 testvector02.dec
|
||||
d15567e919db2d0e818727092c0af8dd9df23c95 testvector03.dec
|
||||
1249dd28f5bd1e39a66fd6d99449dca7a8316342 testvector04.dec
|
||||
b85675d81deef84a112c466cdff3b7aaa1d2fc76 testvector05.dec
|
||||
55f0b191e90bfa6f98b50d01a64b44255cb4813e testvector06.dec
|
||||
61e8b357ab090b1801eeb578a28a6ae935e25b7b testvector07.dec
|
||||
a58539ee5321453b2ddf4c0f2500e856b3966862 testvector08.dec
|
||||
bb96aad2cde188555862b7bbb3af6133851ef8f4 testvector09.dec
|
||||
1b6cdf0413ac9965b16184b1bea129b5c0b2a37a testvector10.dec
|
||||
b1fff72b74666e3027801b29dbc48b31f80dee0d testvector11.dec
|
||||
98e09bbafed329e341c3b4052e9c4ba5fc83f9b1 testvector12.dec
|
||||
1e7d984ea3fbb16ba998aea761f4893fbdb30157 testvector01m.dec
|
||||
48ac1ff1995250a756e1e17bd32acefa8cd2b820 testvector02m.dec
|
||||
d15567e919db2d0e818727092c0af8dd9df23c95 testvector03m.dec
|
||||
1249dd28f5bd1e39a66fd6d99449dca7a8316342 testvector04m.dec
|
||||
d70b0bad431e7d463bc3da49bd2d49f1c6d0a530 testvector05m.dec
|
||||
6ac1648c3174c95fada565161a6c78bdbe59c77d testvector06m.dec
|
||||
fc5e2f709693738324fb4c8bdc0dad6dda04e713 testvector07m.dec
|
||||
aad2ba397bf1b6a18e8e09b50e4b19627d479f00 testvector08m.dec
|
||||
6feb7a7b9d7cdc1383baf8d5739e2a514bd0ba08 testvector09m.dec
|
||||
1b6cdf0413ac9965b16184b1bea129b5c0b2a37a testvector10m.dec
|
||||
fd3d3a7b0dfbdab98d37ed9aa04b659b9fefbd18 testvector11m.dec
|
||||
98e09bbafed329e341c3b4052e9c4ba5fc83f9b1 testvector12m.dec
|
||||
]]>
|
||||
</artwork>
|
||||
</figure>
|
||||
Note that the decoder input bitstream files (.bit) are unchanged.
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section anchor="security" title="Security Considerations">
|
||||
<t>This document fixes two security issues reported on Opus and that affect the
|
||||
reference implementation in <xref target="RFC6716">RFC 6716</xref>: CVE-2013-0899
|
||||
<eref target="https://nvd.nist.gov/vuln/detail/CVE-2013-0899"/>
|
||||
and CVE-2017-0381 <eref target="https://nvd.nist.gov/vuln/detail/CVE-2017-0381"/>.
|
||||
CVE- 2013-0899 theoretically could have caused an information leak. The leaked
|
||||
information would have gone through the decoder process before being accessible
|
||||
to the attacker. It is fixed by <xref target="padding"/>.
|
||||
CVE-2017-0381 could have resulted in a 16-bit out-of-bounds read from a fixed
|
||||
location. It is fixed in <xref target="lsf_overflow"/>.
|
||||
Beyond the two fixed CVEs, this document adds no new security considerations on top of
|
||||
<xref target="RFC6716">RFC 6716</xref>.
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section anchor="IANA" title="IANA Considerations">
|
||||
<t>This document makes no request of IANA.</t>
|
||||
|
||||
<t>Note to RFC Editor: this section may be removed on publication as an
|
||||
RFC.</t>
|
||||
</section>
|
||||
|
||||
<section anchor="Acknowledgements" title="Acknowledgements">
|
||||
<t>We would like to thank Juri Aedla for reporting the issue with the parsing of
|
||||
the Opus padding. Thanks to Felicia Lim for reporting the LSF integer overflow issue.
|
||||
Also, thanks to Tina le Grand, Jonathan Lennox, and Mark Harris for their
|
||||
feedback on this document.</t>
|
||||
</section>
|
||||
</middle>
|
||||
|
||||
<back>
|
||||
<references title="Normative References">
|
||||
<?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"?>
|
||||
<?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.6716.xml"?>
|
||||
|
||||
|
||||
</references>
|
||||
</back>
|
||||
</rfc>
|
||||
8276
Engine/lib/opus/doc/draft-ietf-codec-opus.xml
Normal file
8276
Engine/lib/opus/doc/draft-ietf-codec-opus.xml
Normal file
File diff suppressed because it is too large
Load diff
960
Engine/lib/opus/doc/draft-ietf-payload-rtp-opus.xml
Normal file
960
Engine/lib/opus/doc/draft-ietf-payload-rtp-opus.xml
Normal file
|
|
@ -0,0 +1,960 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
|
||||
<!ENTITY rfc2119 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml'>
|
||||
<!ENTITY rfc3389 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3389.xml'>
|
||||
<!ENTITY rfc3550 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3550.xml'>
|
||||
<!ENTITY rfc3711 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3711.xml'>
|
||||
<!ENTITY rfc3551 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3551.xml'>
|
||||
<!ENTITY rfc6838 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.6838.xml'>
|
||||
<!ENTITY rfc4855 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4855.xml'>
|
||||
<!ENTITY rfc4566 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4566.xml'>
|
||||
<!ENTITY rfc4585 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4585.xml'>
|
||||
<!ENTITY rfc3264 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3264.xml'>
|
||||
<!ENTITY rfc2974 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2974.xml'>
|
||||
<!ENTITY rfc2326 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2326.xml'>
|
||||
<!ENTITY rfc3555 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3555.xml'>
|
||||
<!ENTITY rfc5124 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.5124.xml'>
|
||||
<!ENTITY rfc5405 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.5405.xml'>
|
||||
<!ENTITY rfc5576 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.5576.xml'>
|
||||
<!ENTITY rfc6562 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.6562.xml'>
|
||||
<!ENTITY rfc6716 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.6716.xml'>
|
||||
<!ENTITY rfc7202 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.7202.xml'>
|
||||
<!ENTITY nbsp " ">
|
||||
]>
|
||||
|
||||
<rfc category="std" ipr="trust200902" docName="draft-ietf-payload-rtp-opus-11">
|
||||
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
|
||||
|
||||
<?rfc strict="yes" ?>
|
||||
<?rfc toc="yes" ?>
|
||||
<?rfc tocdepth="3" ?>
|
||||
<?rfc tocappendix='no' ?>
|
||||
<?rfc tocindent='yes' ?>
|
||||
<?rfc symrefs="yes" ?>
|
||||
<?rfc sortrefs="yes" ?>
|
||||
<?rfc compact="no" ?>
|
||||
<?rfc subcompact="yes" ?>
|
||||
<?rfc iprnotified="yes" ?>
|
||||
|
||||
<front>
|
||||
<title abbrev="RTP Payload Format for Opus">
|
||||
RTP Payload Format for the Opus Speech and Audio Codec
|
||||
</title>
|
||||
|
||||
<author fullname="Julian Spittka" initials="J." surname="Spittka">
|
||||
<address>
|
||||
<email>jspittka@gmail.com</email>
|
||||
</address>
|
||||
</author>
|
||||
|
||||
<author initials='K.' surname='Vos' fullname='Koen Vos'>
|
||||
<organization>vocTone</organization>
|
||||
<address>
|
||||
<postal>
|
||||
<street></street>
|
||||
<code></code>
|
||||
<city></city>
|
||||
<region></region>
|
||||
<country></country>
|
||||
</postal>
|
||||
<email>koenvos74@gmail.com</email>
|
||||
</address>
|
||||
</author>
|
||||
|
||||
<author initials="JM" surname="Valin" fullname="Jean-Marc Valin">
|
||||
<organization>Mozilla</organization>
|
||||
<address>
|
||||
<postal>
|
||||
<street>331 E. Evelyn Avenue</street>
|
||||
<city>Mountain View</city>
|
||||
<region>CA</region>
|
||||
<code>94041</code>
|
||||
<country>USA</country>
|
||||
</postal>
|
||||
<email>jmvalin@jmvalin.ca</email>
|
||||
</address>
|
||||
</author>
|
||||
|
||||
<date day='14' month='April' year='2015' />
|
||||
|
||||
<abstract>
|
||||
<t>
|
||||
This document defines the Real-time Transport Protocol (RTP) payload
|
||||
format for packetization of Opus encoded
|
||||
speech and audio data necessary to integrate the codec in the
|
||||
most compatible way. It also provides an applicability statement
|
||||
for the use of Opus over RTP. Further, it describes media type registrations
|
||||
for the RTP payload format.
|
||||
</t>
|
||||
</abstract>
|
||||
</front>
|
||||
|
||||
<middle>
|
||||
<section title='Introduction'>
|
||||
<t>
|
||||
Opus <xref target="RFC6716"/> is a speech and audio codec developed within the
|
||||
IETF Internet Wideband Audio Codec working group. The codec
|
||||
has a very low algorithmic delay and it
|
||||
is highly scalable in terms of audio bandwidth, bitrate, and
|
||||
complexity. Further, it provides different modes to efficiently encode speech signals
|
||||
as well as music signals, thus making it the codec of choice for
|
||||
various applications using the Internet or similar networks.
|
||||
</t>
|
||||
<t>
|
||||
This document defines the Real-time Transport Protocol (RTP)
|
||||
<xref target="RFC3550"/> payload format for packetization
|
||||
of Opus encoded speech and audio data necessary to
|
||||
integrate Opus in the
|
||||
most compatible way. It also provides an applicability statement
|
||||
for the use of Opus over RTP.
|
||||
Further, it describes media type registrations for
|
||||
the RTP payload format.
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section title='Conventions, Definitions and Acronyms used in this document'>
|
||||
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||
document are to be interpreted as described in <xref target="RFC2119"/>.</t>
|
||||
<t>
|
||||
<list style='hanging'>
|
||||
<t hangText="audio bandwidth:"> The range of audio frequecies being coded</t>
|
||||
<t hangText="CBR:"> Constant bitrate</t>
|
||||
<t hangText="CPU:"> Central Processing Unit</t>
|
||||
<t hangText="DTX:"> Discontinuous transmission</t>
|
||||
<t hangText="FEC:"> Forward error correction</t>
|
||||
<t hangText="IP:"> Internet Protocol</t>
|
||||
<t hangText="samples:"> Speech or audio samples (per channel)</t>
|
||||
<t hangText="SDP:"> Session Description Protocol</t>
|
||||
<t hangText="VBR:"> Variable bitrate</t>
|
||||
</list>
|
||||
</t>
|
||||
<t>
|
||||
Throughout this document, we refer to the following definitions:
|
||||
</t>
|
||||
<texttable anchor='bandwidth_definitions'>
|
||||
<ttcol align='center'>Abbreviation</ttcol>
|
||||
<ttcol align='center'>Name</ttcol>
|
||||
<ttcol align='center'>Audio Bandwidth (Hz)</ttcol>
|
||||
<ttcol align='center'>Sampling Rate (Hz)</ttcol>
|
||||
<c>NB</c>
|
||||
<c>Narrowband</c>
|
||||
<c>0 - 4000</c>
|
||||
<c>8000</c>
|
||||
|
||||
<c>MB</c>
|
||||
<c>Mediumband</c>
|
||||
<c>0 - 6000</c>
|
||||
<c>12000</c>
|
||||
|
||||
<c>WB</c>
|
||||
<c>Wideband</c>
|
||||
<c>0 - 8000</c>
|
||||
<c>16000</c>
|
||||
|
||||
<c>SWB</c>
|
||||
<c>Super-wideband</c>
|
||||
<c>0 - 12000</c>
|
||||
<c>24000</c>
|
||||
|
||||
<c>FB</c>
|
||||
<c>Fullband</c>
|
||||
<c>0 - 20000</c>
|
||||
<c>48000</c>
|
||||
|
||||
<postamble>
|
||||
Audio bandwidth naming
|
||||
</postamble>
|
||||
</texttable>
|
||||
</section>
|
||||
|
||||
<section title='Opus Codec'>
|
||||
<t>
|
||||
Opus encodes speech
|
||||
signals as well as general audio signals. Two different modes can be
|
||||
chosen, a voice mode or an audio mode, to allow the most efficient coding
|
||||
depending on the type of the input signal, the sampling frequency of the
|
||||
input signal, and the intended application.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
The voice mode allows efficient encoding of voice signals at lower bit
|
||||
rates while the audio mode is optimized for general audio signals at medium and
|
||||
higher bitrates.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
Opus is highly scalable in terms of audio
|
||||
bandwidth, bitrate, and complexity. Further, Opus allows
|
||||
transmitting stereo signals with in-band signaling in the bit-stream.
|
||||
</t>
|
||||
|
||||
<section title='Network Bandwidth'>
|
||||
<t>
|
||||
Opus supports bitrates from 6 kb/s to 510 kb/s.
|
||||
The bitrate can be changed dynamically within that range.
|
||||
All
|
||||
other parameters being
|
||||
equal, higher bitrates result in higher audio quality.
|
||||
</t>
|
||||
<section title='Recommended Bitrate' anchor='bitrate_by_bandwidth'>
|
||||
<t>
|
||||
For a frame size of
|
||||
20 ms, these
|
||||
are the bitrate "sweet spots" for Opus in various configurations:
|
||||
|
||||
<list style="symbols">
|
||||
<t>8-12 kb/s for NB speech,</t>
|
||||
<t>16-20 kb/s for WB speech,</t>
|
||||
<t>28-40 kb/s for FB speech,</t>
|
||||
<t>48-64 kb/s for FB mono music, and</t>
|
||||
<t>64-128 kb/s for FB stereo music.</t>
|
||||
</list>
|
||||
</t>
|
||||
</section>
|
||||
<section title='Variable versus Constant Bitrate' anchor='variable-vs-constant-bitrate'>
|
||||
<t>
|
||||
For the same average bitrate, variable bitrate (VBR) can achieve higher audio quality
|
||||
than constant bitrate (CBR). For the majority of voice transmission applications, VBR
|
||||
is the best choice. One reason for choosing CBR is the potential
|
||||
information leak that <spanx style='emph'>might</spanx> occur when encrypting the
|
||||
compressed stream. See <xref target="RFC6562"/> for guidelines on when VBR is
|
||||
appropriate for encrypted audio communications. In the case where an existing
|
||||
VBR stream needs to be converted to CBR for security reasons, then the Opus padding
|
||||
mechanism described in <xref target="RFC6716"/> is the RECOMMENDED way to achieve padding
|
||||
because the RTP padding bit is unencrypted.</t>
|
||||
|
||||
<t>
|
||||
The bitrate can be adjusted at any point in time. To avoid congestion,
|
||||
the average bitrate SHOULD NOT exceed the available
|
||||
network bandwidth. If no target bitrate is specified, the bitrates specified in
|
||||
<xref target='bitrate_by_bandwidth'/> are RECOMMENDED.
|
||||
</t>
|
||||
|
||||
</section>
|
||||
|
||||
<section title='Discontinuous Transmission (DTX)'>
|
||||
|
||||
<t>
|
||||
Opus can, as described in <xref target='variable-vs-constant-bitrate'/>,
|
||||
be operated with a variable bitrate. In that case, the encoder will
|
||||
automatically reduce the bitrate for certain input signals, like periods
|
||||
of silence. When using continuous transmission, it will reduce the
|
||||
bitrate when the characteristics of the input signal permit, but
|
||||
will never interrupt the transmission to the receiver. Therefore, the
|
||||
received signal will maintain the same high level of audio quality over the
|
||||
full duration of a transmission while minimizing the average bit
|
||||
rate over time.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
In cases where the bitrate of Opus needs to be reduced even
|
||||
further or in cases where only constant bitrate is available,
|
||||
the Opus encoder can use discontinuous
|
||||
transmission (DTX), where parts of the encoded signal that
|
||||
correspond to periods of silence in the input speech or audio signal
|
||||
are not transmitted to the receiver. A receiver can distinguish
|
||||
between DTX and packet loss by looking for gaps in the sequence
|
||||
number, as described by Section 4.1
|
||||
of <xref target="RFC3551"/>.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
On the receiving side, the non-transmitted parts will be handled by a
|
||||
frame loss concealment unit in the Opus decoder which generates a
|
||||
comfort noise signal to replace the non transmitted parts of the
|
||||
speech or audio signal. Use of <xref target="RFC3389"/> Comfort
|
||||
Noise (CN) with Opus is discouraged.
|
||||
The transmitter MUST drop whole frames only,
|
||||
based on the size of the last transmitted frame,
|
||||
to ensure successive RTP timestamps differ by a multiple of 120 and
|
||||
to allow the receiver to use whole frames for concealment.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
DTX can be used with both variable and constant bitrate.
|
||||
It will have a slightly lower speech or audio
|
||||
quality than continuous transmission. Therefore, using continuous
|
||||
transmission is RECOMMENDED unless constraints on available network bandwidth
|
||||
are severe.
|
||||
</t>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section title='Complexity'>
|
||||
|
||||
<t>
|
||||
Complexity of the encoder can be scaled to optimize for CPU resources in real-time, mostly as
|
||||
a trade-off between audio quality and bitrate. Also, different modes of Opus have different complexity.
|
||||
</t>
|
||||
|
||||
</section>
|
||||
|
||||
<section title="Forward Error Correction (FEC)">
|
||||
|
||||
<t>
|
||||
The voice mode of Opus allows for embedding "in-band" forward error correction (FEC)
|
||||
data into the Opus bit stream. This FEC scheme adds
|
||||
redundant information about the previous packet (N-1) to the current
|
||||
output packet N. For
|
||||
each frame, the encoder decides whether to use FEC based on (1) an
|
||||
externally-provided estimate of the channel's packet loss rate; (2) an
|
||||
externally-provided estimate of the channel's capacity; (3) the
|
||||
sensitivity of the audio or speech signal to packet loss; (4) whether
|
||||
the receiving decoder has indicated it can take advantage of "in-band"
|
||||
FEC information. The decision to send "in-band" FEC information is
|
||||
entirely controlled by the encoder and therefore no special precautions
|
||||
for the payload have to be taken.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
On the receiving side, the decoder can take advantage of this
|
||||
additional information when it loses a packet and the next packet
|
||||
is available. In order to use the FEC data, the jitter buffer needs
|
||||
to provide access to payloads with the FEC data.
|
||||
Instead of performing loss concealment for a missing packet, the
|
||||
receiver can then configure its decoder to decode the FEC data from the next packet.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
Any compliant Opus decoder is capable of ignoring
|
||||
FEC information when it is not needed, so encoding with FEC cannot cause
|
||||
interoperability problems.
|
||||
However, if FEC cannot be used on the receiving side, then FEC
|
||||
SHOULD NOT be used, as it leads to an inefficient usage of network
|
||||
resources. Decoder support for FEC SHOULD be indicated at the time a
|
||||
session is set up.
|
||||
</t>
|
||||
|
||||
</section>
|
||||
|
||||
<section title='Stereo Operation'>
|
||||
|
||||
<t>
|
||||
Opus allows for transmission of stereo audio signals. This operation
|
||||
is signaled in-band in the Opus bit-stream and no special arrangement
|
||||
is needed in the payload format. An
|
||||
Opus decoder is capable of handling a stereo encoding, but an
|
||||
application might only be capable of consuming a single audio
|
||||
channel.
|
||||
</t>
|
||||
<t>
|
||||
If a decoder cannot take advantage of the benefits of a stereo signal
|
||||
this SHOULD be indicated at the time a session is set up. In that case
|
||||
the sending side SHOULD NOT send stereo signals as it leads to an
|
||||
inefficient usage of network resources.
|
||||
</t>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section title='Opus RTP Payload Format' anchor='opus-rtp-payload-format'>
|
||||
<t>The payload format for Opus consists of the RTP header and Opus payload
|
||||
data.</t>
|
||||
<section title='RTP Header Usage'>
|
||||
<t>The format of the RTP header is specified in <xref target="RFC3550"/>.
|
||||
The use of the fields of the RTP header by the Opus payload format is
|
||||
consistent with that specification.</t>
|
||||
|
||||
<t>The payload length of Opus is an integer number of octets and
|
||||
therefore no padding is necessary. The payload MAY be padded by an
|
||||
integer number of octets according to <xref target="RFC3550"/>,
|
||||
although the Opus internal padding is preferred.</t>
|
||||
|
||||
<t>The timestamp, sequence number, and marker bit (M) of the RTP header
|
||||
are used in accordance with Section 4.1
|
||||
of <xref target="RFC3551"/>.</t>
|
||||
|
||||
<t>The RTP payload type for Opus is to be assigned dynamically.</t>
|
||||
|
||||
<t>The receiving side MUST be prepared to receive duplicate RTP
|
||||
packets. The receiver MUST provide at most one of those payloads to the
|
||||
Opus decoder for decoding, and MUST discard the others.</t>
|
||||
|
||||
<t>Opus supports 5 different audio bandwidths, which can be adjusted during
|
||||
a stream.
|
||||
The RTP timestamp is incremented with a 48000 Hz clock rate
|
||||
for all modes of Opus and all sampling rates.
|
||||
The unit
|
||||
for the timestamp is samples per single (mono) channel. The RTP timestamp corresponds to the
|
||||
sample time of the first encoded sample in the encoded frame.
|
||||
For data encoded with sampling rates other than 48000 Hz,
|
||||
the sampling rate has to be adjusted to 48000 Hz.</t>
|
||||
|
||||
</section>
|
||||
|
||||
<section title='Payload Structure'>
|
||||
<t>
|
||||
The Opus encoder can output encoded frames representing 2.5, 5, 10, 20,
|
||||
40, or 60 ms of speech or audio data. Further, an arbitrary number of frames can be
|
||||
combined into a packet, up to a maximum packet duration representing
|
||||
120 ms of speech or audio data. The grouping of one or more Opus
|
||||
frames into a single Opus packet is defined in Section 3 of
|
||||
<xref target="RFC6716"/>. An RTP payload MUST contain exactly one
|
||||
Opus packet as defined by that document.
|
||||
</t>
|
||||
|
||||
<t><xref target='payload-structure'/> shows the structure combined with the RTP header.</t>
|
||||
|
||||
<figure anchor="payload-structure"
|
||||
title="Packet structure with RTP header">
|
||||
<artwork align="center">
|
||||
<![CDATA[
|
||||
+----------+--------------+
|
||||
|RTP Header| Opus Payload |
|
||||
+----------+--------------+
|
||||
]]>
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>
|
||||
<xref target='opus-packetization'/> shows supported frame sizes in
|
||||
milliseconds of encoded speech or audio data for the speech and audio modes
|
||||
(Mode) and sampling rates (fs) of Opus and shows how the timestamp is
|
||||
incremented for packetization (ts incr). If the Opus encoder
|
||||
outputs multiple encoded frames into a single packet, the timestamp
|
||||
increment is the sum of the increments for the individual frames.
|
||||
</t>
|
||||
|
||||
<texttable anchor='opus-packetization' title="Supported Opus frame
|
||||
sizes and timestamp increments marked with an o. Unsupported marked with an x.">
|
||||
<ttcol align='center'>Mode</ttcol>
|
||||
<ttcol align='center'>fs</ttcol>
|
||||
<ttcol align='center'>2.5</ttcol>
|
||||
<ttcol align='center'>5</ttcol>
|
||||
<ttcol align='center'>10</ttcol>
|
||||
<ttcol align='center'>20</ttcol>
|
||||
<ttcol align='center'>40</ttcol>
|
||||
<ttcol align='center'>60</ttcol>
|
||||
<c>ts incr</c>
|
||||
<c>all</c>
|
||||
<c>120</c>
|
||||
<c>240</c>
|
||||
<c>480</c>
|
||||
<c>960</c>
|
||||
<c>1920</c>
|
||||
<c>2880</c>
|
||||
<c>voice</c>
|
||||
<c>NB/MB/WB/SWB/FB</c>
|
||||
<c>x</c>
|
||||
<c>x</c>
|
||||
<c>o</c>
|
||||
<c>o</c>
|
||||
<c>o</c>
|
||||
<c>o</c>
|
||||
<c>audio</c>
|
||||
<c>NB/WB/SWB/FB</c>
|
||||
<c>o</c>
|
||||
<c>o</c>
|
||||
<c>o</c>
|
||||
<c>o</c>
|
||||
<c>x</c>
|
||||
<c>x</c>
|
||||
</texttable>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section title='Congestion Control'>
|
||||
|
||||
<t>The target bitrate of Opus can be adjusted at any point in time, thus
|
||||
allowing efficient congestion control. Furthermore, the amount
|
||||
of encoded speech or audio data encoded in a
|
||||
single packet can be used for congestion control, since the transmission
|
||||
rate is inversely proportional to the packet duration. A lower packet
|
||||
transmission rate reduces the amount of header overhead, but at the same
|
||||
time increases latency and loss sensitivity, so it ought to be used with
|
||||
care.</t>
|
||||
|
||||
<t>Since UDP does not provide congestion control, applications that use
|
||||
RTP over UDP SHOULD implement their own congestion control above the
|
||||
UDP layer <xref target="RFC5405"/>. Work in the rmcat working group
|
||||
<xref target="rmcat"/> describes the
|
||||
interactions and conceptual interfaces necessary between the application
|
||||
components that relate to congestion control, including the RTP layer,
|
||||
the higher-level media codec control layer, and the lower-level
|
||||
transport interface, as well as components dedicated to congestion
|
||||
control functions.</t>
|
||||
</section>
|
||||
|
||||
<section title='IANA Considerations'>
|
||||
<t>One media subtype (audio/opus) has been defined and registered as
|
||||
described in the following section.</t>
|
||||
|
||||
<section title='Opus Media Type Registration'>
|
||||
<t>Media type registration is done according to <xref
|
||||
target="RFC6838"/> and <xref target="RFC4855"/>.<vspace
|
||||
blankLines='1'/></t>
|
||||
|
||||
<t>Type name: audio<vspace blankLines='1'/></t>
|
||||
<t>Subtype name: opus<vspace blankLines='1'/></t>
|
||||
|
||||
<t>Required parameters:</t>
|
||||
<t><list style="hanging">
|
||||
<t hangText="rate:"> the RTP timestamp is incremented with a
|
||||
48000 Hz clock rate for all modes of Opus and all sampling
|
||||
rates. For data encoded with sampling rates other than 48000 Hz,
|
||||
the sampling rate has to be adjusted to 48000 Hz.
|
||||
</t>
|
||||
</list></t>
|
||||
|
||||
<t>Optional parameters:</t>
|
||||
|
||||
<t><list style="hanging">
|
||||
<t hangText="maxplaybackrate:">
|
||||
a hint about the maximum output sampling rate that the receiver is
|
||||
capable of rendering in Hz.
|
||||
The decoder MUST be capable of decoding
|
||||
any audio bandwidth but due to hardware limitations only signals
|
||||
up to the specified sampling rate can be played back. Sending signals
|
||||
with higher audio bandwidth results in higher than necessary network
|
||||
usage and encoding complexity, so an encoder SHOULD NOT encode
|
||||
frequencies above the audio bandwidth specified by maxplaybackrate.
|
||||
This parameter can take any value between 8000 and 48000, although
|
||||
commonly the value will match one of the Opus bandwidths
|
||||
(<xref target="bandwidth_definitions"/>).
|
||||
By default, the receiver is assumed to have no limitations, i.e. 48000.
|
||||
<vspace blankLines='1'/>
|
||||
</t>
|
||||
|
||||
<t hangText="sprop-maxcapturerate:">
|
||||
a hint about the maximum input sampling rate that the sender is likely to produce.
|
||||
This is not a guarantee that the sender will never send any higher bandwidth
|
||||
(e.g. it could send a pre-recorded prompt that uses a higher bandwidth), but it
|
||||
indicates to the receiver that frequencies above this maximum can safely be discarded.
|
||||
This parameter is useful to avoid wasting receiver resources by operating the audio
|
||||
processing pipeline (e.g. echo cancellation) at a higher rate than necessary.
|
||||
This parameter can take any value between 8000 and 48000, although
|
||||
commonly the value will match one of the Opus bandwidths
|
||||
(<xref target="bandwidth_definitions"/>).
|
||||
By default, the sender is assumed to have no limitations, i.e. 48000.
|
||||
<vspace blankLines='1'/>
|
||||
</t>
|
||||
|
||||
<t hangText="maxptime:"> the maximum duration of media represented
|
||||
by a packet (according to Section 6 of
|
||||
<xref target="RFC4566"/>) that a decoder wants to receive, in
|
||||
milliseconds rounded up to the next full integer value.
|
||||
Possible values are 3, 5, 10, 20, 40, 60, or an arbitrary
|
||||
multiple of an Opus frame size rounded up to the next full integer
|
||||
value, up to a maximum value of 120, as
|
||||
defined in <xref target='opus-rtp-payload-format'/>. If no value is
|
||||
specified, the default is 120.
|
||||
<vspace blankLines='1'/></t>
|
||||
|
||||
<t hangText="ptime:"> the preferred duration of media represented
|
||||
by a packet (according to Section 6 of
|
||||
<xref target="RFC4566"/>) that a decoder wants to receive, in
|
||||
milliseconds rounded up to the next full integer value.
|
||||
Possible values are 3, 5, 10, 20, 40, 60, or an arbitrary
|
||||
multiple of an Opus frame size rounded up to the next full integer
|
||||
value, up to a maximum value of 120, as defined in <xref
|
||||
target='opus-rtp-payload-format'/>. If no value is
|
||||
specified, the default is 20.
|
||||
<vspace blankLines='1'/></t>
|
||||
|
||||
<t hangText="maxaveragebitrate:"> specifies the maximum average
|
||||
receive bitrate of a session in bits per second (b/s). The actual
|
||||
value of the bitrate can vary, as it is dependent on the
|
||||
characteristics of the media in a packet. Note that the maximum
|
||||
average bitrate MAY be modified dynamically during a session. Any
|
||||
positive integer is allowed, but values outside the range
|
||||
6000 to 510000 SHOULD be ignored. If no value is specified, the
|
||||
maximum value specified in <xref target='bitrate_by_bandwidth'/>
|
||||
for the corresponding mode of Opus and corresponding maxplaybackrate
|
||||
is the default.<vspace blankLines='1'/></t>
|
||||
|
||||
<t hangText="stereo:">
|
||||
specifies whether the decoder prefers receiving stereo or mono signals.
|
||||
Possible values are 1 and 0 where 1 specifies that stereo signals are preferred,
|
||||
and 0 specifies that only mono signals are preferred.
|
||||
Independent of the stereo parameter every receiver MUST be able to receive and
|
||||
decode stereo signals but sending stereo signals to a receiver that signaled a
|
||||
preference for mono signals may result in higher than necessary network
|
||||
utilization and encoding complexity. If no value is specified,
|
||||
the default is 0 (mono).<vspace blankLines='1'/>
|
||||
</t>
|
||||
|
||||
<t hangText="sprop-stereo:">
|
||||
specifies whether the sender is likely to produce stereo audio.
|
||||
Possible values are 1 and 0, where 1 specifies that stereo signals are likely to
|
||||
be sent, and 0 specifies that the sender will likely only send mono.
|
||||
This is not a guarantee that the sender will never send stereo audio
|
||||
(e.g. it could send a pre-recorded prompt that uses stereo), but it
|
||||
indicates to the receiver that the received signal can be safely downmixed to mono.
|
||||
This parameter is useful to avoid wasting receiver resources by operating the audio
|
||||
processing pipeline (e.g. echo cancellation) in stereo when not necessary.
|
||||
If no value is specified, the default is 0
|
||||
(mono).<vspace blankLines='1'/>
|
||||
</t>
|
||||
|
||||
<t hangText="cbr:">
|
||||
specifies if the decoder prefers the use of a constant bitrate versus
|
||||
variable bitrate. Possible values are 1 and 0, where 1 specifies constant
|
||||
bitrate and 0 specifies variable bitrate. If no value is specified,
|
||||
the default is 0 (vbr). When cbr is 1, the maximum average bitrate can still
|
||||
change, e.g. to adapt to changing network conditions.<vspace blankLines='1'/>
|
||||
</t>
|
||||
|
||||
<t hangText="useinbandfec:"> specifies that the decoder has the capability to
|
||||
take advantage of the Opus in-band FEC. Possible values are 1 and 0.
|
||||
Providing 0 when FEC cannot be used on the receiving side is
|
||||
RECOMMENDED. If no
|
||||
value is specified, useinbandfec is assumed to be 0.
|
||||
This parameter is only a preference and the receiver MUST be able to process
|
||||
packets that include FEC information, even if it means the FEC part is discarded.
|
||||
<vspace blankLines='1'/></t>
|
||||
|
||||
<t hangText="usedtx:"> specifies if the decoder prefers the use of
|
||||
DTX. Possible values are 1 and 0. If no value is specified, the
|
||||
default is 0.<vspace blankLines='1'/></t>
|
||||
</list></t>
|
||||
|
||||
<t>Encoding considerations:<vspace blankLines='1'/></t>
|
||||
<t><list style="hanging">
|
||||
<t>The Opus media type is framed and consists of binary data according
|
||||
to Section 4.8 in <xref target="RFC6838"/>.</t>
|
||||
</list></t>
|
||||
|
||||
<t>Security considerations: </t>
|
||||
<t><list style="hanging">
|
||||
<t>See <xref target='security-considerations'/> of this document.</t>
|
||||
</list></t>
|
||||
|
||||
<t>Interoperability considerations: none<vspace blankLines='1'/></t>
|
||||
<t>Published specification: RFC [XXXX]</t>
|
||||
<t>Note to the RFC Editor: Replace [XXXX] with the number of the published
|
||||
RFC.<vspace blankLines='1'/></t>
|
||||
|
||||
<t>Applications that use this media type: </t>
|
||||
<t><list style="hanging">
|
||||
<t>Any application that requires the transport of
|
||||
speech or audio data can use this media type. Some examples are,
|
||||
but not limited to, audio and video conferencing, Voice over IP,
|
||||
media streaming.</t>
|
||||
</list></t>
|
||||
|
||||
<t>Fragment identifier considerations: N/A<vspace blankLines='1'/></t>
|
||||
|
||||
<t>Person & email address to contact for further information:</t>
|
||||
<t><list style="hanging">
|
||||
<t>SILK Support silksupport@skype.net</t>
|
||||
<t>Jean-Marc Valin jmvalin@jmvalin.ca</t>
|
||||
</list></t>
|
||||
|
||||
<t>Intended usage: COMMON<vspace blankLines='1'/></t>
|
||||
|
||||
<t>Restrictions on usage:<vspace blankLines='1'/></t>
|
||||
|
||||
<t><list style="hanging">
|
||||
<t>For transfer over RTP, the RTP payload format (<xref
|
||||
target='opus-rtp-payload-format'/> of this document) SHALL be
|
||||
used.</t>
|
||||
</list></t>
|
||||
|
||||
<t>Author:</t>
|
||||
<t><list style="hanging">
|
||||
<t>Julian Spittka jspittka@gmail.com<vspace blankLines='1'/></t>
|
||||
<t>Koen Vos koenvos74@gmail.com<vspace blankLines='1'/></t>
|
||||
<t>Jean-Marc Valin jmvalin@jmvalin.ca<vspace blankLines='1'/></t>
|
||||
</list></t>
|
||||
|
||||
<t> Change controller: IETF Payload Working Group delegated from the IESG</t>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section title='SDP Considerations'>
|
||||
<t>The information described in the media type specification has a
|
||||
specific mapping to fields in the Session Description Protocol (SDP)
|
||||
<xref target="RFC4566"/>, which is commonly used to describe RTP
|
||||
sessions. When SDP is used to specify sessions employing Opus,
|
||||
the mapping is as follows:</t>
|
||||
|
||||
<t>
|
||||
<list style="symbols">
|
||||
<t>The media type ("audio") goes in SDP "m=" as the media name.</t>
|
||||
|
||||
<t>The media subtype ("opus") goes in SDP "a=rtpmap" as the encoding
|
||||
name. The RTP clock rate in "a=rtpmap" MUST be 48000 and the number of
|
||||
channels MUST be 2.</t>
|
||||
|
||||
<t>The OPTIONAL media type parameters "ptime" and "maxptime" are
|
||||
mapped to "a=ptime" and "a=maxptime" attributes, respectively, in the
|
||||
SDP.</t>
|
||||
|
||||
<t>The OPTIONAL media type parameters "maxaveragebitrate",
|
||||
"maxplaybackrate", "stereo", "cbr", "useinbandfec", and
|
||||
"usedtx", when present, MUST be included in the "a=fmtp" attribute
|
||||
in the SDP, expressed as a media type string in the form of a
|
||||
semicolon-separated list of parameter=value pairs (e.g.,
|
||||
maxplaybackrate=48000). They MUST NOT be specified in an
|
||||
SSRC-specific "fmtp" source-level attribute (as defined in
|
||||
Section 6.3 of <xref target="RFC5576"/>).</t>
|
||||
|
||||
<t>The OPTIONAL media type parameters "sprop-maxcapturerate",
|
||||
and "sprop-stereo" MAY be mapped to the "a=fmtp" SDP attribute by
|
||||
copying them directly from the media type parameter string as part
|
||||
of the semicolon-separated list of parameter=value pairs (e.g.,
|
||||
sprop-stereo=1). These same OPTIONAL media type parameters MAY also
|
||||
be specified using an SSRC-specific "fmtp" source-level attribute
|
||||
as described in Section 6.3 of <xref target="RFC5576"/>.
|
||||
They MAY be specified in both places, in which case the parameter
|
||||
in the source-level attribute overrides the one found on the
|
||||
"a=fmtp" line. The value of any parameter which is not specified in
|
||||
a source-level source attribute MUST be taken from the "a=fmtp"
|
||||
line, if it is present there.</t>
|
||||
|
||||
</list>
|
||||
</t>
|
||||
|
||||
<t>Below are some examples of SDP session descriptions for Opus:</t>
|
||||
|
||||
<t>Example 1: Standard mono session with 48000 Hz clock rate</t>
|
||||
<figure>
|
||||
<artwork>
|
||||
<![CDATA[
|
||||
m=audio 54312 RTP/AVP 101
|
||||
a=rtpmap:101 opus/48000/2
|
||||
]]>
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
|
||||
<t>Example 2: 16000 Hz clock rate, maximum packet size of 40 ms,
|
||||
recommended packet size of 40 ms, maximum average bitrate of 20000 bps,
|
||||
prefers to receive stereo but only plans to send mono, FEC is desired,
|
||||
DTX is not desired</t>
|
||||
|
||||
<figure>
|
||||
<artwork>
|
||||
<![CDATA[
|
||||
m=audio 54312 RTP/AVP 101
|
||||
a=rtpmap:101 opus/48000/2
|
||||
a=fmtp:101 maxplaybackrate=16000; sprop-maxcapturerate=16000;
|
||||
maxaveragebitrate=20000; stereo=1; useinbandfec=1; usedtx=0
|
||||
a=ptime:40
|
||||
a=maxptime:40
|
||||
]]>
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>Example 3: Two-way full-band stereo preferred</t>
|
||||
|
||||
<figure>
|
||||
<artwork>
|
||||
<![CDATA[
|
||||
m=audio 54312 RTP/AVP 101
|
||||
a=rtpmap:101 opus/48000/2
|
||||
a=fmtp:101 stereo=1; sprop-stereo=1
|
||||
]]>
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
|
||||
<section title='SDP Offer/Answer Considerations'>
|
||||
|
||||
<t>When using the offer-answer procedure described in <xref
|
||||
target="RFC3264"/> to negotiate the use of Opus, the following
|
||||
considerations apply:</t>
|
||||
|
||||
<t><list style="symbols">
|
||||
|
||||
<t>Opus supports several clock rates. For signaling purposes only
|
||||
the highest, i.e. 48000, is used. The actual clock rate of the
|
||||
corresponding media is signaled inside the payload and is not
|
||||
restricted by this payload format description. The decoder MUST be
|
||||
capable of decoding every received clock rate. An example
|
||||
is shown below:
|
||||
|
||||
<figure>
|
||||
<artwork>
|
||||
<![CDATA[
|
||||
m=audio 54312 RTP/AVP 100
|
||||
a=rtpmap:100 opus/48000/2
|
||||
]]>
|
||||
</artwork>
|
||||
</figure>
|
||||
</t>
|
||||
|
||||
<t>The "ptime" and "maxptime" parameters are unidirectional
|
||||
receive-only parameters and typically will not compromise
|
||||
interoperability; however, some values might cause application
|
||||
performance to suffer. <xref
|
||||
target="RFC3264"/> defines the SDP offer-answer handling of the
|
||||
"ptime" parameter. The "maxptime" parameter MUST be handled in the
|
||||
same way.</t>
|
||||
|
||||
<t>
|
||||
The "maxplaybackrate" parameter is a unidirectional receive-only
|
||||
parameter that reflects limitations of the local receiver. When
|
||||
sending to a single destination, a sender MUST NOT use an audio
|
||||
bandwidth higher than necessary to make full use of audio sampled at
|
||||
a sampling rate of "maxplaybackrate". Gateways or senders that
|
||||
are sending the same encoded audio to multiple destinations
|
||||
SHOULD NOT use an audio bandwidth higher than necessary to
|
||||
represent audio sampled at "maxplaybackrate", as this would lead
|
||||
to inefficient use of network resources.
|
||||
The "maxplaybackrate" parameter does not
|
||||
affect interoperability. Also, this parameter SHOULD NOT be used
|
||||
to adjust the audio bandwidth as a function of the bitrate, as this
|
||||
is the responsibility of the Opus encoder implementation.
|
||||
</t>
|
||||
|
||||
<t>The "maxaveragebitrate" parameter is a unidirectional receive-only
|
||||
parameter that reflects limitations of the local receiver. The sender
|
||||
of the other side MUST NOT send with an average bitrate higher than
|
||||
"maxaveragebitrate" as it might overload the network and/or
|
||||
receiver. The "maxaveragebitrate" parameter typically will not
|
||||
compromise interoperability; however, some values might cause
|
||||
application performance to suffer, and ought to be set with
|
||||
care.</t>
|
||||
|
||||
<t>The "sprop-maxcapturerate" and "sprop-stereo" parameters are
|
||||
unidirectional sender-only parameters that reflect limitations of
|
||||
the sender side.
|
||||
They allow the receiver to set up a reduced-complexity audio
|
||||
processing pipeline if the sender is not planning to use the full
|
||||
range of Opus's capabilities.
|
||||
Neither "sprop-maxcapturerate" nor "sprop-stereo" affect
|
||||
interoperability and the receiver MUST be capable of receiving any signal.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
The "stereo" parameter is a unidirectional receive-only
|
||||
parameter. When sending to a single destination, a sender MUST
|
||||
NOT use stereo when "stereo" is 0. Gateways or senders that are
|
||||
sending the same encoded audio to multiple destinations SHOULD
|
||||
NOT use stereo when "stereo" is 0, as this would lead to
|
||||
inefficient use of network resources. The "stereo" parameter does
|
||||
not affect interoperability.
|
||||
</t>
|
||||
|
||||
<t>
|
||||
The "cbr" parameter is a unidirectional receive-only
|
||||
parameter.
|
||||
</t>
|
||||
|
||||
<t>The "useinbandfec" parameter is a unidirectional receive-only
|
||||
parameter.</t>
|
||||
|
||||
<t>The "usedtx" parameter is a unidirectional receive-only
|
||||
parameter.</t>
|
||||
|
||||
<t>Any unknown parameter in an offer MUST be ignored by the receiver
|
||||
and MUST be removed from the answer.</t>
|
||||
|
||||
</list></t>
|
||||
|
||||
<t>
|
||||
The Opus parameters in an SDP Offer/Answer exchange are completely
|
||||
orthogonal, and there is no relationship between the SDP Offer and
|
||||
the Answer.
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<section title='Declarative SDP Considerations for Opus'>
|
||||
|
||||
<t>For declarative use of SDP such as in Session Announcement Protocol
|
||||
(SAP), <xref target="RFC2974"/>, and RTSP, <xref target="RFC2326"/>, for
|
||||
Opus, the following needs to be considered:</t>
|
||||
|
||||
<t><list style="symbols">
|
||||
|
||||
<t>The values for "maxptime", "ptime", "maxplaybackrate", and
|
||||
"maxaveragebitrate" ought to be selected carefully to ensure that a
|
||||
reasonable performance can be achieved for the participants of a session.</t>
|
||||
|
||||
<t>
|
||||
The values for "maxptime", "ptime", and of the payload
|
||||
format configuration are recommendations by the decoding side to ensure
|
||||
the best performance for the decoder.
|
||||
</t>
|
||||
|
||||
<t>All other parameters of the payload format configuration are declarative
|
||||
and a participant MUST use the configurations that are provided for
|
||||
the session. More than one configuration can be provided if necessary
|
||||
by declaring multiple RTP payload types; however, the number of types
|
||||
ought to be kept small.</t>
|
||||
</list></t>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section title='Security Considerations' anchor='security-considerations'>
|
||||
|
||||
<t>Use of variable bitrate (VBR) is subject to the security considerations in
|
||||
<xref target="RFC6562"/>.</t>
|
||||
|
||||
<t>RTP packets using the payload format defined in this specification
|
||||
are subject to the security considerations discussed in the RTP
|
||||
specification <xref target="RFC3550"/>, and in any applicable RTP profile such as
|
||||
RTP/AVP <xref target="RFC3551"/>, RTP/AVPF <xref target="RFC4585"/>,
|
||||
RTP/SAVP <xref target="RFC3711"/> or RTP/SAVPF <xref target="RFC5124"/>.
|
||||
However, as "Securing the RTP Protocol Framework:
|
||||
Why RTP Does Not Mandate a Single Media Security Solution"
|
||||
<xref target="RFC7202"/> discusses, it is not an RTP payload
|
||||
format's responsibility to discuss or mandate what solutions are used
|
||||
to meet the basic security goals like confidentiality, integrity and
|
||||
source authenticity for RTP in general. This responsibility lays on
|
||||
anyone using RTP in an application. They can find guidance on
|
||||
available security mechanisms and important considerations in Options
|
||||
for Securing RTP Sessions [I-D.ietf-avtcore-rtp-security-options].
|
||||
Applications SHOULD use one or more appropriate strong security
|
||||
mechanisms.</t>
|
||||
|
||||
<t>This payload format and the Opus encoding do not exhibit any
|
||||
significant non-uniformity in the receiver-end computational load and thus
|
||||
are unlikely to pose a denial-of-service threat due to the receipt of
|
||||
pathological datagrams.</t>
|
||||
</section>
|
||||
|
||||
<section title='Acknowledgements'>
|
||||
<t>Many people have made useful comments and suggestions contributing to this document.
|
||||
In particular, we would like to thank
|
||||
Tina le Grand, Cullen Jennings, Jonathan Lennox, Gregory Maxwell, Colin Perkins, Jan Skoglund,
|
||||
Timothy B. Terriberry, Martin Thompson, Justin Uberti, Magnus Westerlund, and Mo Zanaty.</t>
|
||||
</section>
|
||||
</middle>
|
||||
|
||||
<back>
|
||||
<references title="Normative References">
|
||||
&rfc2119;
|
||||
&rfc3389;
|
||||
&rfc3550;
|
||||
&rfc3711;
|
||||
&rfc3551;
|
||||
&rfc6838;
|
||||
&rfc4855;
|
||||
&rfc4566;
|
||||
&rfc3264;
|
||||
&rfc2326;
|
||||
&rfc5576;
|
||||
&rfc6562;
|
||||
&rfc6716;
|
||||
</references>
|
||||
|
||||
<references title="Informative References">
|
||||
&rfc2974;
|
||||
&rfc4585;
|
||||
&rfc5124;
|
||||
&rfc5405;
|
||||
&rfc7202;
|
||||
|
||||
<reference anchor='rmcat' target='https://datatracker.ietf.org/wg/rmcat/documents/'>
|
||||
<front>
|
||||
<title>rmcat documents</title>
|
||||
<author/>
|
||||
<date/>
|
||||
<abstract>
|
||||
<t></t>
|
||||
</abstract></front>
|
||||
</reference>
|
||||
|
||||
|
||||
</references>
|
||||
|
||||
</back>
|
||||
</rfc>
|
||||
32
Engine/lib/opus/doc/footer.html
Normal file
32
Engine/lib/opus/doc/footer.html
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<!-- HTML footer for doxygen 1.8.18-->
|
||||
<!-- start footer part -->
|
||||
<!--BEGIN GENERATE_TREEVIEW-->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
<li class="footer">Generated by
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
|
||||
</ul>
|
||||
</div>
|
||||
<!--END GENERATE_TREEVIEW-->
|
||||
<!--BEGIN !GENERATE_TREEVIEW-->
|
||||
<hr class="footer"/>
|
||||
<table width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
For more information visit the <a href="https://opus-codec.org">Opus Website</a>.
|
||||
</td>
|
||||
<td>
|
||||
<address class="footer"><small>
|
||||
Generated by
|
||||
<a href="http://www.doxygen.org/index.html">doxygen</a>
|
||||
$doxygenversion
|
||||
</small></address>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--END !GENERATE_TREEVIEW-->
|
||||
</body>
|
||||
</html>
|
||||
61
Engine/lib/opus/doc/header.html
Normal file
61
Engine/lib/opus/doc/header.html
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<!-- HTML header for doxygen 1.8.18-->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen $doxygenversion"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
||||
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="$relpath^jquery.js"></script>
|
||||
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
||||
$treeview
|
||||
$search
|
||||
$mathjax
|
||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||
$extrastylesheet
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
|
||||
<!--BEGIN TITLEAREA-->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 64px;">
|
||||
<!--BEGIN PROJECT_LOGO-->
|
||||
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
|
||||
<!--END PROJECT_LOGO-->
|
||||
<!--BEGIN PROJECT_NAME-->
|
||||
<td style="padding-left: 0.5em;">
|
||||
<div id="projectname"><img src="opus_logo.svg" width=112 height=64 alt="Opus"/><!--$projectname--></div>
|
||||
</td>
|
||||
<td><table style="padding-left: 0.5em;" cellspacing="0" cellpadding="0"><tbody>
|
||||
<tr><td>
|
||||
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
|
||||
</td></tr>
|
||||
<td><!--BEGIN PROJECT_NUMBER--><span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
|
||||
</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
<!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME-->
|
||||
<!--BEGIN PROJECT_BRIEF-->
|
||||
<td style="padding-left: 0.5em;">
|
||||
<div id="projectbrief">$projectbrief</div>
|
||||
</td>
|
||||
<!--END PROJECT_BRIEF-->
|
||||
<!--END !PROJECT_NAME-->
|
||||
<!--BEGIN DISABLE_INDEX-->
|
||||
<!--BEGIN SEARCHENGINE-->
|
||||
<td>$searchbox</td>
|
||||
<!--END SEARCHENGINE-->
|
||||
<!--END DISABLE_INDEX-->
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--END TITLEAREA-->
|
||||
<!-- end header part -->
|
||||
33
Engine/lib/opus/doc/meson.build
Normal file
33
Engine/lib/opus/doc/meson.build
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
have_dot = find_program('dot', required: false).found()
|
||||
|
||||
doxyfile_conf = configuration_data()
|
||||
doxyfile_conf.set('VERSION', opus_version)
|
||||
doxyfile_conf.set('HAVE_DOT', have_dot)
|
||||
doxyfile_conf.set('top_srcdir', top_srcdir)
|
||||
doxyfile_conf.set('top_builddir', top_builddir)
|
||||
|
||||
doxyfile = configure_file(input: 'Doxyfile.in',
|
||||
output: 'Doxyfile',
|
||||
configuration: doxyfile_conf,
|
||||
install: false)
|
||||
|
||||
docdir = join_paths(get_option('datadir'), get_option('docdir'))
|
||||
|
||||
doc_inputs = [
|
||||
'customdoxygen.css',
|
||||
'footer.html',
|
||||
'header.html',
|
||||
'opus_logo.svg',
|
||||
top_srcdir + '/include/opus.h',
|
||||
top_srcdir + '/include/opus_multistream.h',
|
||||
top_srcdir + '/include/opus_defines.h',
|
||||
top_srcdir + '/include/opus_types.h',
|
||||
top_srcdir + '/include/opus_custom.h',
|
||||
]
|
||||
|
||||
custom_target('doc',
|
||||
input: [ doxyfile ] + doc_inputs,
|
||||
output: [ 'html' ],
|
||||
command: [ doxygen, doxyfile ],
|
||||
install_dir: docdir,
|
||||
install: true)
|
||||
60
Engine/lib/opus/doc/opus_in_isobmff.css
Normal file
60
Engine/lib/opus/doc/opus_in_isobmff.css
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* Normal links */
|
||||
.normal_link a:link
|
||||
{
|
||||
color : yellow;
|
||||
}
|
||||
.normal_link a:visited
|
||||
{
|
||||
color : green;
|
||||
}
|
||||
|
||||
/* Boxes */
|
||||
.pre
|
||||
{
|
||||
white-space: pre; /* CSS 2.0 */
|
||||
white-space: pre-wrap; /* CSS 2.1 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla */
|
||||
white-space: -hp-pre-wrap; /* HP Printers */
|
||||
word-wrap : break-word; /* IE 5+ */
|
||||
}
|
||||
|
||||
.title_box
|
||||
{
|
||||
width : 470px;
|
||||
height : 70px;
|
||||
margin : 2px 50px 2px 2px;
|
||||
padding : 10px;
|
||||
border : 1px solid black;
|
||||
background-color : #666666;
|
||||
white-space : pre;
|
||||
float : left;
|
||||
text-align : center;
|
||||
color : #C0C0C0;
|
||||
font-size : 50pt;
|
||||
font-style : italic;
|
||||
}
|
||||
|
||||
.subindex_box
|
||||
{
|
||||
margin : 5px;
|
||||
padding : 14px 22px;
|
||||
border : 1px solid black;
|
||||
background-color : #778877;
|
||||
float : left;
|
||||
text-align : center;
|
||||
color : #115555;
|
||||
font-size : 32pt;
|
||||
}
|
||||
|
||||
.frame_box
|
||||
{
|
||||
margin : 10px;
|
||||
padding : 10px;
|
||||
border : 0px;
|
||||
background-color : #084040;
|
||||
text-align : left;
|
||||
color : #C0C0C0;
|
||||
font-family : monospace;
|
||||
}
|
||||
692
Engine/lib/opus/doc/opus_in_isobmff.html
Normal file
692
Engine/lib/opus/doc/opus_in_isobmff.html
Normal file
|
|
@ -0,0 +1,692 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="opus_in_isobmff.css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Encapsulation of Opus in ISO Base Media File Format</title>
|
||||
</head>
|
||||
<body bgcolor="0x333333" text="#60B0C0">
|
||||
<b><u>Encapsulation of Opus in ISO Base Media File Format</u></b><br>
|
||||
<font size="2">last updated: August 28, 2018</font><br>
|
||||
<br>
|
||||
<div class="normal_link pre frame_box">
|
||||
|
||||
Encapsulation of Opus in ISO Base Media File Format
|
||||
Version 0.8.1 (incomplete)
|
||||
|
||||
|
||||
Table of Contents
|
||||
<a href="#1">1</a> Scope
|
||||
<a href="#2">2</a> Normative References
|
||||
<a href="#3">3</a> Terms and Definitions
|
||||
<a href="#4">4</a> Design Rules of Encapsulation
|
||||
<a href="#4.1">4.1</a> File Type Identification
|
||||
<a href="#4.2">4.2</a> Overview of Track Structure
|
||||
<a href="#4.3">4.3</a> Definitions of Opus sample
|
||||
<a href="#4.3.1">4.3.1</a> Sample entry format
|
||||
<a href="#4.3.2">4.3.2</a> Opus Specific Box
|
||||
<a href="#4.3.3">4.3.3</a> Sample format
|
||||
<a href="#4.3.4">4.3.4</a> Duration of Opus sample
|
||||
<a href="#4.3.5">4.3.5</a> Sub-sample
|
||||
<a href="#4.3.6">4.3.6</a> Random Access
|
||||
<a href="#4.3.6.1">4.3.6.1</a> Random Access Point
|
||||
<a href="#4.3.6.2">4.3.6.2</a> Pre-roll
|
||||
<a href="#4.4">4.4</a> Trimming of Actual Duration
|
||||
<a href="#4.5">4.5</a> Channel Mapping
|
||||
<a href="#4.5.1">4.5.1</a> ISO Base Media native Channel Mapping
|
||||
<a href="#4.5.2">4.5.2</a> Composition on all active tracks (informative)
|
||||
<a href="#4.6">4.6</a> Basic Structure (informative)
|
||||
<a href="#4.6.1">4.6.2</a> Initial Movie
|
||||
<a href="#4.6.2">4.6.3</a> Movie Fragments
|
||||
<a href="#4.7">4.7</a> Example of Encapsulation (informative)
|
||||
<a href="#5">5</a> Author's Address
|
||||
|
||||
<a name="1"></a>
|
||||
1 Scope
|
||||
This specification specifies the fundamental way of the encapsulation of Opus coded bitstreams in ISO Base Media
|
||||
file format and its derivatives. The encapsulation of Opus coded bitstreams in QuickTime file format is outside
|
||||
the scope of this specification.
|
||||
|
||||
<a name="2"></a>
|
||||
2 Normative References
|
||||
[1] ISO/IEC 14496-12:2015 Corrected version
|
||||
Information technology — Coding of audio-visual objects — Part 12: ISO base media file format
|
||||
|
||||
[2] RFC 6716
|
||||
Definition of the Opus Audio Codec
|
||||
|
||||
[3] RFC 7845
|
||||
Ogg Encapsulation for the Opus Audio Codec
|
||||
|
||||
<a name="3"></a>
|
||||
3 Terms and Definitions
|
||||
3.1 active track
|
||||
enabled track from the non-alternate group or selected track from alternate group
|
||||
|
||||
3.2 actual duration
|
||||
duration constructed from valid samples
|
||||
|
||||
3.3 edit
|
||||
entry in the Edit List Box
|
||||
|
||||
3.4 padded samples
|
||||
PCM samples after decoding Opus sample(s) which are not valid samples
|
||||
An Opus bitstream always contains them partially at the beginning and may contain them in part at the end, as
|
||||
long as not physically removed yet at the beginning and/or the end.
|
||||
|
||||
3.5 priming samples
|
||||
padded samples at the beginning of the Opus bitstream
|
||||
|
||||
3.6 sample-accurate
|
||||
for any PCM sample, a timestamp exactly matching its sampling timestamp is present in the media timeline.
|
||||
|
||||
3.7 valid samples
|
||||
PCM samples after decoding Opus sample(s) corresponding to input PCM samples
|
||||
|
||||
<a name="4"></a>
|
||||
4 Design Rules of Encapsulation
|
||||
4.1 File Type Identification<a name="4.1"></a>
|
||||
This specification defines the brand 'Opus' to declare files are conformant to this specification. Additionally,
|
||||
files conformant to this specification shall contain at least one brand, which supports the requirements and the
|
||||
requirements described in this clause without contradiction, in the compatible brands list of the File Type Box.
|
||||
As an example, the minimal support of the encapsulation of Opus bitstreams in ISO Base Media file format requires
|
||||
the 'iso2' brand in the compatible brands list since support of roll groups is required.
|
||||
<a name="4.2"></a>
|
||||
4.2 Overview of Track Structure
|
||||
This clause summarizes requirements of the encapsulation of Opus coded bitstream as media data in audio tracks
|
||||
in file formats compliant with the ISO Base Media File Format. The details are described in clauses after this
|
||||
clause.
|
||||
+ The handler_type field in the Handler Reference Box shall be set to 'soun'.
|
||||
+ The Media Information Box shall contain the Sound Media Header Box.
|
||||
+ The codingname of the sample entry is 'Opus'.
|
||||
This specification does not define any encapsulation using MP4AudioSampleEntry with objectTypeIndication
|
||||
specified by the MPEG-4 Registration Authority (http://www.mp4ra.org/).
|
||||
See 4.3.1 Sample entry format to get the details about the sample entry.
|
||||
+ The 'dOps' box is added to the sample entry to convey initializing information for the decoder.
|
||||
See 4.3.2 Opus Specific Box to get the details.
|
||||
+ An Opus sample is exactly one Opus packet for each of different Opus bitstreams.
|
||||
See 4.3.3 Sample format to get the details.
|
||||
+ Every Opus sample is a sync sample but requires pre-roll for every random access to get correct output.
|
||||
See 4.3.6 Random Access to get the details.
|
||||
<a name="4.3"></a>
|
||||
4.3 Definitions of Opus sample
|
||||
4.3.1 Sample entry format<a name="4.3.1"></a>
|
||||
For any track containing Opus bitstreams, at least one sample entry describing corresponding Opus bitstream
|
||||
shall be present inside the Sample Table Box. This version of the specification defines only one sample
|
||||
entry format named OpusSampleEntry whose codingname is 'Opus'. This sample entry includes exactly one Opus
|
||||
Specific Box defined in 4.3.2 as a mandatory box and indicates that Opus samples described by this sample
|
||||
entry are stored by the sample format described in 4.3.3.
|
||||
|
||||
The syntax and semantics of the OpusSampleEntry is shown as follows.
|
||||
|
||||
class OpusSampleEntry() extends AudioSampleEntry ('Opus') {
|
||||
OpusSpecificBox();
|
||||
}
|
||||
|
||||
+ channelcount:
|
||||
The channelcount field indicates the number of output channels and shall be set to the same value of
|
||||
the OutputChannelCount in the OpusDecoderConfigurationRecord. The value of this field may be used in
|
||||
the ChannelLayout if any as described in 4.5.1.
|
||||
+ samplesize:
|
||||
The samplesize field shall be set to 16.
|
||||
+ samplerate:
|
||||
The samplerate field shall be set to 48000<<16.
|
||||
+ OpusSpecificBox
|
||||
This box contains initializing information for the decoder as defined in 4.3.2.
|
||||
|
||||
4.3.2 Opus Specific Box<a name="4.3.2"></a>
|
||||
Exactly one Opus Specific Box shall be present in each OpusSampleEntry.
|
||||
The Opus Specific Box contains an OpusDecoderConfigurationRecord which contains the Version field and
|
||||
this specification defines version 0 of this record. If incompatible changes occured in the fields after
|
||||
the Version field within the OpusDecoderConfigurationRecord in the future versions of this specification,
|
||||
another version will be defined.
|
||||
This box refers to Ogg Opus [3] at many parts but all the data are stored as big-endian format.
|
||||
|
||||
The syntax and semantics of the Opus Specific Box is shown as follows.
|
||||
|
||||
class ChannelMappingTable (unsigned int(8) OutputChannelCount) {
|
||||
unsigned int(8) StreamCount;
|
||||
unsigned int(8) CoupledCount;
|
||||
unsigned int(8 * OutputChannelCount) ChannelMapping;
|
||||
}
|
||||
|
||||
aligned(8) class OpusDecoderConfigurationRecord {
|
||||
unsigned int(8) Version;
|
||||
unsigned int(8) OutputChannelCount;
|
||||
unsigned int(16) PreSkip;
|
||||
unsigned int(32) InputSampleRate;
|
||||
signed int(16) OutputGain;
|
||||
unsigned int(8) ChannelMappingFamily;
|
||||
if (ChannelMappingFamily != 0) {
|
||||
ChannelMappingTable(OutputChannelCount);
|
||||
}
|
||||
}
|
||||
|
||||
class OpusSpecificBox extends Box('dOps') {
|
||||
OpusDecoderConfigurationRecord() OpusConfig;
|
||||
}
|
||||
|
||||
+ Version:
|
||||
The Version field shall be set to 0.
|
||||
In the future versions of this specification, this field may be set to other values. And without support
|
||||
of those values, the reader shall not read the fields after this within the OpusSpecificBox.
|
||||
+ OutputChannelCount:
|
||||
The OutputChannelCount field shall be set to the same value as the *Output Channel Count* field in the
|
||||
identification header defined in Ogg Opus [3].
|
||||
+ PreSkip:
|
||||
The PreSkip field indicates the number of the priming samples, that is, the number of samples at 48000 Hz
|
||||
to discard from the decoder output when starting playback. The value of the PreSkip field shall be at least
|
||||
80 milliseconds' worth of PCM samples even when removing any number of Opus samples which may or may not
|
||||
contain the priming samples. The PreSkip field is not used for discarding the priming samples at the whole
|
||||
playback at all since it is informative only, and that task falls on the Edit List Box.
|
||||
+ InputSampleRate:
|
||||
The InputSampleRate field shall be set to the same value as the *Input Sample Rate* field in the
|
||||
identification header defined in Ogg Opus [3].
|
||||
+ OutputGain:
|
||||
The OutputGain field shall be set to the same value as the *Output Gain* field in the identification
|
||||
header define in Ogg Opus [3]. Note that the value is stored as 8.8 fixed-point.
|
||||
+ ChannelMappingFamily:
|
||||
The ChannelMappingFamily field shall be set to the same value as the *Channel Mapping Family* field in
|
||||
the identification header defined in Ogg Opus [3]. Note that the value 255 may be used for an alternative
|
||||
to map channels by ISO Base Media native mapping. The details are described in 4.5.1.
|
||||
+ StreamCount:
|
||||
The StreamCount field shall be set to the same value as the *Stream Count* field in the identification
|
||||
header defined in Ogg Opus [3].
|
||||
+ CoupledCount:
|
||||
The CoupledCount field shall be set to the same value as the *Coupled Count* field in the identification
|
||||
header defined in Ogg Opus [3].
|
||||
+ ChannelMapping:
|
||||
The ChannelMapping field shall be set to the same octet string as *Channel Mapping* field in the identi-
|
||||
fication header defined in Ogg Opus [3].
|
||||
|
||||
4.3.3 Sample format<a name="4.3.3"></a>
|
||||
An Opus sample is exactly one Opus packet for each of different Opus bitstreams. Due to support more than
|
||||
two channels, an Opus sample can contain frames from multiple Opus bitstreams but all Opus packets shall
|
||||
share with the total of frame sizes in a single Opus sample. The way of how to pack an Opus packet from
|
||||
each of Opus bitstreams into a single Opus sample follows Appendix B. in RFC 6716 [2].
|
||||
The endianness has nothing to do with any Opus sample since every Opus packet is processed byte-by-byte.
|
||||
In this specification, 'sample' means 'Opus sample' except for 'padded samples', 'priming samples', 'valid
|
||||
sample' and 'sample-accurate', i.e. 'sample' is 'sample' in the term defined in ISO/IEC 14496-12 [1].
|
||||
|
||||
+-----------------------------------------+-------------------------------------+
|
||||
| Opus packet 0 (self-delimiting framing) | Opus packet 1 (undelimited framing) |
|
||||
+-----------------------------------------+-------------------------------------+
|
||||
|<---------------------------- the size of Opus sample ------------------------>|
|
||||
|
||||
Figure 1 - Example structure of an Opus sample containing two Opus bitstreams
|
||||
|
||||
4.3.4 Duration of Opus sample<a name="4.3.4"></a>
|
||||
The duration of Opus sample is given by multiplying the total of frame sizes for a single Opus bitstream
|
||||
expressed in seconds by the value of the timescale field in the Media Header Box.
|
||||
Let's say an Opus sample consists of two Opus bitstreams, where the frame size of one bitstream is 40 milli-
|
||||
seconds and the frame size of another is 60 milliseconds, and the timescale field in the Media Header Box
|
||||
is set to 48000, then the duration of that Opus sample shall be 120 milliseconds since three 40 millisecond
|
||||
frame and two 60 millisecond frames shall be contained because of the maximum duration of Opus packet, 120
|
||||
milliseconds, and 5760 in the timescale indicated in the Media Header Box.
|
||||
|
||||
To indicate the valid samples excluding the padded samples at the end of Opus bitstream, the duration of
|
||||
the last Opus sample of an Opus bitstream is given by multiplying the number of the valid samples by the
|
||||
value produced by dividing the value of the timescale field in the Media Header Box by 48000.
|
||||
|
||||
4.3.5 Sub-sample<a name="4.3.5"></a>
|
||||
The structure of the last Opus packet in an Opus sample is different from the others in the same Opus sample,
|
||||
and the others are invalid Opus packets as an Opus sample because of self-delimiting framing. To avoid
|
||||
complexities, sub-sample is not defined for Opus sample in this specification.
|
||||
|
||||
4.3.6 Random Access<a name="4.3.6"></a>
|
||||
This subclause describes the nature of the random access of Opus sample.
|
||||
|
||||
4.3.6.1 Random Access Point<a name="4.3.6.1"></a>
|
||||
All Opus samples can be independently decoded i.e. every Opus sample is a sync sample. Therefore, the
|
||||
Sync Sample Box shall not be present as long as there are no samples other than Opus samples in the same
|
||||
track. And the sample_is_non_sync_sample field for Opus samples shall be set to 0.
|
||||
|
||||
4.3.6.2 Pre-roll<a name="4.3.6.2"></a>
|
||||
Opus bitstream requires at least 80 millisecond pre-roll after each random access to get correct output.
|
||||
Pre-roll is indicated by the roll_distance field in AudioRollRecoveryEntry. AudioPreRollEntry shall not
|
||||
be used since every Opus sample is a sync sample in Opus bitstream. Note that roll_distance is expressed
|
||||
in sample units in a term of ISO Base Media File Format, and always takes negative values.
|
||||
|
||||
For any track containing Opus bitstreams, at least one Sample Group Description Box and at least one
|
||||
Sample to Group Box within the Sample Table Box shall be present and these have the grouping_type field
|
||||
set to 'roll'. If any Opus sample is contained in a track fragment, the Sample to Group Box with the
|
||||
grouping_type field set to 'roll' shall be present for that track fragment.
|
||||
|
||||
For the requirement of AudioRollRecoveryEntry, the compatible_brands field in the File Type Box shall
|
||||
contain at least one brand which requires support for roll groups.
|
||||
<a name="4.4"></a>
|
||||
4.4 Trimming of Actual Duration
|
||||
Due to the priming samples (or the padding at the beginning) derived from the pre-roll for the startup and the
|
||||
padded samples at the end, we need trim from media to get the actual duration. An edit in the Edit List Box can
|
||||
achieve this demand, and the Edit Box and the Edit List Box shall be present.
|
||||
|
||||
For sample-accurate trimming, proper timescale should be set to the timescale field in the Movie Header Box
|
||||
and the Media Header Box inside Track Box(es) for Opus bitstream. The timescale field in the Media Header Box is
|
||||
typically set to 48000. It is recommended that the timescale field in the Movie Header Box be set to the same
|
||||
value of the timescale field in the Media Header Box in order to avoid the rounding problem when specifying
|
||||
duration of edit if the timescales in all of the Media Header Boxes are set to the same value.
|
||||
|
||||
For example, to indicate the actual duration of an Opus bitstream in a track with the timescale fields of both
|
||||
the Movie Header Box and the Media Header Box set to 48000, we would use the following edit:
|
||||
segment_duration = the number of the valid samples
|
||||
media_time = the number of the priming samples
|
||||
media_rate = 1 << 16
|
||||
|
||||
The Edit List Box is applied to whole movie including all movie fragments. Therefore, it is impossible to tell
|
||||
the actual duration in the case producing movie fragments on the fly such as live-streaming. In such cases,
|
||||
the duration of the last Opus sample may be helpful by setting zero to the segment_duration field since the
|
||||
value 0 represents implicit duration equal to the sum of the duration of all samples.
|
||||
<a name="4.5"></a>
|
||||
4.5 Channel Mapping
|
||||
4.5.1 ISO Base Media native Channel Mapping<a name="4.5.1"></a>
|
||||
ISO Base Media File Format, that is ISO/IEC 14496-12 [1], defines an extension ChannelLayout to the
|
||||
AudioSampleEntry, which conveys information of mapping channels to loudspeaker positions. The ChannelLayout
|
||||
enables to specify the channel layout more flexibly than the predefined layouts of the ChannelMappingFamily.
|
||||
|
||||
To utilize the ChannelLayout for OpusSampleEntry, the ChannelMappingFamily field should be set to 255.
|
||||
Even when the ChannelMappingFamily field is set to another value, the assignment of each output channel to
|
||||
loudspeaker position specified by the ChannelMappingFamily would be changed as specified by the ChannelLayout.
|
||||
The procedure of the assignment is the following.
|
||||
|
||||
1. Decoded channels are mapped to output channels according to the ChannelMappingTable.
|
||||
2. Output channels are mapped to loudspeaker positions according to the ChannelLayout.
|
||||
|
||||
In this way, the parameters of the Opus Specific Box are processed before the ChannelLayout, and the
|
||||
ChannelLayout shall follow the Opus Specific Box.
|
||||
|
||||
4.5.2 Composition on all active tracks (informative)<a name="4.5.2"></a>
|
||||
By the application of alternate_group in the Track Header Box, whole audio channels in all active tracks from
|
||||
non-alternate group and/or different alternate group from each other are composited into the presentation. If
|
||||
an Opus sample consists of multiple Opus bitstreams, it can be splitted into individual Opus bitstreams and
|
||||
reconstructed into new Opus samples as long as every Opus bitstream has the same total duration in each Opus
|
||||
sample. This nature can be utilized to encapsulate a single Opus bitstream in each track without breaking the
|
||||
original channel layout.
|
||||
|
||||
As an example, let's say there is a following track:
|
||||
OutputChannelCount = 6;
|
||||
StreamCount = 4;
|
||||
CoupledCount = 2;
|
||||
ChannelMapping = {0, 4, 1, 2, 3, 5}; // front left, front center, front right,
|
||||
// rear left, rear right, LFE
|
||||
Here, to couple front left to front right channels into the first stream, and couple rear left to rear right
|
||||
channels into the second stream, reordering is needed since coupled streams must precede any non-coupled
|
||||
stream. You extract the four Opus bitstreams from this track and you encapsulate two of the four into a track
|
||||
and the others into another track. The former track is as follows.
|
||||
OutputChannelCount = 6;
|
||||
StreamCount = 2;
|
||||
CoupledCount = 2;
|
||||
ChannelMapping = {0, 255, 1, 2, 3, 255}; // front left, front center, front right,
|
||||
// rear left, rear right, LFE
|
||||
And the latter track is as follows.
|
||||
OutputChannelCount = 6;
|
||||
StreamCount = 2;
|
||||
CoupledCount = 0;
|
||||
ChannelMapping = {255, 0, 255, 255, 255, 1}; // front left, front center, front right,
|
||||
// rear left, rear right, LFE
|
||||
In addition, the value of the alternate_group field in the both tracks is set to 0. As the result, the player
|
||||
may play as if channels with 255 are not present, and play the presentation constructed from the both tracks
|
||||
in the same channel layout as the one of the original track. Keep in mind that the way of the composition, i.e.
|
||||
the mixing for playback, is not defined here, and maybe different results could occur except for the channel
|
||||
layout of the original, depending on an implementation or the definition of a derived file format.
|
||||
|
||||
Note that some derived file formats may specify the restriction to ignore alternate grouping. In the context
|
||||
of such file formats, this application is not available. This unavailability does not mean incompatibilities
|
||||
among file formats unless the restriction to the value of the alternate_group field is specified and brings
|
||||
about any conflict among their definitions.
|
||||
<a name="4.6"></a>
|
||||
4.6 Basic Structure (informative)
|
||||
4.6.1 Initial Movie<a name="4.6.1"></a>
|
||||
This subclause shows a basic structure of the Movie Box as follows:
|
||||
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
|moov| | | | | | | | Movie Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| |mvhd| | | | | | | Movie Header Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| |trak| | | | | | | Track Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | |tkhd| | | | | | Track Header Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | |edts| | | | | | Edit Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | |elst| | | | | Edit List Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | |mdia| | | | | | Media Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | |mdhd| | | | | Media Header Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | |hdlr| | | | | Handler Reference Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | |minf| | | | | Media Information Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | |smhd| | | | Sound Media Header Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | |dinf| | | | Data Information Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | |dref| | | Data Reference Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | | |url | | DataEntryUrlBox |
|
||||
+----+----+----+----+----+----+ or +----+------------------------------+
|
||||
| | | | | | |urn | | DataEntryUrnBox |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | |stbl| | | | Sample Table |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | |stsd| | | Sample Description Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | | |Opus| | OpusSampleEntry |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | | | |dOps| Opus Specific Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | |stts| | | Decoding Time to Sample Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | |stsc| | | Sample To Chunk Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | |stsz| | | Sample Size Box |
|
||||
+----+----+----+----+----+ or +----+----+------------------------------+
|
||||
| | | | | |stz2| | | Compact Sample Size Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | |stco| | | Chunk Offset Box |
|
||||
+----+----+----+----+----+ or +----+----+------------------------------+
|
||||
| | | | | |co64| | | Chunk Large Offset Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | |sgpd| | | Sample Group Description Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | | | | |sbgp| | | Sample to Group Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| |mvex|* | | | | | | Movie Extends Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | |trex|* | | | | | Track Extends Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
|
||||
Figure 2 - Basic structure of Movie Box
|
||||
|
||||
It is strongly recommended that the order of boxes should follow the above structure.
|
||||
Boxes marked with an asterisk (*) may be present.
|
||||
For most boxes listed above, the definition is as is defined in ISO/IEC 14496-12 [1]. The additional boxes
|
||||
and the additional requirements, restrictions and recommendations to the other boxes are described in this
|
||||
specification.
|
||||
|
||||
4.6.2 Movie Fragments<a name="4.6.2"></a>
|
||||
This subclause shows a basic structure of the Movie Fragment Box as follows:
|
||||
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
|moof| | | | | | | | Movie Fragment Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| |mfhd| | | | | | | Movie Fragment Header Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| |traf| | | | | | | Track Fragment Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | |tfhd| | | | | | Track Fragment Header Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | |trun| | | | | | Track Fragment Run Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | |sgpd|* | | | | | Sample Group Description Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
| | |sbgp| | | | | | Sample to Group Box |
|
||||
+----+----+----+----+----+----+----+----+------------------------------+
|
||||
|
||||
Figure 3 - Basic structure of Movie Fragment Box
|
||||
|
||||
It is strongly recommended that the Movie Fragment Header Box and the Track Fragment Header Box be
|
||||
placed first in their container.
|
||||
Boxes marked with an asterisk (*) may be present.
|
||||
For the boxes listed above, the definition is as is defined in ISO/IEC 14496-12 [1].
|
||||
<a name="4.7"></a>
|
||||
4.7 Example of Encapsulation (informative)
|
||||
[File]
|
||||
size = 17757
|
||||
[ftyp: File Type Box]
|
||||
position = 0
|
||||
size = 24
|
||||
major_brand = Opus : Opus audio coding
|
||||
minor_version = 0
|
||||
compatible_brands
|
||||
brand[0] = Opus : Opus audio coding
|
||||
brand[1] = iso2 : ISO Base Media file format version 2
|
||||
[moov: Movie Box]
|
||||
position = 24
|
||||
size = 757
|
||||
[mvhd: Movie Header Box]
|
||||
position = 32
|
||||
size = 108
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
creation_time = UTC 2014/12/12, 18:41:19
|
||||
modification_time = UTC 2014/12/12, 18:41:19
|
||||
timescale = 48000
|
||||
duration = 33600 (00:00:00.700)
|
||||
rate = 1.000000
|
||||
volume = 1.000000
|
||||
reserved = 0x0000
|
||||
reserved = 0x00000000
|
||||
reserved = 0x00000000
|
||||
transformation matrix
|
||||
| a, b, u | | 1.000000, 0.000000, 0.000000 |
|
||||
| c, d, v | = | 0.000000, 1.000000, 0.000000 |
|
||||
| x, y, w | | 0.000000, 0.000000, 1.000000 |
|
||||
pre_defined = 0x00000000
|
||||
pre_defined = 0x00000000
|
||||
pre_defined = 0x00000000
|
||||
pre_defined = 0x00000000
|
||||
pre_defined = 0x00000000
|
||||
pre_defined = 0x00000000
|
||||
next_track_ID = 2
|
||||
[trak: Track Box]
|
||||
position = 140
|
||||
size = 608
|
||||
[tkhd: Track Header Box]
|
||||
position = 148
|
||||
size = 92
|
||||
version = 0
|
||||
flags = 0x000007
|
||||
Track enabled
|
||||
Track in movie
|
||||
Track in preview
|
||||
creation_time = UTC 2014/12/12, 18:41:19
|
||||
modification_time = UTC 2014/12/12, 18:41:19
|
||||
track_ID = 1
|
||||
reserved = 0x00000000
|
||||
duration = 33600 (00:00:00.700)
|
||||
reserved = 0x00000000
|
||||
reserved = 0x00000000
|
||||
layer = 0
|
||||
alternate_group = 0
|
||||
volume = 1.000000
|
||||
reserved = 0x0000
|
||||
transformation matrix
|
||||
| a, b, u | | 1.000000, 0.000000, 0.000000 |
|
||||
| c, d, v | = | 0.000000, 1.000000, 0.000000 |
|
||||
| x, y, w | | 0.000000, 0.000000, 1.000000 |
|
||||
width = 0.000000
|
||||
height = 0.000000
|
||||
[edts: Edit Box]
|
||||
position = 240
|
||||
size = 36
|
||||
[elst: Edit List Box]
|
||||
position = 281
|
||||
size = 28
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
entry_count = 1
|
||||
entry[0]
|
||||
segment_duration = 33600
|
||||
media_time = 312
|
||||
media_rate = 1.000000
|
||||
[mdia: Media Box]
|
||||
position = 276
|
||||
size = 472
|
||||
[mdhd: Media Header Box]
|
||||
position = 284
|
||||
size = 32
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
creation_time = UTC 2014/12/12, 18:41:19
|
||||
modification_time = UTC 2014/12/12, 18:41:19
|
||||
timescale = 48000
|
||||
duration = 34560 (00:00:00.720)
|
||||
language = und
|
||||
pre_defined = 0x0000
|
||||
[hdlr: Handler Reference Box]
|
||||
position = 316
|
||||
size = 51
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
pre_defined = 0x00000000
|
||||
handler_type = soun
|
||||
reserved = 0x00000000
|
||||
reserved = 0x00000000
|
||||
reserved = 0x00000000
|
||||
name = Xiph Audio Handler
|
||||
[minf: Media Information Box]
|
||||
position = 367
|
||||
size = 381
|
||||
[smhd: Sound Media Header Box]
|
||||
position = 375
|
||||
size = 16
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
balance = 0.000000
|
||||
reserved = 0x0000
|
||||
[dinf: Data Information Box]
|
||||
position = 391
|
||||
size = 36
|
||||
[dref: Data Reference Box]
|
||||
position = 399
|
||||
size = 28
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
entry_count = 1
|
||||
[url : Data Entry Url Box]
|
||||
position = 415
|
||||
size = 12
|
||||
version = 0
|
||||
flags = 0x000001
|
||||
location = in the same file
|
||||
[stbl: Sample Table Box]
|
||||
position = 427
|
||||
size = 321
|
||||
[stsd: Sample Description Box]
|
||||
position = 435
|
||||
size = 79
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
entry_count = 1
|
||||
[Opus: Audio Description]
|
||||
position = 451
|
||||
size = 63
|
||||
reserved = 0x000000000000
|
||||
data_reference_index = 1
|
||||
reserved = 0x0000
|
||||
reserved = 0x0000
|
||||
reserved = 0x00000000
|
||||
channelcount = 6
|
||||
samplesize = 16
|
||||
pre_defined = 0
|
||||
reserved = 0
|
||||
samplerate = 48000.000000
|
||||
[dOps: Opus Specific Box]
|
||||
position = 487
|
||||
size = 27
|
||||
Version = 0
|
||||
OutputChannelCount = 6
|
||||
PreSkip = 312
|
||||
InputSampleRate = 48000
|
||||
OutputGain = 0
|
||||
ChannelMappingFamily = 1
|
||||
StreamCount = 4
|
||||
CoupledCount = 2
|
||||
ChannelMapping
|
||||
0 -> 0: front left
|
||||
1 -> 4: fron center
|
||||
2 -> 1: front right
|
||||
3 -> 2: side left
|
||||
4 -> 3: side right
|
||||
5 -> 5: rear center
|
||||
[stts: Decoding Time to Sample Box]
|
||||
position = 514
|
||||
size = 24
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
entry_count = 1
|
||||
entry[0]
|
||||
sample_count = 18
|
||||
sample_delta = 1920
|
||||
[stsc: Sample To Chunk Box]
|
||||
position = 538
|
||||
size = 40
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
entry_count = 2
|
||||
entry[0]
|
||||
first_chunk = 1
|
||||
samples_per_chunk = 13
|
||||
sample_description_index = 1
|
||||
entry[1]
|
||||
first_chunk = 2
|
||||
samples_per_chunk = 5
|
||||
sample_description_index = 1
|
||||
[stsz: Sample Size Box]
|
||||
position = 578
|
||||
size = 92
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
sample_size = 0 (variable)
|
||||
sample_count = 18
|
||||
entry_size[0] = 977
|
||||
entry_size[1] = 938
|
||||
entry_size[2] = 939
|
||||
entry_size[3] = 938
|
||||
entry_size[4] = 934
|
||||
entry_size[5] = 945
|
||||
entry_size[6] = 948
|
||||
entry_size[7] = 956
|
||||
entry_size[8] = 955
|
||||
entry_size[9] = 930
|
||||
entry_size[10] = 933
|
||||
entry_size[11] = 934
|
||||
entry_size[12] = 972
|
||||
entry_size[13] = 977
|
||||
entry_size[14] = 958
|
||||
entry_size[15] = 949
|
||||
entry_size[16] = 962
|
||||
entry_size[17] = 848
|
||||
[stco: Chunk Offset Box]
|
||||
position = 670
|
||||
size = 24
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
entry_count = 2
|
||||
chunk_offset[0] = 797
|
||||
chunk_offset[1] = 13096
|
||||
[sgpd: Sample Group Description Box]
|
||||
position = 694
|
||||
size = 26
|
||||
version = 1
|
||||
flags = 0x000000
|
||||
grouping_type = roll
|
||||
default_length = 2 (constant)
|
||||
entry_count = 1
|
||||
roll_distance[0] = -2
|
||||
[sbgp: Sample to Group Box]
|
||||
position = 720
|
||||
size = 28
|
||||
version = 0
|
||||
flags = 0x000000
|
||||
grouping_type = roll
|
||||
entry_count = 1
|
||||
entry[0]
|
||||
sample_count = 18
|
||||
group_description_index = 1
|
||||
[free: Free Space Box]
|
||||
position = 748
|
||||
size = 8
|
||||
[mdat: Media Data Box]
|
||||
position = 756
|
||||
size = 17001
|
||||
<a name="5"></a>
|
||||
5 Authors' Address
|
||||
Yusuke Nakamura
|
||||
Email: muken.the.vfrmaniac |at| gmail.com
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
157
Engine/lib/opus/doc/opus_logo.svg
Normal file
157
Engine/lib/opus/doc/opus_logo.svg
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="360"
|
||||
height="205"
|
||||
viewBox="-72 -23.757 360 205"
|
||||
overflow="visible"
|
||||
enable-background="new -72 -23.757 504 252"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
style="overflow:visible">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
xlink:href="#SVGID_1_"
|
||||
id="linearGradient3027"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="194.53169"
|
||||
y1="95.107399"
|
||||
x2="194.53169"
|
||||
y2="9.9475983e-14" /><linearGradient
|
||||
xlink:href="#SVGID_2_"
|
||||
id="linearGradient3029"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="229.61819"
|
||||
y1="116.208"
|
||||
x2="229.61819"
|
||||
y2="164.46291" /><linearGradient
|
||||
xlink:href="#SVGID_3_"
|
||||
id="linearGradient3031"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="43.9897"
|
||||
y1="115.4395"
|
||||
x2="43.9897"
|
||||
y2="165.2314" /><linearGradient
|
||||
xlink:href="#SVGID_4_"
|
||||
id="linearGradient3033"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="311.2847"
|
||||
y1="115.7188"
|
||||
x2="311.2847"
|
||||
y2="165.2822" /><linearGradient
|
||||
xlink:href="#SVGID_5_"
|
||||
id="linearGradient3035"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="129.1987"
|
||||
y1="115.5791"
|
||||
x2="129.1987"
|
||||
y2="204.4863" /></defs>
|
||||
<linearGradient
|
||||
id="SVGID_1_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="194.53169"
|
||||
y1="95.107399"
|
||||
x2="194.53169"
|
||||
y2="9.9475983e-14">
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#8E8E8E"
|
||||
id="stop7" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#B5B5B5"
|
||||
id="stop9" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
id="SVGID_2_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="229.61819"
|
||||
y1="116.208"
|
||||
x2="229.61819"
|
||||
y2="164.46291">
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#494748"
|
||||
id="stop14" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop16" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
id="SVGID_3_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="43.9897"
|
||||
y1="115.4395"
|
||||
x2="43.9897"
|
||||
y2="165.2314">
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#494748"
|
||||
id="stop21" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop23" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
id="SVGID_4_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="311.2847"
|
||||
y1="115.7188"
|
||||
x2="311.2847"
|
||||
y2="165.2822">
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#494748"
|
||||
id="stop28" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop30" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
id="SVGID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="129.1987"
|
||||
y1="115.5791"
|
||||
x2="129.1987"
|
||||
y2="204.4863">
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#494748"
|
||||
id="stop35" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop37" />
|
||||
</linearGradient>
|
||||
<g
|
||||
id="g3020"
|
||||
transform="translate(-72.001783,-23.243)"><path
|
||||
id="path11"
|
||||
d="M 257.355,13.996 C 249.943,7.826 238.533,3.695 223.153,1.588 l -11.302,35.935 c -0.244,1.318 -0.664,2.815 -1.315,4.54 -1.153,2.883 -2.542,5.258 -4.174,7.127 -1.634,1.874 -3.463,3.335 -5.489,4.4 -2.028,1.059 -4.232,1.79 -6.614,2.193 -2.382,0.4 -4.847,0.526 -7.393,0.378 -2.549,-0.148 -4.717,-0.495 -6.501,-1.042 -1.786,-0.546 -3.428,-1.452 -4.925,-2.72 -1.107,-1.245 -1.751,-2.878 -1.927,-4.902 -0.177,-2.024 0.313,-4.527 1.471,-7.509 1.035,-2.592 2.345,-4.852 3.933,-6.771 1.587,-1.921 3.443,-3.411 5.565,-4.467 2.027,-1.059 4.206,-1.768 6.539,-2.125 2.327,-0.354 4.915,-0.448 7.756,-0.283 2.352,0.139 4.542,0.485 6.574,1.048 0.964,0.265 1.808,0.613 2.542,1.033 L 216.57,0.832 c -2.142,-0.202 -4.333,-0.379 -6.609,-0.51 -21.901,-1.279 -40.308,1.251 -55.229,7.576 -14.918,6.33 -24.865,15.715 -29.833,28.154 -1.491,3.814 -2.292,7.408 -2.41,10.785 l -0.01,-0.005 c -1.426,24.463 14.295,38.245 24.007,44.373 3.897,2.609 7.362,3.901 7.362,3.901 l 4.451,-14.225 1.316,-3.496 c 5.859,1.108 12.375,1.879 19.573,2.298 22.053,1.286 40.539,-1.232 55.458,-7.564 14.916,-6.325 24.78,-15.638 29.591,-27.942 4.806,-12.295 2.514,-22.357 -6.882,-30.181 z"
|
||||
style="fill:url(#linearGradient3027)"/><path
|
||||
id="path18"
|
||||
d="m 269.531,139.499 c -2.511,7.718 -8.23,13.807 -17.156,18.27 -8.926,4.463 -20.223,6.694 -33.891,6.694 -13.484,0 -23.292,-2.208 -29.43,-6.626 -6.136,-4.415 -7.904,-10.528 -5.299,-18.338 l 7.53,-23.291 h 25.663 l -7.252,23.151 c -0.931,2.883 -1.232,5.278 -0.906,7.183 0.326,1.907 1.046,3.417 2.162,4.533 1.394,1.113 2.95,1.88 4.672,2.299 1.72,0.419 3.788,0.629 6.207,0.629 2.417,0 4.742,-0.255 6.974,-0.769 2.231,-0.51 4.275,-1.323 6.138,-2.438 1.858,-1.116 3.508,-2.602 4.951,-4.463 1.44,-1.859 2.626,-4.186 3.557,-6.974 l 7.532,-23.151 h 25.663 l -7.115,23.291 z"
|
||||
style="fill:url(#linearGradient3029)"/><path
|
||||
id="path25"
|
||||
d="m 86.875,140.404 c 2.51,-7.717 0.743,-13.808 -5.301,-18.271 -6.044,-4.463 -15.899,-6.694 -29.567,-6.694 -13.483,0 -24.686,2.21 -33.611,6.625 -8.928,4.417 -14.693,10.53 -17.295,18.34 -2.51,7.72 -0.722,13.786 5.37,18.201 6.089,4.418 15.922,6.626 29.498,6.626 13.575,0 24.826,-2.208 33.753,-6.626 8.924,-4.415 14.642,-10.481 17.153,-18.201 z m -26.082,0.14 c -0.931,2.978 -2.069,5.3 -3.417,6.974 -1.349,1.675 -3.046,3.116 -5.09,4.323 -1.768,1.116 -3.765,1.883 -5.997,2.302 -2.232,0.419 -4.463,0.627 -6.696,0.627 -2.697,0 -4.999,-0.23 -6.903,-0.696 -1.907,-0.465 -3.417,-1.256 -4.533,-2.371 -1.21,-1.116 -1.906,-2.626 -2.092,-4.533 -0.188,-1.904 0.14,-4.114 0.977,-6.625 0.929,-2.88 2.161,-5.275 3.696,-7.183 1.534,-1.904 3.229,-3.417 5.09,-4.533 2.138,-1.115 4.206,-1.882 6.207,-2.301 1.999,-0.419 4.207,-0.627 6.625,-0.627 2.416,0 4.603,0.257 6.555,0.767 1.953,0.512 3.486,1.325 4.603,2.44 1.115,1.116 1.789,2.605 2.021,4.463 0.231,1.86 -0.117,4.185 -1.046,6.973 z"
|
||||
style="fill:url(#linearGradient3031)"/><path
|
||||
id="path32"
|
||||
d="m 310.14,126.807 c 2.928,-0.698 9.041,-1.046 18.339,-1.046 4.833,0 9.506,0.487 14.018,1.465 4.508,0.976 9.042,2.209 13.598,3.696 L 360,119.066 c -2.698,-0.744 -6.625,-1.487 -11.787,-2.231 -5.159,-0.744 -10.669,-1.116 -16.526,-1.116 -17.574,0 -30.405,1.513 -38.493,4.533 -8.089,3.022 -12.879,6.812 -14.366,11.366 -1.115,3.44 -0.348,6.346 2.302,8.717 2.65,2.371 7.322,4.115 14.016,5.229 2.511,0.467 6.624,0.838 12.343,1.117 5.718,0.279 9.46,0.557 11.228,0.836 3.717,0.373 6.205,0.837 7.461,1.396 1.254,0.558 1.695,1.394 1.325,2.511 -0.467,1.303 -1.976,2.279 -4.533,2.928 -2.559,0.652 -6.3,0.977 -11.227,0.977 -0.77,0 -1.513,-0.003 -2.241,-0.007 -1.846,-0.101 -3.858,-0.272 -5.791,-0.476 -2.06,-0.22 -4.118,-0.485 -6.162,-0.795 -4.089,-0.62 -8.132,-1.419 -12.058,-2.439 -3.921,-1.022 -7.734,-2.267 -11.26,-3.813 -0.474,-0.208 -0.932,-0.433 -1.394,-0.654 -2.476,3.979 -5.905,7.451 -10.27,10.396 2.259,1.085 4.539,1.976 6.807,2.742 4.52,1.506 9.034,2.52 13.525,3.266 4.494,0.741 8.969,1.203 13.431,1.472 2.231,0.133 4.459,0.215 6.691,0.248 1.966,0.026 3.882,0.02 5.902,-0.045 12.216,-0.072 22.318,-1.53 30.294,-4.386 8.18,-2.929 13.062,-6.81 14.644,-11.645 1.116,-3.349 0.441,-6.138 -2.021,-8.369 -2.466,-2.231 -6.813,-3.857 -13.041,-4.882 -2.883,-0.371 -5.768,-0.719 -8.647,-1.046 -2.884,-0.324 -5.533,-0.628 -7.951,-0.906 -9.577,-0.65 -14.924,-1.255 -16.039,-1.813 -1.116,-0.558 -1.488,-1.394 -1.116,-2.511 0.467,-1.209 2.164,-2.163 5.094,-2.859 z"
|
||||
style="fill:url(#linearGradient3033)"/><path
|
||||
id="path39"
|
||||
d="m 172.838,122.204 c -6.091,-4.415 -15.924,-6.625 -29.499,-6.625 -13.577,0 -24.826,2.21 -33.751,6.625 -8.926,4.417 -14.4,10.415 -16.911,18.131 l -0.105,0.349 -12.692,39.19 c -5.26,17.631 17.526,24.612 17.526,24.612 l 7.58,-24.612 0.656,-2.106 c 0.592,-1.982 1.192,-3.964 1.781,-5.948 l 1.686,-5.531 c 0.603,-1.832 1.207,-3.662 1.85,-5.481 l 3.979,-10.875 1.993,-5.436 1.429,-3.718 c 0.051,-0.172 0.099,-0.339 0.155,-0.514 0.836,-2.509 1.953,-4.718 3.347,-6.624 1.396,-1.904 3.069,-3.417 5.021,-4.533 1.859,-1.115 3.882,-1.904 6.067,-2.371 2.183,-0.464 4.625,-0.696 7.322,-0.696 2.231,0 4.325,0.208 6.277,0.627 1.952,0.419 3.438,1.186 4.463,2.301 1.301,1.209 2.068,2.65 2.3,4.323 0.231,1.675 -0.117,3.999 -1.046,6.974 -0.931,2.79 -2.116,5.116 -3.557,6.974 -1.442,1.862 -3.091,3.348 -4.951,4.464 -1.861,1.115 -3.905,1.931 -6.136,2.44 -2.231,0.512 -4.558,0.767 -6.973,0.767 -2.419,0 -4.487,-0.208 -6.207,-0.627 -1.721,-0.419 -3.326,-1.186 -4.812,-2.302 -0.112,-0.112 -0.201,-0.247 -0.305,-0.366 l -3.674,10.658 c -0.206,0.613 -0.403,1.228 -0.601,1.842 3.479,0.708 7.507,1.13 12.111,1.256 13.668,0 24.965,-2.231 33.893,-6.694 8.926,-4.464 14.643,-10.552 17.154,-18.271 2.511,-7.719 0.718,-13.786 -5.37,-18.203 z"
|
||||
style="fill:url(#linearGradient3035)"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.5 KiB |
244
Engine/lib/opus/doc/opus_update.patch
Normal file
244
Engine/lib/opus/doc/opus_update.patch
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
diff --git a/celt/bands.c b/celt/bands.c
|
||||
index 6962587..32e1de6 100644
|
||||
--- a/celt/bands.c
|
||||
+++ b/celt/bands.c
|
||||
@@ -1234,9 +1234,23 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
||||
b = 0;
|
||||
}
|
||||
|
||||
- if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))
|
||||
+ if (resynth && (M*eBands[i]-N >= M*eBands[start] || i==start+1) && (update_lowband || lowband_offset==0))
|
||||
lowband_offset = i;
|
||||
|
||||
+ if (i == start+1)
|
||||
+ {
|
||||
+ int n1, n2;
|
||||
+ int offset;
|
||||
+ n1 = M*(eBands[start+1]-eBands[start]);
|
||||
+ n2 = M*(eBands[start+2]-eBands[start+1]);
|
||||
+ offset = M*eBands[start];
|
||||
+ /* Duplicate enough of the first band folding data to be able to fold the second band.
|
||||
+ Copies no data for CELT-only mode. */
|
||||
+ OPUS_COPY(&norm[offset+n1], &norm[offset+2*n1 - n2], n2-n1);
|
||||
+ if (C==2)
|
||||
+ OPUS_COPY(&norm2[offset+n1], &norm2[offset+2*n1 - n2], n2-n1);
|
||||
+ }
|
||||
+
|
||||
tf_change = tf_res[i];
|
||||
if (i>=m->effEBands)
|
||||
{
|
||||
@@ -1257,7 +1271,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
||||
fold_start = lowband_offset;
|
||||
while(M*eBands[--fold_start] > effective_lowband);
|
||||
fold_end = lowband_offset-1;
|
||||
- while(M*eBands[++fold_end] < effective_lowband+N);
|
||||
+ while(++fold_end < i && M*eBands[fold_end] < effective_lowband+N);
|
||||
x_cm = y_cm = 0;
|
||||
fold_i = fold_start; do {
|
||||
x_cm |= collapse_masks[fold_i*C+0];
|
||||
diff --git a/celt/quant_bands.c b/celt/quant_bands.c
|
||||
index e5ed9ef..82fb823 100644
|
||||
--- a/celt/quant_bands.c
|
||||
+++ b/celt/quant_bands.c
|
||||
@@ -552,6 +552,7 @@ void log2Amp(const CELTMode *m, int start, int end,
|
||||
{
|
||||
opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
|
||||
SHL16((opus_val16)eMeans[i],6));
|
||||
+ lg = MIN32(QCONST32(32.f, 16), lg);
|
||||
eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
|
||||
}
|
||||
for (;i<m->nbEBands;i++)
|
||||
diff --git a/silk/LPC_inv_pred_gain.c b/silk/LPC_inv_pred_gain.c
|
||||
index 60c439b..6c301da 100644
|
||||
--- a/silk/LPC_inv_pred_gain.c
|
||||
+++ b/silk/LPC_inv_pred_gain.c
|
||||
@@ -84,8 +84,13 @@ static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inver
|
||||
|
||||
/* Update AR coefficient */
|
||||
for( n = 0; n < k; n++ ) {
|
||||
- tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 );
|
||||
- Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );
|
||||
+ opus_int64 tmp64;
|
||||
+ tmp_QA = silk_SUB_SAT32( Aold_QA[ n ], MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 ) );
|
||||
+ tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( tmp_QA, rc_mult2 ), mult2Q);
|
||||
+ if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ Anew_QA[ n ] = ( opus_int32 )tmp64;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/silk/NLSF_stabilize.c b/silk/NLSF_stabilize.c
|
||||
index 979aaba..2ef2398 100644
|
||||
--- a/silk/NLSF_stabilize.c
|
||||
+++ b/silk/NLSF_stabilize.c
|
||||
@@ -134,7 +134,7 @@ void silk_NLSF_stabilize(
|
||||
|
||||
/* Keep delta_min distance between the NLSFs */
|
||||
for( i = 1; i < L; i++ )
|
||||
- NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
|
||||
+ NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
|
||||
|
||||
/* Last NLSF should be no higher than 1 - NDeltaMin[L] */
|
||||
NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
|
||||
diff --git a/silk/dec_API.c b/silk/dec_API.c
|
||||
index efd7918..21bb7e0 100644
|
||||
--- a/silk/dec_API.c
|
||||
+++ b/silk/dec_API.c
|
||||
@@ -72,6 +72,9 @@ opus_int silk_InitDecoder( /* O Returns error co
|
||||
for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {
|
||||
ret = silk_init_decoder( &channel_state[ n ] );
|
||||
}
|
||||
+ silk_memset(&((silk_decoder *)decState)->sStereo, 0, sizeof(((silk_decoder *)decState)->sStereo));
|
||||
+ /* Not strictly needed, but it's cleaner that way */
|
||||
+ ((silk_decoder *)decState)->prev_decode_only_middle = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
diff --git a/silk/resampler_private_IIR_FIR.c b/silk/resampler_private_IIR_FIR.c
|
||||
index dbd6d9a..91a43aa 100644
|
||||
--- a/silk/resampler_private_IIR_FIR.c
|
||||
+++ b/silk/resampler_private_IIR_FIR.c
|
||||
@@ -75,10 +75,10 @@ void silk_resampler_private_IIR_FIR(
|
||||
silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
|
||||
opus_int32 nSamplesIn;
|
||||
opus_int32 max_index_Q16, index_increment_Q16;
|
||||
- opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ];
|
||||
+ opus_int16 buf[ 2*RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ];
|
||||
|
||||
/* Copy buffered samples to start of buffer */
|
||||
- silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
|
||||
+ silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
|
||||
|
||||
/* Iterate over blocks of frameSizeIn input samples */
|
||||
index_increment_Q16 = S->invRatio_Q16;
|
||||
@@ -95,13 +95,13 @@ void silk_resampler_private_IIR_FIR(
|
||||
|
||||
if( inLen > 0 ) {
|
||||
/* More iterations to do; copy last part of filtered signal to beginning of buffer */
|
||||
- silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
|
||||
+ silk_memmove( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy last part of filtered signal to the state for the next call */
|
||||
- silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
|
||||
+ silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
|
||||
}
|
||||
|
||||
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
|
||||
index 0cc56f8..8a30fbc 100644
|
||||
--- a/src/opus_decoder.c
|
||||
+++ b/src/opus_decoder.c
|
||||
@@ -595,16 +595,14 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
|
||||
/* Padding flag is bit 6 */
|
||||
if (ch&0x40)
|
||||
{
|
||||
- int padding=0;
|
||||
int p;
|
||||
do {
|
||||
if (len<=0)
|
||||
return OPUS_INVALID_PACKET;
|
||||
p = *data++;
|
||||
len--;
|
||||
- padding += p==255 ? 254: p;
|
||||
+ len -= p==255 ? 254: p;
|
||||
} while (p==255);
|
||||
- len -= padding;
|
||||
}
|
||||
if (len<0)
|
||||
return OPUS_INVALID_PACKET;
|
||||
diff --git a/run_vectors.sh b/run_vectors.sh
|
||||
index 7cd23ed..4841b0a 100755
|
||||
--- a/run_vectors.sh
|
||||
+++ b/run_vectors.sh
|
||||
@@ -1,3 +1,5 @@
|
||||
+#!/bin/sh
|
||||
+#
|
||||
# Copyright (c) 2011-2012 IETF Trust, Jean-Marc Valin. All rights reserved.
|
||||
#
|
||||
# This file is extracted from RFC6716. Please see that RFC for additional
|
||||
@@ -31,10 +33,8 @@
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
-#!/bin/sh
|
||||
-
|
||||
-rm logs_mono.txt
|
||||
-rm logs_stereo.txt
|
||||
+rm -f logs_mono.txt logs_mono2.txt
|
||||
+rm -f logs_stereo.txt logs_stereo2.txt
|
||||
|
||||
if [ "$#" -ne "3" ]; then
|
||||
echo "usage: run_vectors.sh <exec path> <vector path> <rate>"
|
||||
@@ -45,18 +45,23 @@ CMD_PATH=$1
|
||||
VECTOR_PATH=$2
|
||||
RATE=$3
|
||||
|
||||
-OPUS_DEMO=$CMD_PATH/opus_demo
|
||||
-OPUS_COMPARE=$CMD_PATH/opus_compare
|
||||
+: ${OPUS_DEMO:=$CMD_PATH/opus_demo}
|
||||
+: ${OPUS_COMPARE:=$CMD_PATH/opus_compare}
|
||||
|
||||
if [ -d $VECTOR_PATH ]; then
|
||||
echo Test vectors found in $VECTOR_PATH
|
||||
else
|
||||
echo No test vectors found
|
||||
- #Don't make the test fail here because the test vectors will be
|
||||
- #distributed separately
|
||||
+ #Don't make the test fail here because the test vectors
|
||||
+ #will be distributed separately
|
||||
exit 0
|
||||
fi
|
||||
|
||||
+if [ ! -x $OPUS_COMPARE ]; then
|
||||
+ echo ERROR: Compare program not found: $OPUS_COMPARE
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
if [ -x $OPUS_DEMO ]; then
|
||||
echo Decoding with $OPUS_DEMO
|
||||
else
|
||||
@@ -82,9 +87,11 @@ do
|
||||
echo ERROR: decoding failed
|
||||
exit 1
|
||||
fi
|
||||
- $OPUS_COMPARE -r $RATE $VECTOR_PATH/testvector$file.dec tmp.out >> logs_mono.txt 2>&1
|
||||
+ $OPUS_COMPARE -r $RATE $VECTOR_PATH/testvector${file}.dec tmp.out >> logs_mono.txt 2>&1
|
||||
float_ret=$?
|
||||
- if [ "$float_ret" -eq "0" ]; then
|
||||
+ $OPUS_COMPARE -r $RATE $VECTOR_PATH/testvector${file}m.dec tmp.out >> logs_mono2.txt 2>&1
|
||||
+ float_ret2=$?
|
||||
+ if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then
|
||||
echo output matches reference
|
||||
else
|
||||
echo ERROR: output does not match reference
|
||||
@@ -111,9 +118,11 @@ do
|
||||
echo ERROR: decoding failed
|
||||
exit 1
|
||||
fi
|
||||
- $OPUS_COMPARE -s -r $RATE $VECTOR_PATH/testvector$file.dec tmp.out >> logs_stereo.txt 2>&1
|
||||
+ $OPUS_COMPARE -s -r $RATE $VECTOR_PATH/testvector${file}.dec tmp.out >> logs_stereo.txt 2>&1
|
||||
float_ret=$?
|
||||
- if [ "$float_ret" -eq "0" ]; then
|
||||
+ $OPUS_COMPARE -s -r $RATE $VECTOR_PATH/testvector${file}m.dec tmp.out >> logs_stereo2.txt 2>&1
|
||||
+ float_ret2=$?
|
||||
+ if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then
|
||||
echo output matches reference
|
||||
else
|
||||
echo ERROR: output does not match reference
|
||||
@@ -125,5 +134,10 @@ done
|
||||
|
||||
|
||||
echo All tests have passed successfully
|
||||
-grep quality logs_mono.txt | awk '{sum+=$4}END{print "Average mono quality is", sum/NR, "%"}'
|
||||
-grep quality logs_stereo.txt | awk '{sum+=$4}END{print "Average stereo quality is", sum/NR, "%"}'
|
||||
+mono1=`grep quality logs_mono.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
|
||||
+mono2=`grep quality logs_mono2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
|
||||
+echo $mono1 $mono2 | awk '{if ($2 > $1) $1 = $2; print "Average mono quality is", $1, "%"}'
|
||||
+
|
||||
+stereo1=`grep quality logs_stereo.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
|
||||
+stereo2=`grep quality logs_stereo2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
|
||||
+echo $stereo1 $stereo2 | awk '{if ($2 > $1) $1 = $2; print "Average stereo quality is", $1, "%"}'
|
||||
43
Engine/lib/opus/doc/release.txt
Normal file
43
Engine/lib/opus/doc/release.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
= Release checklist =
|
||||
|
||||
== Source release ==
|
||||
|
||||
- Check for uncommitted changes to master.
|
||||
- Update OPUS_LT_* API versioning in configure.ac.
|
||||
- Tag the release commit with 'git tag -s vN.M'.
|
||||
- Include release notes in the tag annotation.
|
||||
- Verify 'make distcheck' produces a tarball with
|
||||
the desired name.
|
||||
- Push tag to public repo.
|
||||
- Upload source package 'opus-${version}.tar.gz'
|
||||
- Add to https://svn.xiph.org/releases/opus/
|
||||
- Update checksum files
|
||||
- svn commit
|
||||
- Copy to archive.mozilla.org/pub/opus/
|
||||
- Update checksum files there as well.
|
||||
- Add release notes to https://gitlab.xiph.org/xiph/opus-website.git
|
||||
- Update links and checksums on the downloads page.
|
||||
- Add a copy of the documentation to <https://www.opus-codec.org/docs/>
|
||||
and update the links.
|
||||
- Update /topic in #opus IRC channel.
|
||||
|
||||
Releases are commited to https://svn.xiph.org/releases/opus/
|
||||
which propagates to downloads.xiph.org, and copied manually
|
||||
to https://archive.mozilla.org/pub/opus/
|
||||
|
||||
Website updates are committed to https://gitlab.xiph.org/xiph/opus-website.git
|
||||
which propagates to https://opus-codec.org/
|
||||
|
||||
== Binary release ==
|
||||
|
||||
We usually build opus-tools binaries for MacOS and Windows.
|
||||
|
||||
Binary releases are copied manually to
|
||||
https://archive.mozilla.org/pub/opus/win32/
|
||||
|
||||
For Mac, submit a pull request to homebrew.
|
||||
|
||||
== Website updates ==
|
||||
|
||||
For major releases, recreate the files on https://opus-codec.org/examples/
|
||||
with the next encoder.
|
||||
171
Engine/lib/opus/doc/trivial_example.c
Normal file
171
Engine/lib/opus/doc/trivial_example.c
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/* Copyright (c) 2013 Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This is meant to be a simple example of encoding and decoding audio
|
||||
using Opus. It should make it easy to understand how the Opus API
|
||||
works. For more information, see the full API documentation at:
|
||||
https://www.opus-codec.org/docs/ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <opus.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*The frame size is hardcoded for this sample code but it doesn't have to be*/
|
||||
#define FRAME_SIZE 960
|
||||
#define SAMPLE_RATE 48000
|
||||
#define CHANNELS 2
|
||||
#define APPLICATION OPUS_APPLICATION_AUDIO
|
||||
#define BITRATE 64000
|
||||
|
||||
#define MAX_FRAME_SIZE 6*960
|
||||
#define MAX_PACKET_SIZE (3*1276)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *inFile;
|
||||
FILE *fin;
|
||||
char *outFile;
|
||||
FILE *fout;
|
||||
opus_int16 in[FRAME_SIZE*CHANNELS];
|
||||
opus_int16 out[MAX_FRAME_SIZE*CHANNELS];
|
||||
unsigned char cbits[MAX_PACKET_SIZE];
|
||||
int nbBytes;
|
||||
/*Holds the state of the encoder and decoder */
|
||||
OpusEncoder *encoder;
|
||||
OpusDecoder *decoder;
|
||||
int err;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
fprintf(stderr, "usage: trivial_example input.pcm output.pcm\n");
|
||||
fprintf(stderr, "input and output are 16-bit little-endian raw files\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/*Create a new encoder state */
|
||||
encoder = opus_encoder_create(SAMPLE_RATE, CHANNELS, APPLICATION, &err);
|
||||
if (err<0)
|
||||
{
|
||||
fprintf(stderr, "failed to create an encoder: %s\n", opus_strerror(err));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
/* Set the desired bit-rate. You can also set other parameters if needed.
|
||||
The Opus library is designed to have good defaults, so only set
|
||||
parameters you know you need. Doing otherwise is likely to result
|
||||
in worse quality, but better. */
|
||||
err = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(BITRATE));
|
||||
if (err<0)
|
||||
{
|
||||
fprintf(stderr, "failed to set bitrate: %s\n", opus_strerror(err));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
inFile = argv[1];
|
||||
fin = fopen(inFile, "rb");
|
||||
if (fin==NULL)
|
||||
{
|
||||
fprintf(stderr, "failed to open input file: %s\n", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new decoder state. */
|
||||
decoder = opus_decoder_create(SAMPLE_RATE, CHANNELS, &err);
|
||||
if (err<0)
|
||||
{
|
||||
fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
outFile = argv[2];
|
||||
fout = fopen(outFile, "wb");
|
||||
if (fout==NULL)
|
||||
{
|
||||
fprintf(stderr, "failed to open output file: %s\n", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
int i;
|
||||
unsigned char pcm_bytes[MAX_FRAME_SIZE*CHANNELS*2];
|
||||
int frame_size;
|
||||
size_t samples;
|
||||
|
||||
/* Read a 16 bits/sample audio frame. */
|
||||
samples = fread(pcm_bytes, sizeof(short)*CHANNELS, FRAME_SIZE, fin);
|
||||
|
||||
/* For simplicity, only read whole frames. In a real application,
|
||||
* we'd pad the final partial frame with zeroes, record the exact
|
||||
* duration, and trim the decoded audio to match.
|
||||
*/
|
||||
if (samples != FRAME_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Convert from little-endian ordering. */
|
||||
for (i=0;i<CHANNELS*FRAME_SIZE;i++)
|
||||
{
|
||||
in[i]=pcm_bytes[2*i+1]<<8|pcm_bytes[2*i];
|
||||
}
|
||||
|
||||
/* Encode the frame. */
|
||||
nbBytes = opus_encode(encoder, in, FRAME_SIZE, cbits, MAX_PACKET_SIZE);
|
||||
if (nbBytes<0)
|
||||
{
|
||||
fprintf(stderr, "encode failed: %s\n", opus_strerror(nbBytes));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/* Decode the data. In this example, frame_size will be constant because
|
||||
the encoder is using a constant frame size. However, that may not
|
||||
be the case for all encoders, so the decoder must always check
|
||||
the frame size returned. */
|
||||
frame_size = opus_decode(decoder, cbits, nbBytes, out, MAX_FRAME_SIZE, 0);
|
||||
if (frame_size<0)
|
||||
{
|
||||
fprintf(stderr, "decoder failed: %s\n", opus_strerror(frame_size));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Convert to little-endian ordering. */
|
||||
for(i=0;i<CHANNELS*frame_size;i++)
|
||||
{
|
||||
pcm_bytes[2*i]=out[i]&0xFF;
|
||||
pcm_bytes[2*i+1]=(out[i]>>8)&0xFF;
|
||||
}
|
||||
/* Write the decoded audio to file. */
|
||||
fwrite(pcm_bytes, sizeof(short), frame_size*CHANNELS, fout);
|
||||
}
|
||||
/*Destroy the encoder state*/
|
||||
opus_encoder_destroy(encoder);
|
||||
opus_decoder_destroy(decoder);
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue