OLD | NEW |
(Empty) | |
| 1 <?xml version="1.0" encoding="US-ASCII"?> |
| 2 <!DOCTYPE rfc SYSTEM "rfc2629.dtd"> |
| 3 <?rfc toc="yes"?> |
| 4 <?rfc tocompact="yes"?> |
| 5 <?rfc tocdepth="3"?> |
| 6 <?rfc tocindent="yes"?> |
| 7 <?rfc symrefs="yes"?> |
| 8 <?rfc sortrefs="yes"?> |
| 9 <?rfc comments="yes"?> |
| 10 <?rfc inline="yes"?> |
| 11 <?rfc compact="yes"?> |
| 12 <?rfc subcompact="no"?> |
| 13 <rfc category="std" docName="draft-valin-codec-opus-update-00" |
| 14 ipr="trust200902"> |
| 15 <front> |
| 16 <title abbrev="Opus Update">Updates to the Opus Audio Codec</title> |
| 17 |
| 18 <author initials="JM" surname="Valin" fullname="Jean-Marc Valin"> |
| 19 <organization>Mozilla Corporation</organization> |
| 20 <address> |
| 21 <postal> |
| 22 <street>650 Castro Street</street> |
| 23 <city>Mountain View</city> |
| 24 <region>CA</region> |
| 25 <code>94041</code> |
| 26 <country>USA</country> |
| 27 </postal> |
| 28 <phone>+1 650 903-0800</phone> |
| 29 <email>jmvalin@jmvalin.ca</email> |
| 30 </address> |
| 31 </author> |
| 32 |
| 33 <author initials="T." surname="Terriberry" fullname="Timothy B. Terriberry"> |
| 34 <organization>Mozilla Corporation</organization> |
| 35 <address> |
| 36 <postal> |
| 37 <street>650 Castro Street</street> |
| 38 <city>Mountain View</city> |
| 39 <region>CA</region> |
| 40 <code>94041</code> |
| 41 <country>USA</country> |
| 42 </postal> |
| 43 <phone>+1 650 903-0800</phone> |
| 44 <email>tterriberry@mozilla.com</email> |
| 45 </address> |
| 46 </author> |
| 47 |
| 48 <author initials="K." surname="Vos" fullname="Koen Vos"> |
| 49 <organization>Skype Technologies S.A.</organization> |
| 50 <address> |
| 51 <postal> |
| 52 <street>Soder Malarstrand 43</street> |
| 53 <city>Stockholm</city> |
| 54 <region></region> |
| 55 <code>11825</code> |
| 56 <country>SE</country> |
| 57 </postal> |
| 58 <phone>+46 73 085 7619</phone> |
| 59 <email>koen.vos@skype.net</email> |
| 60 </address> |
| 61 </author> |
| 62 |
| 63 |
| 64 |
| 65 <date day="12" month="July" year="2013" /> |
| 66 |
| 67 <abstract> |
| 68 <t>This document addresses minor issues that were found in the specificati
on |
| 69 of the Opus audio codec in <xref target="RFC6716">RFC 6716</xref>.</t> |
| 70 </abstract> |
| 71 </front> |
| 72 |
| 73 <middle> |
| 74 <section title="Introduction"> |
| 75 <t>This document address minor issues that were discovered in the referenc
e |
| 76 implementation of the Opus codec that serves as the specification in |
| 77 <xref target="RFC6716">RFC 6716</xref>. Only issues affecting the decoder
are |
| 78 listed here. An up-to-date implementation of the Opus encoder can be found
at |
| 79 http://opus-codec.org/. The updated specification remains fully compatible
with |
| 80 the original specification and only one of the changes results in any diff
erence |
| 81 in the audio output. |
| 82 </t> |
| 83 </section> |
| 84 |
| 85 <section title="Terminology"> |
| 86 <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", |
| 87 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this |
| 88 document are to be interpreted as described in <xref |
| 89 target="RFC2119">RFC 2119</xref>.</t> |
| 90 </section> |
| 91 |
| 92 <section title="Stereo State Reset in SILK"> |
| 93 <t>The reference implementation does not reinitialize the stereo state |
| 94 during a mode switch. The old stereo memory can produce a brief impulse |
| 95 (i.e. single sample) in the decoded audio. This can be fixed by changing |
| 96 silk/dec_API.c at line 72: |
| 97 <figure> |
| 98 <artwork><![CDATA[ |
| 99 for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) { |
| 100 ret = silk_init_decoder( &channel_state[ n ] ); |
| 101 } |
| 102 + silk_memset(&((silk_decoder *)decState)->sStereo, 0, |
| 103 + sizeof(((silk_decoder *)decState)->sStereo)); |
| 104 + /* Not strictly needed, but it's cleaner that way */ |
| 105 + ((silk_decoder *)decState)->prev_decode_only_middle = 0; |
| 106 |
| 107 return ret; |
| 108 } |
| 109 ]]></artwork> |
| 110 </figure> |
| 111 This change affects the normative part of the decoder. Fortunately, |
| 112 the modified decoder is still compliant with the original specification bec
ause |
| 113 it still easily passes the testvectors. For example, for the float decoder |
| 114 at 48 kHz, the opus_compare (arbitrary) "quality score" changes from |
| 115 from 99.9333% to 99.925%. |
| 116 </t> |
| 117 </section> |
| 118 |
| 119 <section anchor="padding" title="Parsing of the Opus Packet Padding"> |
| 120 <t>It was discovered that some invalid packets of very large size could tr
igger |
| 121 an out-of-bounds read in the Opus packet parsing code responsible for padd
ing. |
| 122 This is due to an integer overflow if the signaled padding exceeds 2^31-1
bytes |
| 123 (the actual packet may be smaller). The code can be fixed by applying the
following |
| 124 changes at line 596 of src/opus_decoder.c: |
| 125 <figure> |
| 126 <artwork><![CDATA[ |
| 127 /* Padding flag is bit 6 */ |
| 128 if (ch&0x40) |
| 129 { |
| 130 - int padding=0; |
| 131 int p; |
| 132 do { |
| 133 if (len<=0) |
| 134 return OPUS_INVALID_PACKET; |
| 135 p = *data++; |
| 136 len--; |
| 137 - padding += p==255 ? 254: p; |
| 138 + len -= p==255 ? 254: p; |
| 139 } while (p==255); |
| 140 - len -= padding; |
| 141 } |
| 142 ]]></artwork> |
| 143 </figure> |
| 144 </t> |
| 145 <t>This packet parsing issue is limited to reading memory up |
| 146 to about 60 kB beyond the compressed buffer. This can only be triggered |
| 147 by a compressed packet more than about 16 MB long, so it's not a proble
m |
| 148 for RTP. In theory, it <spanx style="emph">could</spanx> crash a file |
| 149 decoder (e.g. Opus in Ogg) if the memory just after the incoming packet |
| 150 is out-of-range, but that could not be achieved when attempted in a pro
duction |
| 151 application built using an affected version of the Opus decoder.</t> |
| 152 </section> |
| 153 |
| 154 <section anchor="resampler" title="Resampler buffer"> |
| 155 <t>The SILK resampler had the following issues: |
| 156 <list style="numbers"> |
| 157 <t>The calls to memcpy() were using sizeof(opus_int32), but the type of the |
| 158 local buffer was opus_int16.</t> |
| 159 <t>Because the size was wrong, this potentially allowed the source |
| 160 and destination regions of the memcpy overlap. |
| 161 We <spanx style="emph">believe</spanx> that nSamplesIn is at least fs_
in_khZ, |
| 162 which is at least 8. |
| 163 Since RESAMPLER_ORDER_FIR_12 is only 8,that should not be a problem once |
| 164 the type size is fixed.</t> |
| 165 <t>The size of the buffer used RESAMPLER_MAX_BATCH_SIZE_IN, but the |
| 166 data stored in it was actually _twice_ the input batch size |
| 167 (nSamplesIn<<1).</t> |
| 168 </list></t> |
| 169 <t> |
| 170 The fact that the code never produced any error in testing (including when
run under the |
| 171 Valgrind memory debugger), suggests that in practice |
| 172 the batch sizes are reasonable enough that none of the issues above |
| 173 was ever a problem. However, proving that is non-obvious. |
| 174 </t> |
| 175 <t>The code can be fixed by applying the following changes to like 70 of sil
k/resampler_private_IIR_FIR.c: |
| 176 <figure> |
| 177 <artwork><![CDATA[ |
| 178 opus_int16 out[], /* O Output signal
*/ |
| 179 const opus_int16 in[], /* I Input signal
*/ |
| 180 opus_int32 inLen /* I Number of input sam
ples */ |
| 181 ) |
| 182 { |
| 183 silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; |
| 184 opus_int32 nSamplesIn; |
| 185 opus_int32 max_index_Q16, index_increment_Q16; |
| 186 - opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ]; |
| 187 + opus_int16 buf[ 2*RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ]; |
| 188 |
| 189 /* Copy buffered samples to start of buffer */ |
| 190 - silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); |
| 191 + silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); |
| 192 |
| 193 /* Iterate over blocks of frameSizeIn input samples */ |
| 194 index_increment_Q16 = S->invRatio_Q16; |
| 195 while( 1 ) { |
| 196 nSamplesIn = silk_min( inLen, S->batchSize ); |
| 197 |
| 198 /* Upsample 2x */ |
| 199 silk_resampler_private_up2_HQ( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_12 ],
in, nSamplesIn ); |
| 200 |
| 201 max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 ); /* + 1 bec
ause 2x upsampling */ |
| 202 out = silk_resampler_private_IIR_FIR_INTERPOL( out, buf, max_index_Q16,
index_increment_Q16 ); |
| 203 in += nSamplesIn; |
| 204 inLen -= nSamplesIn; |
| 205 |
| 206 if( inLen > 0 ) { |
| 207 /* More iterations to do; copy last part of filtered signal to begi
nning of buffer */ |
| 208 - silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 *
sizeof( opus_int32 ) ); |
| 209 + silk_memmove( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12
* sizeof( opus_int16 ) ); |
| 210 } else { |
| 211 break; |
| 212 } |
| 213 } |
| 214 |
| 215 /* Copy last part of filtered signal to the state for the next call */ |
| 216 - silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * siz
eof( opus_int32 ) ); |
| 217 + silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * siz
eof( opus_int16 ) ); |
| 218 } |
| 219 ]]></artwork> |
| 220 </figure> |
| 221 </t> |
| 222 </section> |
| 223 |
| 224 <section title="Downmix to Mono"> |
| 225 <t>The last issue is not strictly a bug, but it is an issue that has been
reported |
| 226 when downmixing Opus decoded stream to mono, whether this is done inside t
he decoder |
| 227 or as a post-processing on the stereo decoder output. Opus intensity stere
o allows |
| 228 optionally coding the two channels 180-degrees out of phase on a per-band
basis. |
| 229 This provides better stereo quality than forcing the two channels to be in
phase, |
| 230 but when the output is downmixed to mono, the energy in the affected bands
is cancelled |
| 231 sometimes resulting in audible artefacts. |
| 232 </t> |
| 233 <t>A possible work-around for this issue would be to optionally allow the
decoder to |
| 234 not apply the 180-degree phase shift when the output is meant to be downmi
xed (inside or |
| 235 outside of the decoder). |
| 236 </t> |
| 237 </section> |
| 238 <section anchor="IANA" title="IANA Considerations"> |
| 239 <t>This document makes no request of IANA.</t> |
| 240 |
| 241 <t>Note to RFC Editor: this section may be removed on publication as an |
| 242 RFC.</t> |
| 243 </section> |
| 244 |
| 245 <section anchor="Acknowledgements" title="Acknowledgements"> |
| 246 <t>We would like to thank Juri Aedla for reporting the issue with the pars
ing of |
| 247 the Opus padding.</t> |
| 248 </section> |
| 249 </middle> |
| 250 |
| 251 <back> |
| 252 <references title="References"> |
| 253 <?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.211
9.xml"?> |
| 254 <?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.671
6.xml"?> |
| 255 |
| 256 |
| 257 </references> |
| 258 </back> |
| 259 </rfc> |
OLD | NEW |