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.
This commit is contained in:
parent
d405237bae
commit
6ac34eed54
@ -301,29 +301,29 @@ static int16_t g726_encode(G726Context* c, int16_t sig)
|
|||||||
static av_cold int g726_encode_init(AVCodecContext *avctx)
|
static av_cold int g726_encode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
G726Context* c = avctx->priv_data;
|
G726Context* c = avctx->priv_data;
|
||||||
unsigned int index;
|
|
||||||
|
|
||||||
if (avctx->sample_rate <= 0) {
|
if (avctx->sample_rate <= 0) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n");
|
av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n");
|
||||||
return -1;
|
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){
|
if(avctx->channels != 1){
|
||||||
av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
|
av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(index>3){
|
|
||||||
av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2);
|
if (avctx->bit_rate % avctx->sample_rate) {
|
||||||
return -1;
|
av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
g726_reset(c, index);
|
c->code_size = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate;
|
||||||
c->code_size = index+2;
|
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();
|
avctx->coded_frame = avcodec_alloc_frame();
|
||||||
if (!avctx->coded_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
|
/* select a frame size that will end on a byte boundary and have a size of
|
||||||
approximately 1024 bytes */
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -365,25 +365,23 @@ static int g726_encode_frame(AVCodecContext *avctx,
|
|||||||
static av_cold int g726_decode_init(AVCodecContext *avctx)
|
static av_cold int g726_decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
G726Context* c = avctx->priv_data;
|
G726Context* c = avctx->priv_data;
|
||||||
unsigned int index;
|
|
||||||
|
|
||||||
if (avctx->sample_rate <= 0) {
|
if (avctx->sample_rate <= 0) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n");
|
av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2;
|
|
||||||
|
|
||||||
if(avctx->channels != 1){
|
if(avctx->channels != 1){
|
||||||
av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
|
av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(index>3){
|
|
||||||
av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2);
|
c->code_size = avctx->bits_per_coded_sample;
|
||||||
return -1;
|
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);
|
g726_reset(c, c->code_size - 2);
|
||||||
c->code_size = index+2;
|
|
||||||
|
|
||||||
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
|
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||||
|
|
||||||
|
@ -385,11 +385,13 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
|
|||||||
avio_wl32(pb, enc->sample_rate);
|
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) {
|
if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) {
|
||||||
bps = 0;
|
bps = 0;
|
||||||
} else if (enc->codec_id == CODEC_ID_ADPCM_G726) {
|
|
||||||
bps = 4;
|
|
||||||
} else {
|
} else {
|
||||||
if (!(bps = av_get_bits_per_sample(enc->codec_id)))
|
if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
|
||||||
bps = 16; // default to 16
|
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){
|
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);
|
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;
|
//blkalign = 144 * enc->bit_rate/enc->sample_rate;
|
||||||
} else if (enc->codec_id == CODEC_ID_AC3) {
|
} else if (enc->codec_id == CODEC_ID_AC3) {
|
||||||
blkalign = 3840; //maximum bytes per frame
|
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 */
|
} else if (enc->block_align != 0) { /* specified by the codec */
|
||||||
blkalign = enc->block_align;
|
blkalign = enc->block_align;
|
||||||
} else
|
} else
|
||||||
blkalign = enc->channels*bps >> 3;
|
blkalign = bps * enc->channels / av_gcd(8, bps);
|
||||||
if (enc->codec_id == CODEC_ID_PCM_U8 ||
|
if (enc->codec_id == CODEC_ID_PCM_U8 ||
|
||||||
enc->codec_id == CODEC_ID_PCM_S24LE ||
|
enc->codec_id == CODEC_ID_PCM_S24LE ||
|
||||||
enc->codec_id == CODEC_ID_PCM_S32LE ||
|
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->channels = 0;
|
||||||
codec->sample_rate = 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user