early-access version 1255

This commit is contained in:
pineappleEA
2020-12-28 15:15:37 +00:00
parent 84b39492d1
commit 78b48028e1
6254 changed files with 1868140 additions and 0 deletions

335
externals/opus/opus/doc/Doxyfile.in vendored Executable file
View File

@@ -0,0 +1,335 @@
# Doxyfile 1.8.10
# 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
# and 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 http://www.mathjax.org before deployment.
# The default value is: http://cdn.mathjax.org/mathjax/latest.
# 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.
# 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@

45
externals/opus/opus/doc/Makefile.am vendored Executable file
View 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

104
externals/opus/opus/doc/build_draft.sh vendored Executable file
View File

@@ -0,0 +1,104 @@
#!/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}/celt"
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
externals/opus/opus/doc/build_isobmff.sh vendored Executable file
View 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
externals/opus/opus/doc/build_oggdraft.sh vendored Executable file
View 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
externals/opus/opus/doc/customdoxygen.css vendored Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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&lt;&lt;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>

File diff suppressed because it is too large Load Diff

View 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 "&#160;">
]>
<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&nbsp;kb/s to 510&nbsp;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&nbsp;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&nbsp;<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&nbsp;<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&nbsp;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&nbsp;ms of speech or audio data. The grouping of one or more Opus
frames into a single Opus packet is defined in Section&nbsp;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&nbsp;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&nbsp;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&nbsp;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 &amp; 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&nbsp;6.3 of&nbsp;<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&nbsp;6.3 of&nbsp;<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>

28
externals/opus/opus/doc/footer.html vendored Executable file
View File

@@ -0,0 +1,28 @@
<!--BEGIN GENERATE_TREEVIEW-->
<li class="footer">Generated by
<a href="https://www.stack.nl/~dimitri/doxygen/">
<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="https://www.stack.nl/~dimitri/doxygen/">doxygen</a>
$doxygenversion
</small></address>
</td>
</tr>
</tbody>
</table>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

54
externals/opus/opus/doc/header.html vendored Executable file
View File

@@ -0,0 +1,54 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://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"/>
<!--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"/>
<link href="$relpath$customdoxygen.css" rel="stylesheet" type="text/css" />
$treeview
$search
$mathjax
</head>
<body>
<div id="top"><!-- do not remove this div! -->
<!--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-->

60
externals/opus/opus/doc/opus_in_isobmff.css vendored Executable file
View 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
externals/opus/opus/doc/opus_in_isobmff.html vendored Executable file
View 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&lt&lt16.
+ 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 &lt&lt 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
externals/opus/opus/doc/opus_logo.svg vendored Executable file
View 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
externals/opus/opus/doc/opus_update.patch vendored Executable file
View 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
externals/opus/opus/doc/release.txt vendored Executable file
View 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://git.xiph.org/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://git.xiph.org/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.

160
externals/opus/opus/doc/trivial_example.c vendored Executable file
View File

@@ -0,0 +1,160 @@
/* 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, "r");
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, "w");
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;
/* Read a 16 bits/sample audio frame. */
fread(pcm_bytes, sizeof(short)*CHANNELS, FRAME_SIZE, fin);
if (feof(fin))
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;
}