X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Famrwbdec.c;h=a6c1d894d75cb780b5b04ea88a8d3a46d05a9990;hb=a247ac640df3da573cd661065bf53f37863e2b46;hp=47fe7eb55e1882e1f381caf007dd80de69fc8fd7;hpb=b8eb0827f053230dd919bc73e25381b47b4fe1a7;p=ffmpeg diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 47fe7eb55e1..a6c1d894d75 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -1119,12 +1119,23 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, buf_out = (float *)frame->data[0]; header_size = decode_mime_header(ctx, buf); + expected_fr_size = ((cf_sizes_wb[ctx->fr_cur_mode] + 7) >> 3) + 1; + + if (!ctx->fr_quality) + av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n"); + + if (ctx->fr_cur_mode == NO_DATA || !ctx->fr_quality) { + /* The specification suggests a "random signal" and + "a muting technique" to "gradually decrease the output level". */ + av_samples_set_silence(&frame->data[0], 0, frame->nb_samples, 1, AV_SAMPLE_FMT_FLT); + *got_frame_ptr = 1; + return expected_fr_size; + } if (ctx->fr_cur_mode > MODE_SID) { av_log(avctx, AV_LOG_ERROR, "Invalid mode %d\n", ctx->fr_cur_mode); return AVERROR_INVALIDDATA; } - expected_fr_size = ((cf_sizes_wb[ctx->fr_cur_mode] + 7) >> 3) + 1; if (buf_size < expected_fr_size) { av_log(avctx, AV_LOG_ERROR, @@ -1133,9 +1144,6 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (!ctx->fr_quality || ctx->fr_cur_mode > MODE_SID) - av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n"); - if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */ avpriv_request_sample(avctx, "SID mode"); return AVERROR_PATCHWELCOME; @@ -1267,7 +1275,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, return expected_fr_size; } -AVCodec ff_amrwb_decoder = { +const AVCodec ff_amrwb_decoder = { .name = "amrwb", .long_name = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"), .type = AVMEDIA_TYPE_AUDIO, @@ -1275,7 +1283,7 @@ AVCodec ff_amrwb_decoder = { .priv_data_size = sizeof(AMRWBContext), .init = amrwb_decode_init, .decode = amrwb_decode_frame, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE }, };