From 6ac34eed54f8e0298acb16636d0104c297e3d09f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 20:16:45 -0400 Subject: [PATCH] g726: use bits_per_coded_sample instead of bitrate to determine mode This requires some workarounds in the WAV muxer and demuxer. We need to write the correct bits_per_coded_sample and block_align in the muxer. In the demuxer, we cannot rely on the bits_per_coded_sample value, so we use the bit rate and sample rate to determine the value. This avoids having the decoder rely on AVCodecContext.bit_rate, which is not required to be set by the user for decoding according to our API. --- libavcodec/g726.c | 40 +++++++++++++++++++--------------------- libavformat/riff.c | 17 ++++++++++------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/libavcodec/g726.c b/libavcodec/g726.c index b150f587f7..339281110c 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -301,29 +301,29 @@ static int16_t g726_encode(G726Context* c, int16_t sig) static av_cold int g726_encode_init(AVCodecContext *avctx) { G726Context* c = avctx->priv_data; - unsigned int index; if (avctx->sample_rate <= 0) { av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n"); return -1; } - index = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2; - - if (avctx->bit_rate % avctx->sample_rate) { - av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n"); - return -1; - } if(avctx->channels != 1){ av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); return -1; } - if(index>3){ - av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2); - return -1; + + if (avctx->bit_rate % avctx->sample_rate) { + av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n"); + return AVERROR(EINVAL); } - g726_reset(c, index); - c->code_size = index+2; + c->code_size = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate; + if (c->code_size < 2 || c->code_size > 5) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size); + return AVERROR(EINVAL); + } + avctx->bits_per_coded_sample = c->code_size; + + g726_reset(c, c->code_size - 2); avctx->coded_frame = avcodec_alloc_frame(); if (!avctx->coded_frame) @@ -332,7 +332,7 @@ static av_cold int g726_encode_init(AVCodecContext *avctx) /* select a frame size that will end on a byte boundary and have a size of approximately 1024 bytes */ - avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[index]; + avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[c->code_size - 2]; return 0; } @@ -365,25 +365,23 @@ static int g726_encode_frame(AVCodecContext *avctx, static av_cold int g726_decode_init(AVCodecContext *avctx) { G726Context* c = avctx->priv_data; - unsigned int index; if (avctx->sample_rate <= 0) { av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n"); return -1; } - index = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2; - if(avctx->channels != 1){ av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); return -1; } - if(index>3){ - av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2); - return -1; + + c->code_size = avctx->bits_per_coded_sample; + if (c->code_size < 2 || c->code_size > 5) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size); + return AVERROR(EINVAL); } - g726_reset(c, index); - c->code_size = index+2; + g726_reset(c, c->code_size - 2); avctx->sample_fmt = AV_SAMPLE_FMT_S16; diff --git a/libavformat/riff.c b/libavformat/riff.c index 0f4c079b35..8eed7ce28e 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -385,11 +385,13 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc) avio_wl32(pb, enc->sample_rate); if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) { bps = 0; - } else if (enc->codec_id == CODEC_ID_ADPCM_G726) { - bps = 4; } else { - if (!(bps = av_get_bits_per_sample(enc->codec_id))) - bps = 16; // default to 16 + if (!(bps = av_get_bits_per_sample(enc->codec_id))) { + if (enc->bits_per_coded_sample) + bps = enc->bits_per_coded_sample; + else + bps = 16; // default to 16 + } } if(bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample){ av_log(enc, AV_LOG_WARNING, "requested bits_per_coded_sample (%d) and actually stored (%d) differ\n", enc->bits_per_coded_sample, bps); @@ -400,12 +402,10 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc) //blkalign = 144 * enc->bit_rate/enc->sample_rate; } else if (enc->codec_id == CODEC_ID_AC3) { blkalign = 3840; //maximum bytes per frame - } else if (enc->codec_id == CODEC_ID_ADPCM_G726) { // - blkalign = 1; } else if (enc->block_align != 0) { /* specified by the codec */ blkalign = enc->block_align; } else - blkalign = enc->channels*bps >> 3; + blkalign = bps * enc->channels / av_gcd(8, bps); if (enc->codec_id == CODEC_ID_PCM_U8 || enc->codec_id == CODEC_ID_PCM_S24LE || enc->codec_id == CODEC_ID_PCM_S32LE || @@ -545,6 +545,9 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) codec->channels = 0; codec->sample_rate = 0; } + /* override bits_per_coded_sample for G.726 */ + if (codec->codec_id == CODEC_ID_ADPCM_G726) + codec->bits_per_coded_sample = codec->bit_rate / codec->sample_rate; return 0; }