ac3dec: allow selecting float output at runtime.
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>
Mon, 25 Apr 2011 09:59:28 +0000 (11:59 +0200)
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>
Mon, 25 Apr 2011 14:51:27 +0000 (16:51 +0200)
libavcodec/ac3dec.c
libavcodec/avcodec.h
libavcodec/options.c

index b2e4f81..431f67d 100644 (file)
@@ -185,14 +185,6 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
     ff_fmt_convert_init(&s->fmt_conv, avctx);
     av_lfg_init(&s->dith_state, 0);
 
-    /* ffdshow custom code */
-#if CONFIG_AUDIO_FLOAT
-    s->mul_bias = 1.0f;
-#else
-    /* set scale value for float to int16 conversion */
-    s->mul_bias = 32767.0f;
-#endif
-
     /* allow downmixing to stereo or mono */
     if (avctx->channels > 0 && avctx->request_channels > 0 &&
             avctx->request_channels < avctx->channels &&
@@ -201,12 +193,14 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
     }
     s->downmixed = 1;
 
-    /* ffdshow custom code */
-#if CONFIG_AUDIO_FLOAT
-    avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
-#else
-    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-#endif
+    if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
+        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+        s->mul_bias = 1.0f;
+    } else {
+        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+        /* set scale value for float to int16 conversion */
+        s->mul_bias = 32767.0f;
+    }
     return 0;
 }
 
@@ -1301,12 +1295,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     AC3DecodeContext *s = avctx->priv_data;
-    /* ffdshow custom code */
-#if CONFIG_AUDIO_FLOAT
-    float *out_samples = (float *)data;
-#else
+    float *out_samples_flt = (float *)data;
     int16_t *out_samples = (int16_t *)data;
-#endif
     int blk, ch, err;
     const uint8_t *channel_map;
     const float *output[AC3_MAX_CHANNELS];
@@ -1412,15 +1402,16 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
             av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");
             err = 1;
         }
-        /* ffdshow custom code */
-#if CONFIG_AUDIO_FLOAT
-        float_interleave_noscale(out_samples, output, 256, s->out_channels);
-#else
-        s->fmt_conv.float_to_int16_interleave(out_samples, output, 256, s->out_channels);
-#endif
-        out_samples += 256 * s->out_channels;
+        if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
+            float_interleave_noscale(out_samples_flt, output, 256, s->out_channels);
+            out_samples_flt += 256 * s->out_channels;
+        } else {
+            s->fmt_conv.float_to_int16_interleave(out_samples, output, 256, s->out_channels);
+            out_samples += 256 * s->out_channels;
+        }
     }
-    *data_size = s->num_blocks * 256 * avctx->channels * sizeof (out_samples[0]); /* ffdshow custom code */
+    *data_size = s->num_blocks * 256 * avctx->channels;
+    *data_size *= avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? sizeof(*out_samples_flt) : sizeof(*out_samples);
     return FFMIN(buf_size, s->frame_size);
 }
 
index 10866a1..58a38fa 100644 (file)
@@ -2877,6 +2877,14 @@ typedef struct AVCodecContext {
     int64_t pts_correction_last_pts;       /// PTS of the last frame
     int64_t pts_correction_last_dts;       /// DTS of the last frame
 
+    /**
+     * desired sample format
+     * - encoding: Not used.
+     * - decoding: Set by user.
+     * Decoder will decode to this format if it can.
+     */
+    enum AVSampleFormat request_sample_fmt;
+
 } AVCodecContext;
 
 /**
index 2c39551..ebe228e 100644 (file)
@@ -447,6 +447,7 @@ static const AVOption options[]={
 {"em", "Emergency",          0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_EMERGENCY,         INT_MIN, INT_MAX, A|E, "audio_service_type"},
 {"vo", "Voice Over",         0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_VOICE_OVER,        INT_MIN, INT_MAX, A|E, "audio_service_type"},
 {"ka", "Karaoke",            0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_KARAOKE,           INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), FF_OPT_TYPE_INT, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D},
 {NULL},
 };