[FFmpeg-devel] [PATCH] Flush last frame in WMA lossless decoder

Jakub Stachowski qbast at go2.pl
Sun Apr 29 22:43:47 CEST 2012


Hello

Here is cleaned up version of my patches to flush last frames and skip 
right number of samples in WMA lossless decoder. This causes ffmpeg to 
output the same number of samples as wmal2pcm.exe which I use as reference.
-------------- next part --------------
From cfa3e9b07c2ac5b0509966ac0b109f1df71b6ef0 Mon Sep 17 00:00:00 2001
From: Jakub Stachowski <qbast at go2.pl>
Date: Sun, 29 Apr 2012 22:11:08 +0200
Subject: [PATCH 1/2] Flush remaining frames from last packets

---
 libavcodec/wmalosslessdec.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index de5dca3..c1e5480 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -1173,7 +1173,10 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr,
 
     s->frame.nb_samples = 0;
 
-    if (s->packet_done || s->packet_loss) {
+    if ( !buf && s->num_saved_bits > get_bits_count(&s->gb)) {
+        s->packet_done = 0;
+        if (!decode_frame(s)) s->num_saved_bits = 0;
+    } else if (s->packet_done || s->packet_loss) {
         s->packet_done = 0;
 
         /* sanity check for the buffer length */
-- 
1.7.7
-------------- next part --------------
From 29701dfd9101726fe2acf8e077fa32776ae71a3d Mon Sep 17 00:00:00 2001
From: Jakub Stachowski <qbast at go2.pl>
Date: Sun, 29 Apr 2012 22:24:13 +0200
Subject: [PATCH 2/2] Skip last samples in frame if needed

---
 libavcodec/wmalosslessdec.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index c1e5480..b77d576 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -977,8 +977,16 @@ static int decode_subframe(WmallDecodeCtx *s)
 
     /* Write to proper output buffer depending on bit-depth */
     for (i = 0; i < s->channels_for_cur_subframe; i++) {
+        int already_written;
         int c = s->channel_indexes_for_cur_subframe[i];
-        int subframe_len = s->channel[c].subframe_len[s->channel[c].cur_subframe];
+        
+        if (s->bits_per_sample == 16) 
+            already_written = (s->samples_16[c] - ((int16_t *)s->frame.data[0] + c)) / s->num_channels;
+        else
+            already_written = (s->samples_32[c] - ((int32_t *)s->frame.data[0] + c)) / s->num_channels;
+
+        int subframe_len = FFMIN(s->frame.nb_samples - already_written, s->channel[c].subframe_len[s->channel[c].cur_subframe]);
+
 
         for (j = 0; j < subframe_len; j++) {
             if (s->bits_per_sample == 16) {
@@ -1056,6 +1064,11 @@ static int decode_frame(WmallDecodeCtx *s)
         if (get_bits1(gb)) {
             skip = get_bits(gb, av_log2(s->samples_per_frame * 2));
             av_dlog(s->avctx, "end skip: %i\n", skip);
+            s->frame.nb_samples -= skip;
+            if (s->frame.nb_samples<0) {
+                av_log(s->avctx, AV_LOG_ERROR,"negative number of samples\n");
+                return AVERROR_INVALIDDATA;
+           }
         }
 
     }
-- 
1.7.7


More information about the ffmpeg-devel mailing list