[FFmpeg-devel] [RFC]Support G.726 in Sun AU
Carl Eugen Hoyos
cehoyos at ag.or.at
Sat Nov 24 21:18:12 CET 2012
On Saturday 24 November 2012 04:46:12 pm Paul B Mahol wrote:
> LOL, but i was referring to using bits_per_coded sample to not need to
> use private_data.
Yes, definitely;-)
Piotr found another completely broken sample, patch updated.
Carl Eugen
-------------- next part --------------
diff --git a/libavformat/au.c b/libavformat/au.c
index d4d4ff3..b54b37b 100644
--- a/libavformat/au.c
+++ b/libavformat/au.c
@@ -47,8 +47,12 @@ static const AVCodecTag codec_au_tags[] = {
{ AV_CODEC_ID_PCM_S32BE, 5 },
{ AV_CODEC_ID_PCM_F32BE, 6 },
{ AV_CODEC_ID_PCM_F64BE, 7 },
+ { AV_CODEC_ID_ADPCM_G726, 23 },
{ AV_CODEC_ID_ADPCM_G722, 24 },
+ { AV_CODEC_ID_ADPCM_G726, 25 },
+ { AV_CODEC_ID_ADPCM_G726, 26 },
{ AV_CODEC_ID_PCM_ALAW, 27 },
+ { AV_CODEC_ID_ADPCM_G726, MKBETAG('7','2','6','2') },
{ AV_CODEC_ID_NONE, 0 },
};
@@ -58,6 +62,15 @@ static int put_au_header(AVIOContext *pb, AVCodecContext *enc)
{
if(!enc->codec_tag)
return -1;
+ if (enc->codec_id == AV_CODEC_ID_ADPCM_G726) {
+ if (enc->bits_per_coded_sample < 3 || enc->bits_per_coded_sample > 5) {
+ av_log(pb, AV_LOG_ERROR,
+ "bits_per_coded_sample '%d' not supported for G.726 in Sun AU\n",
+ enc->bits_per_coded_sample);
+ return AVERROR_INVALIDDATA;
+ }
+ enc->codec_tag = (uint8_t []){23, 26, 0, 25}[enc->bits_per_coded_sample & 3];
+ }
ffio_wfourcc(pb, ".snd"); /* magic number */
avio_wb32(pb, AU_HEADER_SIZE); /* header size */
avio_wb32(pb, AU_UNKNOWN_SIZE); /* data size */
@@ -149,7 +162,13 @@ static int au_read_header(AVFormatContext *s)
codec = ff_codec_get_id(codec_au_tags, id);
- if (!(bps = av_get_bits_per_sample(codec))) {
+ if (codec == AV_CODEC_ID_ADPCM_G726) {
+ if (id == MKBETAG('7','2','6','2')) {
+ bps = 2;
+ } else {
+ bps = (uint8_t []){4, 0, 3, 5}[id - 23];
+ }
+ } else if (!(bps = av_get_bits_per_sample(codec))) {
av_log_ask_for_sample(s, "could not determine bits per sample\n");
return AVERROR_INVALIDDATA;
}
@@ -173,6 +192,8 @@ static int au_read_header(AVFormatContext *s)
st->codec->codec_id = codec;
st->codec->channels = channels;
st->codec->sample_rate = rate;
+ st->codec->bits_per_coded_sample = bps;
+ st->codec->bit_rate = channels * rate * bps;
if (data_size != AU_UNKNOWN_SIZE)
st->duration = (((int64_t)data_size)<<3) / (st->codec->channels * (int64_t)bps);
avpriv_set_pts_info(st, 64, 1, rate);
@@ -185,7 +206,7 @@ static int au_read_packet(AVFormatContext *s,
AVPacket *pkt)
{
int ret;
- int bpcs = av_get_bits_per_sample(s->streams[0]->codec->codec_id);
+ int bpcs = s->streams[0]->codec->bits_per_coded_sample;
if (!bpcs)
return AVERROR(EINVAL);
More information about the ffmpeg-devel
mailing list