[FFmpeg-cvslog] Fix audio output

Mashiat Sarker Shakkhar git at videolan.org
Tue Jan 3 23:53:10 CET 2012


ffmpeg | branch: master | Mashiat Sarker Shakkhar <shahriman_ams at yahoo.com> | Tue Jan  3 01:49:00 2012 +0600| [2083a10abff252efc5a54c778e985516d520587a] | committer: Mashiat Sarker Shakkhar

Fix audio output

Up until now, the decoder didn't output anything
in the data buffer. This fixes all the issues
related to sample format, removes leftover code
and actually outputs some audio to data buffer.

With this, the only sample we have can be played.
Seeking is still broken though.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2083a10abff252efc5a54c778e985516d520587a
---

 libavcodec/wmalosslessdec.c |   50 ++++++++++++++++++++++++++++++++++--------
 1 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index adf9ae9..c623f4e 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -200,8 +200,10 @@ typedef struct WmallDecodeCtx {
     uint32_t         frame_num;                     ///< current frame number (not used for decoding)
     GetBitContext    gb;                            ///< bitstream reader context
     int              buf_bit_size;                  ///< buffer size in bits
-    float*           samples;                       ///< current samplebuffer pointer
-    float*           samples_end;                   ///< maximum samplebuffer pointer
+    int16_t*         samples_16;                    ///< current samplebuffer pointer (16-bit)
+    int16_t*         samples_16_end;                ///< maximum samplebuffer pointer
+    int16_t*         samples_32;                    ///< current samplebuffer pointer (24-bit)
+    int16_t*         samples_32_end;                ///< maximum samplebuffer pointer
     uint8_t          drc_gain;                      ///< gain for the DRC tool
     int8_t           skip_frame;                    ///< skip output step
     int8_t           parsed_all_subframes;          ///< all subframes decoded?
@@ -357,12 +359,19 @@ static av_cold int decode_init(AVCodecContext *avctx)
     dsputil_init(&s->dsp, avctx);
     init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
 
-    avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
-
     if (avctx->extradata_size >= 18) {
         s->decode_flags    = AV_RL16(edata_ptr+14);
         channel_mask       = AV_RL32(edata_ptr+2);
         s->bits_per_sample = AV_RL16(edata_ptr);
+        if (s->bits_per_sample == 16)
+            avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+        else if (s->bits_per_sample == 24)
+            avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+        else {
+            av_log(avctx, AV_LOG_ERROR, "Unknown bit-depth: %d\n",
+                   s->bits_per_sample);
+            return AVERROR_INVALIDDATA;
+        }
         /** dump the extradata */
         for (i = 0; i < avctx->extradata_size; i++)
             dprintf(avctx, "[%x] ", avctx->extradata[i]);
@@ -1198,6 +1207,15 @@ static int decode_subframe(WmallDecodeCtx *s)
             for (j = 0; j < subframe_len; j++)
                 s->channel_residues[i][j] *= s->quant_stepsize;
 
+    // Write to proper output buffer depending on bit-depth
+    for (i = 0; i < subframe_len; i++)
+        for (j = 0; j < s->num_channels; j++) {
+            if (s->bits_per_sample == 16)
+                *s->samples_16++ = (int16_t) s->channel_residues[j][i];
+            else
+                *s->samples_32++ = s->channel_residues[j][i];
+        }
+
     /** handled one subframe */
 
     for (i = 0; i < s->channels_for_cur_subframe; i++) {
@@ -1224,9 +1242,14 @@ static int decode_frame(WmallDecodeCtx *s)
     int more_frames = 0;
     int len = 0;
     int i;
+    int buffer_len;
 
     /** check for potential output buffer overflow */
-    if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) {
+    if (s->bits_per_sample == 16)
+        buffer_len = s->samples_16_end - s->samples_16;
+    else
+        buffer_len = s->samples_32_end - s->samples_32;
+    if (s->num_channels * s->samples_per_frame > buffer_len) {
         /** return an error if no frame could be decoded at all */
         av_log(s->avctx, AV_LOG_ERROR,
                "not enough space for the output samples\n");
@@ -1288,8 +1311,7 @@ static int decode_frame(WmallDecodeCtx *s)
 
     if (s->skip_frame) {
         s->skip_frame = 0;
-    } else
-        s->samples += s->num_channels * s->samples_per_frame;
+    }
 
     if (s->len_prefix) {
         if (len != (get_bits_count(gb) - s->frame_offset) + 2) {
@@ -1398,8 +1420,13 @@ static int decode_packet(AVCodecContext *avctx,
     int num_bits_prev_frame;
     int packet_sequence_number;
 
-    s->samples       = data;
-    s->samples_end   = (float*)((int8_t*)data + *data_size);
+    if (s->bits_per_sample == 16) {
+        s->samples_16     = (int16_t *) data;
+        s->samples_16_end = (int16_t *) ((int8_t*)data + *data_size);
+    } else {
+        s->samples_32     = (int *) data;
+        s->samples_32_end = (int *) ((int8_t*)data + *data_size);;
+    }
     *data_size = 0;
 
     if (s->packet_done || s->packet_loss) {
@@ -1492,7 +1519,10 @@ static int decode_packet(AVCodecContext *avctx,
         save_bits(s, gb, remaining_bits(s, gb), 0);
     }
 
-    *data_size = 0; // (int8_t *)s->samples - (int8_t *)data;
+    if (s->bits_per_sample == 16)
+        *data_size = (int8_t *)s->samples_16 - (int8_t *)data;
+    else
+        *data_size = (int8_t *)s->samples_32 - (int8_t *)data;
     s->packet_offset = get_bits_count(gb) & 7;
 
     return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3;



More information about the ffmpeg-cvslog mailing list