mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
opusdec: do not fail when LBRR frames are present
Decode and discard them. Fixes ticket 4641.
This commit is contained in:
parent
3bf5cc9c58
commit
33b4b788aa
@ -506,7 +506,8 @@ static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
|
||||
#define LTP_ORDER 5
|
||||
|
||||
static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
|
||||
int frame_num, int channel, int coded_channels, int active, int active1)
|
||||
int frame_num, int channel, int coded_channels,
|
||||
int active, int active1, int redundant)
|
||||
{
|
||||
/* per frame */
|
||||
int voiced; // combines with active to indicate inactive, active, or active+voiced
|
||||
@ -665,8 +666,9 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
|
||||
silk_decode_excitation(s, rc, residual + SILK_MAX_LAG, qoffset_high,
|
||||
active, voiced);
|
||||
|
||||
/* skip synthesising the side channel if we want mono-only */
|
||||
if (s->output_channels == channel)
|
||||
/* skip synthesising the output if we do not need it */
|
||||
// TODO: implement error recovery
|
||||
if (s->output_channels == channel || redundant)
|
||||
return;
|
||||
|
||||
/* generate the output signal */
|
||||
@ -814,15 +816,27 @@ int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
|
||||
active[i][j] = ff_opus_rc_dec_log(rc, 1);
|
||||
|
||||
redundancy[i] = ff_opus_rc_dec_log(rc, 1);
|
||||
if (redundancy[i]) {
|
||||
avpriv_report_missing_feature(s->avctx, "LBRR frames");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
|
||||
/* read the per-frame LBRR flags */
|
||||
for (i = 0; i < coded_channels; i++)
|
||||
if (redundancy[i] && duration_ms > 20) {
|
||||
redundancy[i] = ff_opus_rc_dec_cdf(rc, duration_ms == 40 ?
|
||||
ff_silk_model_lbrr_flags_40 : ff_silk_model_lbrr_flags_60);
|
||||
}
|
||||
|
||||
/* decode the LBRR frames */
|
||||
for (i = 0; i < nb_frames; i++) {
|
||||
for (j = 0; j < coded_channels; j++)
|
||||
if (redundancy[j] & (1 << i)) {
|
||||
int active1 = (j == 0 && !(redundancy[1] & (1 << i))) ? 0 : 1;
|
||||
silk_decode_frame(s, rc, i, j, coded_channels, 1, active1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nb_frames; i++) {
|
||||
for (j = 0; j < coded_channels && !s->midonly; j++)
|
||||
silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active[1][i]);
|
||||
silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active[1][i], 0);
|
||||
|
||||
/* reset the side channel if it is not coded */
|
||||
if (s->midonly && s->frame[1].coded)
|
||||
|
@ -26,6 +26,9 @@ const uint8_t ff_opus_default_coupled_streams[] = { 0, 1, 1, 2, 2, 2, 2, 3 };
|
||||
|
||||
const uint8_t ff_celt_band_end[] = { 13, 17, 17, 19, 21 };
|
||||
|
||||
const uint16_t ff_silk_model_lbrr_flags_40[] = { 256, 0, 53, 106, 256 };
|
||||
const uint16_t ff_silk_model_lbrr_flags_60[] = { 256, 0, 41, 61, 90, 131, 146, 174, 256 };
|
||||
|
||||
const uint16_t ff_silk_model_stereo_s1[] = {
|
||||
256, 7, 9, 10, 11, 12, 22, 46, 54, 55, 56, 59, 82, 174, 197, 200,
|
||||
201, 202, 210, 234, 244, 245, 246, 247, 249, 256
|
||||
|
@ -31,6 +31,9 @@ extern const uint8_t ff_celt_band_end[];
|
||||
|
||||
extern const uint8_t ff_opus_default_coupled_streams[];
|
||||
|
||||
extern const uint16_t ff_silk_model_lbrr_flags_40[];
|
||||
extern const uint16_t ff_silk_model_lbrr_flags_60[];
|
||||
|
||||
extern const uint16_t ff_silk_model_stereo_s1[];
|
||||
extern const uint16_t ff_silk_model_stereo_s2[];
|
||||
extern const uint16_t ff_silk_model_stereo_s3[];
|
||||
|
Loading…
Reference in New Issue
Block a user