[FFmpeg-devel] [PATCH] DCA floating point output

FB2000 flybird2k
Mon Apr 26 00:51:05 CEST 2010


I understand a patch like this one had been discussed at January 2008 but it used a compiling switch 

#define CONFIG_AUDIO_NONSHORT 1

which by itself might bring some confusion. 

Since DCA source PCM resolution is either 16, 20 or 24 bits, and the DCA decoder uses float internally, it's clear that float is a much better output format than currently used int16_t. My point is that we should change to float directly without using any switch. By changing 

avctx->sample_fmt = SAMPLE_FMT_S16;

to

avctx->sample_fmt = SAMPLE_FMT_FLT;

at dca_decode_init(), callers like ffmpeg or ffplay understand the output format correctly thus nothing need to be modified out of dca.c.

I've also removed codes related to float_to_int16_interleave since it's no longer needed for the output.

I hope this patch could find its way into libavcodec, so that we could finally get a better quality DCA decoder. 

Best regards,

FB2000


Index: libavcodec/dca.c
===================================================================
--- libavcodec/dca.c	(revision 22960)
+++ libavcodec/dca.c	(working copy)
@@ -1203,8 +1203,8 @@
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
 
-    int i;
-    int16_t *samples = data;
+    int i, j, k;
+    float *samples = data;
     DCAContext *s = avctx->priv_data;
     int channels;
 
@@ -1259,13 +1259,16 @@
     if (!avctx->channels)
         avctx->channels = channels;
 
-    if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels)
+    if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(float) * 
+ channels)
         return -1;
-    *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels;
+    *data_size = 256 / 8 * s->sample_blocks * sizeof(float) * channels;
     for (i = 0; i < (s->sample_blocks / 8); i++) {
         dca_decode_block(s);
-        s->dsp.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels);
-        samples += 256 * channels;
+        for (j = 0; j < 256; j++) {
+            for (k = 0; k < channels; k++)
+                samples[k] = s->samples[j + k * 256] / 32768.0f;
+            samples += channels;
+        }
     }
 
     return buf_size;
@@ -1294,20 +1297,15 @@
 
     for(i = 0; i < 6; i++)
         s->samples_chanptr[i] = s->samples + i * 256;
-    avctx->sample_fmt = SAMPLE_FMT_S16;
+    avctx->sample_fmt = SAMPLE_FMT_FLT;
 
-    if(s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) {
-        s->add_bias = 385.0f;
-        s->scale_bias = 1.0 / 32768.0;
-    } else {
-        s->add_bias = 0.0f;
-        s->scale_bias = 1.0;
+    s->add_bias = 0.0f;
+    s->scale_bias = 1.0;
 
-        /* allow downmixing to stereo */
-        if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
-                avctx->request_channels == 2) {
+    /* allow downmixing to stereo */
+    if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
+        avctx->request_channels == 2) {
             avctx->channels = avctx->request_channels;
-        }
     }






More information about the ffmpeg-devel mailing list