• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_coding/codecs/opus/opus_interface.h"
12 
13 #include <cstdlib>
14 
15 #include "rtc_base/checks.h"
16 #include "system_wrappers/include/field_trial.h"
17 
18 enum {
19 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME
20   /* Maximum supported frame size in WebRTC is 120 ms. */
21   kWebRtcOpusMaxEncodeFrameSizeMs = 120,
22 #else
23   /* Maximum supported frame size in WebRTC is 60 ms. */
24   kWebRtcOpusMaxEncodeFrameSizeMs = 60,
25 #endif
26 
27   /* The format allows up to 120 ms frames. Since we don't control the other
28    * side, we must allow for packets of that size. NetEq is currently limited
29    * to 60 ms on the receive side. */
30   kWebRtcOpusMaxDecodeFrameSizeMs = 120,
31 
32   // Duration of audio that each call to packet loss concealment covers.
33   kWebRtcOpusPlcFrameSizeMs = 10,
34 };
35 
36 constexpr char kPlcUsePrevDecodedSamplesFieldTrial[] =
37     "WebRTC-Audio-OpusPlcUsePrevDecodedSamples";
38 
FrameSizePerChannel(int frame_size_ms,int sample_rate_hz)39 static int FrameSizePerChannel(int frame_size_ms, int sample_rate_hz) {
40   RTC_DCHECK_GT(frame_size_ms, 0);
41   RTC_DCHECK_EQ(frame_size_ms % 10, 0);
42   RTC_DCHECK_GT(sample_rate_hz, 0);
43   RTC_DCHECK_EQ(sample_rate_hz % 1000, 0);
44   return frame_size_ms * (sample_rate_hz / 1000);
45 }
46 
47 // Maximum sample count per channel.
MaxFrameSizePerChannel(int sample_rate_hz)48 static int MaxFrameSizePerChannel(int sample_rate_hz) {
49   return FrameSizePerChannel(kWebRtcOpusMaxDecodeFrameSizeMs, sample_rate_hz);
50 }
51 
52 // Default sample count per channel.
DefaultFrameSizePerChannel(int sample_rate_hz)53 static int DefaultFrameSizePerChannel(int sample_rate_hz) {
54   return FrameSizePerChannel(20, sample_rate_hz);
55 }
56 
WebRtcOpus_EncoderCreate(OpusEncInst ** inst,size_t channels,int32_t application,int sample_rate_hz)57 int16_t WebRtcOpus_EncoderCreate(OpusEncInst** inst,
58                                  size_t channels,
59                                  int32_t application,
60                                  int sample_rate_hz) {
61   int opus_app;
62   if (!inst)
63     return -1;
64 
65   switch (application) {
66     case 0:
67       opus_app = OPUS_APPLICATION_VOIP;
68       break;
69     case 1:
70       opus_app = OPUS_APPLICATION_AUDIO;
71       break;
72     default:
73       return -1;
74   }
75 
76   OpusEncInst* state =
77       reinterpret_cast<OpusEncInst*>(calloc(1, sizeof(OpusEncInst)));
78   RTC_DCHECK(state);
79 
80   int error;
81   state->encoder = opus_encoder_create(
82       sample_rate_hz, static_cast<int>(channels), opus_app, &error);
83 
84   if (error != OPUS_OK || (!state->encoder && !state->multistream_encoder)) {
85     WebRtcOpus_EncoderFree(state);
86     return -1;
87   }
88 
89   state->in_dtx_mode = 0;
90   state->channels = channels;
91 
92   *inst = state;
93   return 0;
94 }
95 
WebRtcOpus_MultistreamEncoderCreate(OpusEncInst ** inst,size_t channels,int32_t application,size_t streams,size_t coupled_streams,const unsigned char * channel_mapping)96 int16_t WebRtcOpus_MultistreamEncoderCreate(
97     OpusEncInst** inst,
98     size_t channels,
99     int32_t application,
100     size_t streams,
101     size_t coupled_streams,
102     const unsigned char* channel_mapping) {
103   int opus_app;
104   if (!inst)
105     return -1;
106 
107   switch (application) {
108     case 0:
109       opus_app = OPUS_APPLICATION_VOIP;
110       break;
111     case 1:
112       opus_app = OPUS_APPLICATION_AUDIO;
113       break;
114     default:
115       return -1;
116   }
117 
118   OpusEncInst* state =
119       reinterpret_cast<OpusEncInst*>(calloc(1, sizeof(OpusEncInst)));
120   RTC_DCHECK(state);
121 
122   int error;
123   state->multistream_encoder =
124       opus_multistream_encoder_create(48000, channels, streams, coupled_streams,
125                                       channel_mapping, opus_app, &error);
126 
127   if (error != OPUS_OK || (!state->encoder && !state->multistream_encoder)) {
128     WebRtcOpus_EncoderFree(state);
129     return -1;
130   }
131 
132   state->in_dtx_mode = 0;
133   state->channels = channels;
134 
135   *inst = state;
136   return 0;
137 }
138 
WebRtcOpus_EncoderFree(OpusEncInst * inst)139 int16_t WebRtcOpus_EncoderFree(OpusEncInst* inst) {
140   if (inst) {
141     if (inst->encoder) {
142       opus_encoder_destroy(inst->encoder);
143     } else {
144       opus_multistream_encoder_destroy(inst->multistream_encoder);
145     }
146     free(inst);
147     return 0;
148   } else {
149     return -1;
150   }
151 }
152 
WebRtcOpus_Encode(OpusEncInst * inst,const int16_t * audio_in,size_t samples,size_t length_encoded_buffer,uint8_t * encoded)153 int WebRtcOpus_Encode(OpusEncInst* inst,
154                       const int16_t* audio_in,
155                       size_t samples,
156                       size_t length_encoded_buffer,
157                       uint8_t* encoded) {
158   int res;
159 
160   if (samples > 48 * kWebRtcOpusMaxEncodeFrameSizeMs) {
161     return -1;
162   }
163 
164   if (inst->encoder) {
165     res = opus_encode(inst->encoder, (const opus_int16*)audio_in,
166                       static_cast<int>(samples), encoded,
167                       static_cast<opus_int32>(length_encoded_buffer));
168   } else {
169     res = opus_multistream_encode(
170         inst->multistream_encoder, (const opus_int16*)audio_in,
171         static_cast<int>(samples), encoded,
172         static_cast<opus_int32>(length_encoded_buffer));
173   }
174 
175   if (res <= 0) {
176     return -1;
177   }
178 
179   if (res <= 2) {
180     // Indicates DTX since the packet has nothing but a header. In principle,
181     // there is no need to send this packet. However, we do transmit the first
182     // occurrence to let the decoder know that the encoder enters DTX mode.
183     if (inst->in_dtx_mode) {
184       return 0;
185     } else {
186       inst->in_dtx_mode = 1;
187       return res;
188     }
189   }
190 
191   inst->in_dtx_mode = 0;
192   return res;
193 }
194 
195 #define ENCODER_CTL(inst, vargs)                \
196   (inst->encoder                                \
197        ? opus_encoder_ctl(inst->encoder, vargs) \
198        : opus_multistream_encoder_ctl(inst->multistream_encoder, vargs))
199 
WebRtcOpus_SetBitRate(OpusEncInst * inst,int32_t rate)200 int16_t WebRtcOpus_SetBitRate(OpusEncInst* inst, int32_t rate) {
201   if (inst) {
202     return ENCODER_CTL(inst, OPUS_SET_BITRATE(rate));
203   } else {
204     return -1;
205   }
206 }
207 
WebRtcOpus_SetPacketLossRate(OpusEncInst * inst,int32_t loss_rate)208 int16_t WebRtcOpus_SetPacketLossRate(OpusEncInst* inst, int32_t loss_rate) {
209   if (inst) {
210     return ENCODER_CTL(inst, OPUS_SET_PACKET_LOSS_PERC(loss_rate));
211   } else {
212     return -1;
213   }
214 }
215 
WebRtcOpus_SetMaxPlaybackRate(OpusEncInst * inst,int32_t frequency_hz)216 int16_t WebRtcOpus_SetMaxPlaybackRate(OpusEncInst* inst, int32_t frequency_hz) {
217   opus_int32 set_bandwidth;
218 
219   if (!inst)
220     return -1;
221 
222   if (frequency_hz <= 8000) {
223     set_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
224   } else if (frequency_hz <= 12000) {
225     set_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
226   } else if (frequency_hz <= 16000) {
227     set_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
228   } else if (frequency_hz <= 24000) {
229     set_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
230   } else {
231     set_bandwidth = OPUS_BANDWIDTH_FULLBAND;
232   }
233   return ENCODER_CTL(inst, OPUS_SET_MAX_BANDWIDTH(set_bandwidth));
234 }
235 
WebRtcOpus_GetMaxPlaybackRate(OpusEncInst * const inst,int32_t * result_hz)236 int16_t WebRtcOpus_GetMaxPlaybackRate(OpusEncInst* const inst,
237                                       int32_t* result_hz) {
238   if (inst->encoder) {
239     if (opus_encoder_ctl(inst->encoder, OPUS_GET_MAX_BANDWIDTH(result_hz)) ==
240         OPUS_OK) {
241       return 0;
242     }
243     return -1;
244   }
245 
246   opus_int32 max_bandwidth;
247   int s;
248   int ret;
249 
250   max_bandwidth = 0;
251   ret = OPUS_OK;
252   s = 0;
253   while (ret == OPUS_OK) {
254     OpusEncoder* enc;
255     opus_int32 bandwidth;
256 
257     ret = ENCODER_CTL(inst, OPUS_MULTISTREAM_GET_ENCODER_STATE(s, &enc));
258     if (ret == OPUS_BAD_ARG)
259       break;
260     if (ret != OPUS_OK)
261       return -1;
262     if (opus_encoder_ctl(enc, OPUS_GET_MAX_BANDWIDTH(&bandwidth)) != OPUS_OK)
263       return -1;
264 
265     if (max_bandwidth != 0 && max_bandwidth != bandwidth)
266       return -1;
267 
268     max_bandwidth = bandwidth;
269     s++;
270   }
271   *result_hz = max_bandwidth;
272   return 0;
273 }
274 
WebRtcOpus_EnableFec(OpusEncInst * inst)275 int16_t WebRtcOpus_EnableFec(OpusEncInst* inst) {
276   if (inst) {
277     return ENCODER_CTL(inst, OPUS_SET_INBAND_FEC(1));
278   } else {
279     return -1;
280   }
281 }
282 
WebRtcOpus_DisableFec(OpusEncInst * inst)283 int16_t WebRtcOpus_DisableFec(OpusEncInst* inst) {
284   if (inst) {
285     return ENCODER_CTL(inst, OPUS_SET_INBAND_FEC(0));
286   } else {
287     return -1;
288   }
289 }
290 
WebRtcOpus_EnableDtx(OpusEncInst * inst)291 int16_t WebRtcOpus_EnableDtx(OpusEncInst* inst) {
292   if (!inst) {
293     return -1;
294   }
295 
296   // To prevent Opus from entering CELT-only mode by forcing signal type to
297   // voice to make sure that DTX behaves correctly. Currently, DTX does not
298   // last long during a pure silence, if the signal type is not forced.
299   // TODO(minyue): Remove the signal type forcing when Opus DTX works properly
300   // without it.
301   int ret = ENCODER_CTL(inst, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
302   if (ret != OPUS_OK)
303     return ret;
304 
305   return ENCODER_CTL(inst, OPUS_SET_DTX(1));
306 }
307 
WebRtcOpus_DisableDtx(OpusEncInst * inst)308 int16_t WebRtcOpus_DisableDtx(OpusEncInst* inst) {
309   if (inst) {
310     int ret = ENCODER_CTL(inst, OPUS_SET_SIGNAL(OPUS_AUTO));
311     if (ret != OPUS_OK)
312       return ret;
313     return ENCODER_CTL(inst, OPUS_SET_DTX(0));
314   } else {
315     return -1;
316   }
317 }
318 
WebRtcOpus_EnableCbr(OpusEncInst * inst)319 int16_t WebRtcOpus_EnableCbr(OpusEncInst* inst) {
320   if (inst) {
321     return ENCODER_CTL(inst, OPUS_SET_VBR(0));
322   } else {
323     return -1;
324   }
325 }
326 
WebRtcOpus_DisableCbr(OpusEncInst * inst)327 int16_t WebRtcOpus_DisableCbr(OpusEncInst* inst) {
328   if (inst) {
329     return ENCODER_CTL(inst, OPUS_SET_VBR(1));
330   } else {
331     return -1;
332   }
333 }
334 
WebRtcOpus_SetComplexity(OpusEncInst * inst,int32_t complexity)335 int16_t WebRtcOpus_SetComplexity(OpusEncInst* inst, int32_t complexity) {
336   if (inst) {
337     return ENCODER_CTL(inst, OPUS_SET_COMPLEXITY(complexity));
338   } else {
339     return -1;
340   }
341 }
342 
WebRtcOpus_GetBandwidth(OpusEncInst * inst)343 int32_t WebRtcOpus_GetBandwidth(OpusEncInst* inst) {
344   if (!inst) {
345     return -1;
346   }
347   int32_t bandwidth;
348   if (ENCODER_CTL(inst, OPUS_GET_BANDWIDTH(&bandwidth)) == 0) {
349     return bandwidth;
350   } else {
351     return -1;
352   }
353 }
354 
WebRtcOpus_SetBandwidth(OpusEncInst * inst,int32_t bandwidth)355 int16_t WebRtcOpus_SetBandwidth(OpusEncInst* inst, int32_t bandwidth) {
356   if (inst) {
357     return ENCODER_CTL(inst, OPUS_SET_BANDWIDTH(bandwidth));
358   } else {
359     return -1;
360   }
361 }
362 
WebRtcOpus_SetForceChannels(OpusEncInst * inst,size_t num_channels)363 int16_t WebRtcOpus_SetForceChannels(OpusEncInst* inst, size_t num_channels) {
364   if (!inst)
365     return -1;
366   if (num_channels == 0) {
367     return ENCODER_CTL(inst, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO));
368   } else if (num_channels == 1 || num_channels == 2) {
369     return ENCODER_CTL(inst, OPUS_SET_FORCE_CHANNELS(num_channels));
370   } else {
371     return -1;
372   }
373 }
374 
WebRtcOpus_GetInDtx(OpusEncInst * inst)375 int32_t WebRtcOpus_GetInDtx(OpusEncInst* inst) {
376   if (!inst) {
377     return -1;
378   }
379 #ifdef OPUS_GET_IN_DTX
380   int32_t in_dtx;
381   if (ENCODER_CTL(inst, OPUS_GET_IN_DTX(&in_dtx)) == 0) {
382     return in_dtx;
383   }
384 #endif
385   return -1;
386 }
387 
WebRtcOpus_DecoderCreate(OpusDecInst ** inst,size_t channels,int sample_rate_hz)388 int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst,
389                                  size_t channels,
390                                  int sample_rate_hz) {
391   int error;
392   OpusDecInst* state;
393 
394   if (inst != NULL) {
395     // Create Opus decoder state.
396     state = reinterpret_cast<OpusDecInst*>(calloc(1, sizeof(OpusDecInst)));
397     if (state == NULL) {
398       return -1;
399     }
400 
401     state->decoder =
402         opus_decoder_create(sample_rate_hz, static_cast<int>(channels), &error);
403     if (error == OPUS_OK && state->decoder) {
404       // Creation of memory all ok.
405       state->channels = channels;
406       state->sample_rate_hz = sample_rate_hz;
407       state->plc_use_prev_decoded_samples =
408           webrtc::field_trial::IsEnabled(kPlcUsePrevDecodedSamplesFieldTrial);
409       if (state->plc_use_prev_decoded_samples) {
410         state->prev_decoded_samples =
411             DefaultFrameSizePerChannel(state->sample_rate_hz);
412       }
413       state->in_dtx_mode = 0;
414       *inst = state;
415       return 0;
416     }
417 
418     // If memory allocation was unsuccessful, free the entire state.
419     if (state->decoder) {
420       opus_decoder_destroy(state->decoder);
421     }
422     free(state);
423   }
424   return -1;
425 }
426 
WebRtcOpus_MultistreamDecoderCreate(OpusDecInst ** inst,size_t channels,size_t streams,size_t coupled_streams,const unsigned char * channel_mapping)427 int16_t WebRtcOpus_MultistreamDecoderCreate(
428     OpusDecInst** inst,
429     size_t channels,
430     size_t streams,
431     size_t coupled_streams,
432     const unsigned char* channel_mapping) {
433   int error;
434   OpusDecInst* state;
435 
436   if (inst != NULL) {
437     // Create Opus decoder state.
438     state = reinterpret_cast<OpusDecInst*>(calloc(1, sizeof(OpusDecInst)));
439     if (state == NULL) {
440       return -1;
441     }
442 
443     // Create new memory, always at 48000 Hz.
444     state->multistream_decoder = opus_multistream_decoder_create(
445         48000, channels, streams, coupled_streams, channel_mapping, &error);
446 
447     if (error == OPUS_OK && state->multistream_decoder) {
448       // Creation of memory all ok.
449       state->channels = channels;
450       state->sample_rate_hz = 48000;
451       state->plc_use_prev_decoded_samples =
452           webrtc::field_trial::IsEnabled(kPlcUsePrevDecodedSamplesFieldTrial);
453       if (state->plc_use_prev_decoded_samples) {
454         state->prev_decoded_samples =
455             DefaultFrameSizePerChannel(state->sample_rate_hz);
456       }
457       state->in_dtx_mode = 0;
458       *inst = state;
459       return 0;
460     }
461 
462     // If memory allocation was unsuccessful, free the entire state.
463     opus_multistream_decoder_destroy(state->multistream_decoder);
464     free(state);
465   }
466   return -1;
467 }
468 
WebRtcOpus_DecoderFree(OpusDecInst * inst)469 int16_t WebRtcOpus_DecoderFree(OpusDecInst* inst) {
470   if (inst) {
471     if (inst->decoder) {
472       opus_decoder_destroy(inst->decoder);
473     } else if (inst->multistream_decoder) {
474       opus_multistream_decoder_destroy(inst->multistream_decoder);
475     }
476     free(inst);
477     return 0;
478   } else {
479     return -1;
480   }
481 }
482 
WebRtcOpus_DecoderChannels(OpusDecInst * inst)483 size_t WebRtcOpus_DecoderChannels(OpusDecInst* inst) {
484   return inst->channels;
485 }
486 
WebRtcOpus_DecoderInit(OpusDecInst * inst)487 void WebRtcOpus_DecoderInit(OpusDecInst* inst) {
488   if (inst->decoder) {
489     opus_decoder_ctl(inst->decoder, OPUS_RESET_STATE);
490   } else {
491     opus_multistream_decoder_ctl(inst->multistream_decoder, OPUS_RESET_STATE);
492   }
493   inst->in_dtx_mode = 0;
494 }
495 
496 /* For decoder to determine if it is to output speech or comfort noise. */
DetermineAudioType(OpusDecInst * inst,size_t encoded_bytes)497 static int16_t DetermineAudioType(OpusDecInst* inst, size_t encoded_bytes) {
498   // Audio type becomes comfort noise if |encoded_byte| is 1 and keeps
499   // to be so if the following |encoded_byte| are 0 or 1.
500   if (encoded_bytes == 0 && inst->in_dtx_mode) {
501     return 2;  // Comfort noise.
502   } else if (encoded_bytes == 1 || encoded_bytes == 2) {
503     // TODO(henrik.lundin): There is a slight risk that a 2-byte payload is in
504     // fact a 1-byte TOC with a 1-byte payload. That will be erroneously
505     // interpreted as comfort noise output, but such a payload is probably
506     // faulty anyway.
507 
508     // TODO(webrtc:10218): This is wrong for multistream opus. Then are several
509     // single-stream packets glued together with some packet size bytes in
510     // between. See https://tools.ietf.org/html/rfc6716#appendix-B
511     inst->in_dtx_mode = 1;
512     return 2;  // Comfort noise.
513   } else {
514     inst->in_dtx_mode = 0;
515     return 0;  // Speech.
516   }
517 }
518 
519 /* |frame_size| is set to maximum Opus frame size in the normal case, and
520  * is set to the number of samples needed for PLC in case of losses.
521  * It is up to the caller to make sure the value is correct. */
DecodeNative(OpusDecInst * inst,const uint8_t * encoded,size_t encoded_bytes,int frame_size,int16_t * decoded,int16_t * audio_type,int decode_fec)522 static int DecodeNative(OpusDecInst* inst,
523                         const uint8_t* encoded,
524                         size_t encoded_bytes,
525                         int frame_size,
526                         int16_t* decoded,
527                         int16_t* audio_type,
528                         int decode_fec) {
529   int res = -1;
530   if (inst->decoder) {
531     res = opus_decode(
532         inst->decoder, encoded, static_cast<opus_int32>(encoded_bytes),
533         reinterpret_cast<opus_int16*>(decoded), frame_size, decode_fec);
534   } else {
535     res = opus_multistream_decode(inst->multistream_decoder, encoded,
536                                   static_cast<opus_int32>(encoded_bytes),
537                                   reinterpret_cast<opus_int16*>(decoded),
538                                   frame_size, decode_fec);
539   }
540 
541   if (res <= 0)
542     return -1;
543 
544   *audio_type = DetermineAudioType(inst, encoded_bytes);
545 
546   return res;
547 }
548 
DecodePlc(OpusDecInst * inst,int16_t * decoded)549 static int DecodePlc(OpusDecInst* inst, int16_t* decoded) {
550   int16_t audio_type = 0;
551   int decoded_samples;
552   int plc_samples =
553       FrameSizePerChannel(kWebRtcOpusPlcFrameSizeMs, inst->sample_rate_hz);
554 
555   if (inst->plc_use_prev_decoded_samples) {
556     /* The number of samples we ask for is |number_of_lost_frames| times
557      * |prev_decoded_samples_|. Limit the number of samples to maximum
558      * |MaxFrameSizePerChannel()|. */
559     plc_samples = inst->prev_decoded_samples;
560     const int max_samples_per_channel =
561         MaxFrameSizePerChannel(inst->sample_rate_hz);
562     plc_samples = plc_samples <= max_samples_per_channel
563                       ? plc_samples
564                       : max_samples_per_channel;
565   }
566   decoded_samples =
567       DecodeNative(inst, NULL, 0, plc_samples, decoded, &audio_type, 0);
568   if (decoded_samples < 0) {
569     return -1;
570   }
571 
572   return decoded_samples;
573 }
574 
WebRtcOpus_Decode(OpusDecInst * inst,const uint8_t * encoded,size_t encoded_bytes,int16_t * decoded,int16_t * audio_type)575 int WebRtcOpus_Decode(OpusDecInst* inst,
576                       const uint8_t* encoded,
577                       size_t encoded_bytes,
578                       int16_t* decoded,
579                       int16_t* audio_type) {
580   int decoded_samples;
581 
582   if (encoded_bytes == 0) {
583     *audio_type = DetermineAudioType(inst, encoded_bytes);
584     decoded_samples = DecodePlc(inst, decoded);
585   } else {
586     decoded_samples = DecodeNative(inst, encoded, encoded_bytes,
587                                    MaxFrameSizePerChannel(inst->sample_rate_hz),
588                                    decoded, audio_type, 0);
589   }
590   if (decoded_samples < 0) {
591     return -1;
592   }
593 
594   if (inst->plc_use_prev_decoded_samples) {
595     /* Update decoded sample memory, to be used by the PLC in case of losses. */
596     inst->prev_decoded_samples = decoded_samples;
597   }
598 
599   return decoded_samples;
600 }
601 
WebRtcOpus_DecodeFec(OpusDecInst * inst,const uint8_t * encoded,size_t encoded_bytes,int16_t * decoded,int16_t * audio_type)602 int WebRtcOpus_DecodeFec(OpusDecInst* inst,
603                          const uint8_t* encoded,
604                          size_t encoded_bytes,
605                          int16_t* decoded,
606                          int16_t* audio_type) {
607   int decoded_samples;
608   int fec_samples;
609 
610   if (WebRtcOpus_PacketHasFec(encoded, encoded_bytes) != 1) {
611     return 0;
612   }
613 
614   fec_samples =
615       opus_packet_get_samples_per_frame(encoded, inst->sample_rate_hz);
616 
617   decoded_samples = DecodeNative(inst, encoded, encoded_bytes, fec_samples,
618                                  decoded, audio_type, 1);
619   if (decoded_samples < 0) {
620     return -1;
621   }
622 
623   return decoded_samples;
624 }
625 
WebRtcOpus_DurationEst(OpusDecInst * inst,const uint8_t * payload,size_t payload_length_bytes)626 int WebRtcOpus_DurationEst(OpusDecInst* inst,
627                            const uint8_t* payload,
628                            size_t payload_length_bytes) {
629   if (payload_length_bytes == 0) {
630     // WebRtcOpus_Decode calls PLC when payload length is zero. So we return
631     // PLC duration correspondingly.
632     return WebRtcOpus_PlcDuration(inst);
633   }
634 
635   int frames, samples;
636   frames = opus_packet_get_nb_frames(
637       payload, static_cast<opus_int32>(payload_length_bytes));
638   if (frames < 0) {
639     /* Invalid payload data. */
640     return 0;
641   }
642   samples =
643       frames * opus_packet_get_samples_per_frame(payload, inst->sample_rate_hz);
644   if (samples > 120 * inst->sample_rate_hz / 1000) {
645     // More than 120 ms' worth of samples.
646     return 0;
647   }
648   return samples;
649 }
650 
WebRtcOpus_PlcDuration(OpusDecInst * inst)651 int WebRtcOpus_PlcDuration(OpusDecInst* inst) {
652   if (inst->plc_use_prev_decoded_samples) {
653     /* The number of samples we ask for is |number_of_lost_frames| times
654      * |prev_decoded_samples_|. Limit the number of samples to maximum
655      * |MaxFrameSizePerChannel()|. */
656     const int plc_samples = inst->prev_decoded_samples;
657     const int max_samples_per_channel =
658         MaxFrameSizePerChannel(inst->sample_rate_hz);
659     return plc_samples <= max_samples_per_channel ? plc_samples
660                                                   : max_samples_per_channel;
661   }
662   return FrameSizePerChannel(kWebRtcOpusPlcFrameSizeMs, inst->sample_rate_hz);
663 }
664 
WebRtcOpus_FecDurationEst(const uint8_t * payload,size_t payload_length_bytes,int sample_rate_hz)665 int WebRtcOpus_FecDurationEst(const uint8_t* payload,
666                               size_t payload_length_bytes,
667                               int sample_rate_hz) {
668   if (WebRtcOpus_PacketHasFec(payload, payload_length_bytes) != 1) {
669     return 0;
670   }
671   const int samples =
672       opus_packet_get_samples_per_frame(payload, sample_rate_hz);
673   const int samples_per_ms = sample_rate_hz / 1000;
674   if (samples < 10 * samples_per_ms || samples > 120 * samples_per_ms) {
675     /* Invalid payload duration. */
676     return 0;
677   }
678   return samples;
679 }
680 
WebRtcOpus_NumSilkFrames(const uint8_t * payload)681 int WebRtcOpus_NumSilkFrames(const uint8_t* payload) {
682   // For computing the payload length in ms, the sample rate is not important
683   // since it cancels out. We use 48 kHz, but any valid sample rate would work.
684   int payload_length_ms =
685       opus_packet_get_samples_per_frame(payload, 48000) / 48;
686   if (payload_length_ms < 10)
687     payload_length_ms = 10;
688 
689   int silk_frames;
690   switch (payload_length_ms) {
691     case 10:
692     case 20:
693       silk_frames = 1;
694       break;
695     case 40:
696       silk_frames = 2;
697       break;
698     case 60:
699       silk_frames = 3;
700       break;
701     default:
702       return 0;  // It is actually even an invalid packet.
703   }
704   return silk_frames;
705 }
706 
707 // This method is based on Definition of the Opus Audio Codec
708 // (https://tools.ietf.org/html/rfc6716). Basically, this method is based on
709 // parsing the LP layer of an Opus packet, particularly the LBRR flag.
WebRtcOpus_PacketHasFec(const uint8_t * payload,size_t payload_length_bytes)710 int WebRtcOpus_PacketHasFec(const uint8_t* payload,
711                             size_t payload_length_bytes) {
712   if (payload == NULL || payload_length_bytes == 0)
713     return 0;
714 
715   // In CELT_ONLY mode, packets should not have FEC.
716   if (payload[0] & 0x80)
717     return 0;
718 
719   int silk_frames = WebRtcOpus_NumSilkFrames(payload);
720   if (silk_frames == 0)
721     return 0;  // Not valid.
722 
723   const int channels = opus_packet_get_nb_channels(payload);
724   RTC_DCHECK(channels == 1 || channels == 2);
725 
726   // Max number of frames in an Opus packet is 48.
727   opus_int16 frame_sizes[48];
728   const unsigned char* frame_data[48];
729 
730   // Parse packet to get the frames. But we only care about the first frame,
731   // since we can only decode the FEC from the first one.
732   if (opus_packet_parse(payload, static_cast<opus_int32>(payload_length_bytes),
733                         NULL, frame_data, frame_sizes, NULL) < 0) {
734     return 0;
735   }
736 
737   if (frame_sizes[0] < 1) {
738     return 0;
739   }
740 
741   // A frame starts with the LP layer. The LP layer begins with two to eight
742   // header bits.These consist of one VAD bit per SILK frame (up to 3),
743   // followed by a single flag indicating the presence of LBRR frames.
744   // For a stereo packet, these first flags correspond to the mid channel, and
745   // a second set of flags is included for the side channel. Because these are
746   // the first symbols decoded by the range coder and because they are coded
747   // as binary values with uniform probability, they can be extracted directly
748   // from the most significant bits of the first byte of compressed data.
749   for (int n = 0; n < channels; n++) {
750     // The LBRR bit for channel 1 is on the (|silk_frames| + 1)-th bit, and
751     // that of channel 2 is on the |(|silk_frames| + 1) * 2 + 1|-th bit.
752     if (frame_data[0][0] & (0x80 >> ((n + 1) * (silk_frames + 1) - 1)))
753       return 1;
754   }
755 
756   return 0;
757 }
758 
WebRtcOpus_PacketHasVoiceActivity(const uint8_t * payload,size_t payload_length_bytes)759 int WebRtcOpus_PacketHasVoiceActivity(const uint8_t* payload,
760                                       size_t payload_length_bytes) {
761   if (payload == NULL || payload_length_bytes == 0)
762     return 0;
763 
764   // In CELT_ONLY mode we can not determine whether there is VAD.
765   if (payload[0] & 0x80)
766     return -1;
767 
768   int silk_frames = WebRtcOpus_NumSilkFrames(payload);
769   if (silk_frames == 0)
770     return 0;
771 
772   const int channels = opus_packet_get_nb_channels(payload);
773   RTC_DCHECK(channels == 1 || channels == 2);
774 
775   // Max number of frames in an Opus packet is 48.
776   opus_int16 frame_sizes[48];
777   const unsigned char* frame_data[48];
778 
779   // Parse packet to get the frames.
780   int frames =
781       opus_packet_parse(payload, static_cast<opus_int32>(payload_length_bytes),
782                         NULL, frame_data, frame_sizes, NULL);
783   if (frames < 0)
784     return -1;
785 
786   // Iterate over all Opus frames which may contain multiple SILK frames.
787   for (int frame = 0; frame < frames; frame++) {
788     if (frame_sizes[frame] < 1) {
789       continue;
790     }
791     if (frame_data[frame][0] >> (8 - silk_frames))
792       return 1;
793     if (channels == 2 &&
794         (frame_data[frame][0] << (silk_frames + 1)) >> (8 - silk_frames))
795       return 1;
796   }
797 
798   return 0;
799 }
800