Network Working Group JM. Valin
Internet-Draft Mozilla Corporation
Updates: 6716 (if approved) K. Vos
Intended status: Standards Track vocTone
Expires: January 17, 2018 July 16, 2017
Updates to the Opus Audio Codecdraft-ietf-codec-opus-update-07
Abstract
This document addresses minor issues that were found in the
specification of the Opus audio codec in RFC 6716.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on January 17, 2018.
Copyright Notice
Copyright (c) 2017 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.
Valin & Vos Expires January 17, 2018 [Page 1]

Internet-Draft Opus Update July 20173. Stereo State Reset in SILK
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:
<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>
This change affects the normative part of the decoder, although the
amount of change is too small to make a significant impact on
testvectors.
4. Parsing of the Opus Packet Padding
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 applying the following changes at
line 596 of src/opus_decoder.c:
Valin & Vos Expires January 17, 2018 [Page 3]

Internet-Draft Opus Update July 2017
<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>
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.
5. Resampler buffer
The SILK resampler had the following issues:
1. The calls to memcpy() were using sizeof(opus_int32), but the type
of the local buffer was opus_int16.
2. Because the size was wrong, this potentially allowed the source
and destination regions of the memcpy() to overlap. We _believe_
that nSamplesIn is at least fs_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.
3. The size of the buffer used RESAMPLER_MAX_BATCH_SIZE_IN, but the
data stored in it was actually _twice_ the input batch size
(nSamplesIn<<1).
The fact that the code never produced any error in testing (including
when run under the Valgrind memory debugger), suggests that in
practice the batch sizes are reasonable enough that none of the
issues above was ever a problem. However, proving that is non-
obvious.
Valin & Vos Expires January 17, 2018 [Page 4]

Internet-Draft Opus Update July 2017
<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>
8. Cap on Band Energy
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, 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:
<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>
9. Hybrid Folding
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 LCG noise. Because it can also happen on transients
(e.g. stops), it can cause audible pre-echo.
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:
Valin & Vos Expires January 17, 2018 [Page 7]

Internet-Draft Opus Update July 2017
reasonable way for an encoder to use the original behavior to improve
quality over the proposed change.
10. Downmix to Mono
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
artefacts.
As a work-around for this issue, the decoder MAY choose not to apply
the 180-degree phase shift when the output is meant to be downmixed
(inside or outside of the decoder).
11. New Test Vectors
Changes in Section 9 and Section 10 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
Section 10, while the outputs without the suffix do. An
implementation is compliant as long as it passes either set of
vectors.
In addition, any Opus implementation that passes the original test
vectors from RFC 6716 [RFC6716] is still compliant with the Opus
specification. However, newer implementations SHOULD be based on the
new test vectors rather than the old ones.
The new test vectors are located at
<https://www.ietf.org/proceedings/98/slides/materials-98-codec-opus-newvectors-00.tar.gz>.
12. Security Considerations
This document adds no new security considerations on top of RFC 6716
[RFC6716].
Valin & Vos Expires January 17, 2018 [Page 9]