Commit 801dbf02 authored by foo86's avatar foo86 Committed by 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: 's avatarJames Almer <jamrial@gmail.com>
parent a0349ae2
...@@ -193,10 +193,8 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data, ...@@ -193,10 +193,8 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
if (AV_RB32(input) == DCA_SYNCWORD_CORE_BE) { if (AV_RB32(input) == DCA_SYNCWORD_CORE_BE) {
int frame_size; int frame_size;
if ((ret = ff_dca_core_parse(&s->core, input, input_size)) < 0) { if ((ret = ff_dca_core_parse(&s->core, input, input_size)) < 0)
s->core_residual_valid = 0;
return ret; return ret;
}
s->packet |= DCA_PACKET_CORE; s->packet |= DCA_PACKET_CORE;
...@@ -265,19 +263,20 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data, ...@@ -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) if (s->xll.chset[0].freq == 96000 && s->core.sample_rate == 48000)
x96_synth = 1; x96_synth = 1;
if ((ret = ff_dca_core_filter_fixed(&s->core, x96_synth)) < 0) { if ((ret = ff_dca_core_filter_fixed(&s->core, x96_synth)) < 0)
s->core_residual_valid = 0;
return ret; return ret;
}
// Force lossy downmixed output on the first core frame filtered. // Force lossy downmixed output on the first core frame filtered.
// This prevents audible clicks when seeking and is consistent with // This prevents audible clicks when seeking and is consistent with
// what reference decoder does when there are multiple channel sets. // what reference decoder does when there are multiple channel sets.
if (!s->core_residual_valid) { if (!(prev_packet & DCA_PACKET_RESIDUAL) && s->xll.nreschsets > 0
if (s->xll.nreschsets > 0 && s->xll.nchsets > 1) && s->xll.nchsets > 1) {
s->packet |= DCA_PACKET_RECOVERY; av_log(avctx, AV_LOG_VERBOSE, "Forcing XLL recovery mode\n");
s->core_residual_valid = 1; 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) { if ((ret = ff_dca_xll_filter_frame(&s->xll, frame)) < 0) {
...@@ -286,17 +285,14 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data, ...@@ -286,17 +285,14 @@ static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
return ret; return ret;
if (ret != AVERROR_INVALIDDATA || (avctx->err_recognition & AV_EF_EXPLODE)) if (ret != AVERROR_INVALIDDATA || (avctx->err_recognition & AV_EF_EXPLODE))
return ret; return ret;
if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0) { if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0)
s->core_residual_valid = 0;
return ret; return ret;
}
} }
} else if (s->packet & DCA_PACKET_CORE) { } else if (s->packet & DCA_PACKET_CORE) {
if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0) { if ((ret = ff_dca_core_filter_frame(&s->core, frame)) < 0)
s->core_residual_valid = 0;
return ret; return ret;
} if (s->core.filter_mode & DCA_FILTER_MODE_FIXED)
s->core_residual_valid = !!(s->core.filter_mode & DCA_FILTER_MODE_FIXED); s->packet |= DCA_PACKET_RESIDUAL;
} else { } else {
av_log(avctx, AV_LOG_ERROR, "No valid DCA sub-stream found\n"); av_log(avctx, AV_LOG_ERROR, "No valid DCA sub-stream found\n");
if (s->core_only) if (s->core_only)
...@@ -317,7 +313,7 @@ static av_cold void dcadec_flush(AVCodecContext *avctx) ...@@ -317,7 +313,7 @@ static av_cold void dcadec_flush(AVCodecContext *avctx)
ff_dca_xll_flush(&s->xll); ff_dca_xll_flush(&s->xll);
ff_dca_lbr_flush(&s->lbr); ff_dca_lbr_flush(&s->lbr);
s->core_residual_valid = 0; s->packet &= DCA_PACKET_MASK;
} }
static av_cold int dcadec_close(AVCodecContext *avctx) static av_cold int dcadec_close(AVCodecContext *avctx)
......
...@@ -40,7 +40,10 @@ ...@@ -40,7 +40,10 @@
#define DCA_PACKET_EXSS 0x02 #define DCA_PACKET_EXSS 0x02
#define DCA_PACKET_XLL 0x04 #define DCA_PACKET_XLL 0x04
#define DCA_PACKET_LBR 0x08 #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 { typedef struct DCAContext {
const AVClass *class; ///< class for AVOptions const AVClass *class; ///< class for AVOptions
...@@ -60,8 +63,6 @@ typedef struct DCAContext { ...@@ -60,8 +63,6 @@ typedef struct DCAContext {
int packet; ///< Packet flags int packet; ///< Packet flags
int core_residual_valid; ///< Core valid for residual decoding
int request_channel_layout; ///< Converted from avctx.request_channel_layout int request_channel_layout; ///< Converted from avctx.request_channel_layout
int core_only; ///< Core only decoding flag int core_only; ///< Core only decoding flag
} DCAContext; } DCAContext;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment