[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