[FFmpeg-cvslog] avcodec/dca: simplify 'residual ok' flag tracking

foo86 git at videolan.org
Sat May 21 04:01:37 CEST 2016


ffmpeg | branch: master | foo86 <foobaz86 at gmail.com> | Fri May 13 12:48:24 2016 +0300| [801dbf0269b1bb5bc70c550e971491e0aea9eb70] | committer: James Almer

avcodec/dca: simplify 'residual ok' flag tracking

Move this from separate structure field to a packet flag.

Behavior should be equivalent, except that residual flag is now properly
cleared when packet has no core frame at all.

Also print a message when forcing recovery mode due to invalid residual
to make debugging easier.

Signed-off-by: James Almer <jamrial at gmail.com>

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

 libavcodec/dcadec.c |   32 ++++++++++++++------------------
 libavcodec/dcadec.h |    7 ++++---
 2 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 417632f..565242d 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -193,10 +193,8 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
     if (AV_RB32(input) == DCA_SYNCWORD_CORE_BE) {
         int frame_size;
 
-        if ((ret = ff_dca_core_parse(&s->core, input, input_size)) < 0) {
-            s->core_residual_valid = 0;
+        if ((ret = ff_dca_core_parse(&s->core, input, input_size)) < 0)
             return ret;
-        }
 
         s->packet |= DCA_PACKET_CORE;
 
@@ -265,19 +263,20 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
             if (s->xll.chset[0].freq == 96000 && s->core.sample_rate == 48000)
                 x96_synth = 1;
 
-            if ((ret = ff_dca_core_filter_fixed(&s->core, x96_synth)) < 0) {
-                s->core_residual_valid = 0;
+            if ((ret = ff_dca_core_filter_fixed(&s->core, x96_synth)) < 0)
                 return ret;
-            }
 
             // Force lossy downmixed output on the first core frame filtered.
             // This prevents audible clicks when seeking and is consistent with
             // what reference decoder does when there are multiple channel sets.
-            if (!s->core_residual_valid) {
-                if (s->xll.nreschsets > 0 && s->xll.nchsets > 1)
-                    s->packet |= DCA_PACKET_RECOVERY;
-                s->core_residual_valid = 1;
+            if (!(prev_packet & DCA_PACKET_RESIDUAL) && s->xll.nreschsets > 0
+                && s->xll.nchsets > 1) {
+                av_log(avctx, AV_LOG_VERBOSE, "Forcing XLL recovery mode\n");
+                s->packet |= DCA_PACKET_RECOVERY;
             }
+
+            // Set 'residual ok' flag for the next frame
+            s->packet |= DCA_PACKET_RESIDUAL;
         }
 
         if ((ret = ff_dca_xll_filter_frame(&s->xll, frame)) < 0) {
@@ -286,17 +285,14 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
                 return ret;
             if (ret != AVERROR_INVALIDDATA || (avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
-            if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0) {
-                s->core_residual_valid = 0;
+            if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0)
                 return ret;
-            }
         }
     } else if (s->packet & DCA_PACKET_CORE) {
-        if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0) {
-            s->core_residual_valid = 0;
+        if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0)
             return ret;
-        }
-        s->core_residual_valid = !!(s->core.filter_mode & DCA_FILTER_MODE_FIXED);
+        if (s->core.filter_mode & DCA_FILTER_MODE_FIXED)
+            s->packet |= DCA_PACKET_RESIDUAL;
     } else {
         av_log(avctx, AV_LOG_ERROR, "No valid DCA sub-stream found\n");
         if (s->core_only)
@@ -317,7 +313,7 @@ static av_cold void dcadec_flush(AVCodecContext *avctx)
     ff_dca_xll_flush(&s->xll);
     ff_dca_lbr_flush(&s->lbr);
 
-    s->core_residual_valid = 0;
+    s->packet &= DCA_PACKET_MASK;
 }
 
 static av_cold int dcadec_close(AVCodecContext *avctx)
diff --git a/libavcodec/dcadec.h b/libavcodec/dcadec.h
index 5e47077..8528332 100644
--- a/libavcodec/dcadec.h
+++ b/libavcodec/dcadec.h
@@ -40,7 +40,10 @@
 #define DCA_PACKET_EXSS         0x02
 #define DCA_PACKET_XLL          0x04
 #define DCA_PACKET_LBR          0x08
-#define DCA_PACKET_RECOVERY     0x10
+#define DCA_PACKET_MASK         0x0f
+
+#define DCA_PACKET_RECOVERY     0x10    ///< Sync error recovery flag
+#define DCA_PACKET_RESIDUAL     0x20    ///< Core valid for residual decoding
 
 typedef struct DCAContext {
     const AVClass   *class;       ///< class for AVOptions
@@ -60,8 +63,6 @@ typedef struct DCAContext {
 
     int     packet; ///< Packet flags
 
-    int     core_residual_valid;    ///< Core valid for residual decoding
-
     int     request_channel_layout; ///< Converted from avctx.request_channel_layout
     int     core_only;              ///< Core only decoding flag
 } DCAContext;



More information about the ffmpeg-cvslog mailing list