Commit 51c73fcbbb for ffmpeg
commit 51c73fcbbbccacbf57acdb7a527e87d6016d8a99
Author: Rainbaby <r@bgr.jp>
Date: Fri Aug 28 16:18:09 2026 +0900
avcodec/cavsdec: decode the intra macroblock layer with AEC
The aec_mb_stuffing_bit ends a slice, after which the reader is
repositioned on the next start code. Field pictures use the scan of
clause 9.5.3 c).
Signed-off-by: Rainbaby <r@bgr.jp>
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c
index 3c3b95093b..0fdc9daca4 100644
--- a/libavcodec/cavs.c
+++ b/libavcodec/cavs.c
@@ -59,6 +59,17 @@ static const uint8_t tc_tab[64] = {
* or not yet decoded */
static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
+/**
+ * Inverse block scan method 2 (clause 9.5.3 c), figure 23), for field
+ * coded pictures, as the inverse ff_permute_scantable() expects.
+ */
+static const uint8_t cavs_scan_field[64] = {
+ 0, 8, 16, 1, 24, 32, 9, 17, 40, 48, 25, 2, 10, 56, 33, 18,
+ 3, 41, 49, 26, 11, 19, 4, 57, 34, 12, 42, 27, 20, 50, 35, 28,
+ 5, 13, 58, 43, 36, 21, 6, 29, 51, 44, 14, 22, 37, 59, 52, 30,
+ 45, 60, 38, 53, 46, 61, 54, 7, 62, 15, 23, 31, 39, 47, 55, 63,
+};
+
static const int8_t left_modifier_l[8] = { 0, -1, 6, -1, -1, 7, 6, 7 };
static const int8_t top_modifier_l[8] = { -1, 1, 5, -1, -1, 5, 7, 7 };
static const int8_t left_modifier_c[7] = { 5, -1, 2, -1, 6, 5, 6 };
@@ -772,10 +783,16 @@ int ff_cavs_init_top_lines(AVSContext *h)
4 * sizeof(*h->col_mv));
h->col_type_base = av_mallocz(h->mb_width * h->mb_height);
+ h->top_cbp = av_mallocz(h->mb_width);
+ h->top_c_pred_mode = av_mallocz(h->mb_width);
+
if (!h->top_qp || !h->top_mv[0] || !h->top_mv[1] || !h->top_pred_Y ||
+ !h->top_cbp || !h->top_c_pred_mode ||
!h->top_border_y || !h->top_border_u || !h->top_border_v ||
!h->col_mv || !h->col_type_base) {
av_freep(&h->top_qp);
+ av_freep(&h->top_cbp);
+ av_freep(&h->top_c_pred_mode);
av_freep(&h->top_mv[0]);
av_freep(&h->top_mv[1]);
av_freep(&h->top_pred_Y);
@@ -800,6 +817,9 @@ av_cold int ff_cavs_init(AVCodecContext *avctx)
ff_cavsdsp_init(&h->cdsp);
ff_init_scantable_permutation(permutation, h->cdsp.idct_perm);
ff_permute_scantable(h->permutated_scantable, ff_zigzag_direct, permutation);
+ ff_permute_scantable(h->permutated_scantable_field, cavs_scan_field,
+ permutation);
+ h->scantable = h->permutated_scantable;
h->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
@@ -843,6 +863,8 @@ av_cold int ff_cavs_end(AVCodecContext *avctx)
av_frame_free(&h->DPB[1].f);
av_freep(&h->top_qp);
+ av_freep(&h->top_cbp);
+ av_freep(&h->top_c_pred_mode);
av_freep(&h->top_mv[0]);
av_freep(&h->top_mv[1]);
av_freep(&h->top_pred_Y);
diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h
index 213a306ed5..d111714879 100644
--- a/libavcodec/cavs.h
+++ b/libavcodec/cavs.h
@@ -30,6 +30,7 @@
#include "libavutil/mem_internal.h"
#include "avcodec.h"
+#include "cavs_aec.h"
#include "cavsdsp.h"
#include "blockdsp.h"
#include "h264chroma.h"
@@ -185,8 +186,15 @@ typedef struct AVSContext {
int stream_revision; ///<0 for samples from 2006, 1 for rm52j encoder
int progressive;
int pic_structure;
- int skip_mode_flag; ///< select between skip_count or one skip_flag per MB
+ int skip_mode_flag; ///< select between skip_count or one skip_flag per MB
int aec_enable; ///< the macroblock layer uses AEC (AVS1-P16)
+ int aec_start; ///< byte offset of the current AEC slice's payload
+ CAVSAECContext aec; ///< AEC decoder state and contexts, clause 8.4
+ int prev_delta_qp; ///< PreviousDeltaQP of clause 9.4.8, an AEC context
+ int left_cbp; ///< MbCBP of the macroblock to the left
+ uint8_t *top_cbp; ///< MbCBP of the macroblock above, one per column
+ int left_c_pred_mode; ///< IntraChromaPredMode to the left, 8.4.4.2 e)
+ uint8_t *top_c_pred_mode; ///< IntraChromaPredMode above, per column
int loop_filter_disable;
int alpha_offset, beta_offset;
int ref_flag;
@@ -228,6 +236,10 @@ typedef struct AVSContext {
int cbp;
DECLARE_ALIGNED(32, int16_t, block)[64];
uint8_t permutated_scantable[64];
+ /** inverse block scan method 2 of clause 9.5.3 c), for field pictures */
+ uint8_t permutated_scantable_field[64];
+ /** the one of the two the current picture uses, selected in decode_pic() */
+ const uint8_t *scantable;
/** intra prediction is done with un-deblocked samples
they are saved here before deblocking the MB */
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index b0e6c1361a..4d1f1c9275 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -528,7 +528,7 @@ static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf,
{
int round = 1 << (shift - 1);
int pos = -1;
- const uint8_t *scantab = h->permutated_scantable;
+ const uint8_t *scantab = h->scantable;
/* inverse scan and dequantization */
while (--coeff_num >= 0) {
@@ -602,6 +602,255 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb,
}
+/*****************************************************************************
+ *
+ * advanced entropy coding (AEC), clause 8.4
+ *
+ ****************************************************************************/
+
+/* Table 51: start index of each ae(v) element's context models */
+#define AEC_MB_SKIP_RUN 0
+#define AEC_MB_TYPE 4
+#define AEC_MB_PART_TYPE 19
+#define AEC_INTRA_LUMA_PRED_MODE 22
+#define AEC_INTRA_CHROMA_PRED_MODE 26
+#define AEC_MB_REFERENCE_INDEX 30
+#define AEC_MV_DIFF_X 36
+#define AEC_MV_DIFF_Y 42
+#define AEC_CBP 48
+#define AEC_MB_QP_DELTA 54
+#define AEC_COEFF_FRAME_LUMA 58
+#define AEC_COEFF_FRAME_CHROMA 124
+#define AEC_COEFF_FIELD_LUMA 190
+#define AEC_COEFF_FIELD_CHROMA 256
+
+/* a conforming block's quantized coefficients span -2^(n+3)..2^(n+3)-1
+ * with n the sample precision, 8 for both profiles (clause 9.6.2) */
+#define CAVS_MAX_ABS_LEVEL 2048
+
+/* one trans_coefficient set: 14 + 32 + 20 models, coeffRun from index 46 */
+#define AEC_COEFF_NUM_CTX 66
+#define AEC_COEFF_RUN 46
+#define AEC_COEFF_RUN_NUM_CTX 20
+
+/** Table 52, priIdx as a function of lMax, which saturates at 5. */
+static const uint8_t cavs_aec_pri_idx[6] = { 0, 1, 2, 3, 3, 4 };
+
+/**
+ * Decode intra_luma_pred_mode (table 47) and derive IntraLumaPredMode
+ * from predIntraPredMode per clause 9.4.4.2 a).
+ */
+static int aec_intra_luma_pred_mode(AVSContext *h, int pred)
+{
+ int v = 0;
+
+ while (v < 4 &&
+ !ff_cavs_aec_decode_decision(&h->aec, AEC_INTRA_LUMA_PRED_MODE + v))
+ v++;
+
+ if (v == 0)
+ return pred;
+ if (v == 4) /* 4 stands for 0 (9.4.4.2 a) 2)) */
+ v = 0;
+ return v < pred ? v : v + 1;
+}
+
+/**
+ * Decode intra_chroma_pred_mode (table 48, 8.4.4.2 e)).
+ * @return IntraChromaPredMode, 0 to 3 (table 60)
+ */
+static int aec_intra_chroma_pred_mode(AVSContext *h)
+{
+ /* a and b of 8.4.4.2 e); non-intra neighbours hold INTRA_C_LP */
+ const int a = (h->flags & A_AVAIL) &&
+ h->left_c_pred_mode != INTRA_C_LP;
+ const int b = (h->flags & B_AVAIL) &&
+ h->top_c_pred_mode[h->mbx] != INTRA_C_LP;
+ int v;
+
+ if (!ff_cavs_aec_decode_decision(&h->aec,
+ AEC_INTRA_CHROMA_PRED_MODE + a + b))
+ v = 0;
+ else if (!ff_cavs_aec_decode_decision(&h->aec,
+ AEC_INTRA_CHROMA_PRED_MODE + 3))
+ v = 1;
+ else
+ v = 2 + ff_cavs_aec_decode_decision(&h->aec,
+ AEC_INTRA_CHROMA_PRED_MODE + 3);
+
+ h->left_c_pred_mode = v;
+ h->top_c_pred_mode[h->mbx] = v;
+ return v;
+}
+
+/**
+ * Decode cbp (table 50, 8.4.4.2 h), clause 9.4.7).
+ * @return MbCBP, a six bit mask over the block order numbers
+ */
+static int aec_cbp(AVSContext *h)
+{
+ const int left = (h->flags & A_AVAIL) ? ~h->left_cbp : 0;
+ const int top = (h->flags & B_AVAIL) ? ~h->top_cbp[h->mbx] : 0;
+ int cbp = 0;
+ int a, b;
+
+ a = (left >> 1) & 1; /* left macroblock, block 1 */
+ b = (top >> 2) & 1; /* above macroblock, block 2 */
+ cbp |= ff_cavs_aec_decode_decision(&h->aec, AEC_CBP + a + 2 * b) << 0;
+
+ a = ~cbp & 1; /* this macroblock, block 0 */
+ b = (top >> 3) & 1; /* above macroblock, block 3 */
+ cbp |= ff_cavs_aec_decode_decision(&h->aec, AEC_CBP + a + 2 * b) << 1;
+
+ a = (left >> 3) & 1; /* left macroblock, block 3 */
+ b = ~cbp & 1; /* this macroblock, block 0 */
+ cbp |= ff_cavs_aec_decode_decision(&h->aec, AEC_CBP + a + 2 * b) << 2;
+
+ a = (~cbp >> 2) & 1; /* this macroblock, block 2 */
+ b = (~cbp >> 1) & 1; /* this macroblock, block 1 */
+ cbp |= ff_cavs_aec_decode_decision(&h->aec, AEC_CBP + a + 2 * b) << 3;
+
+ if (ff_cavs_aec_decode_decision(&h->aec, AEC_CBP + 4)) {
+ if (ff_cavs_aec_decode_decision(&h->aec, AEC_CBP + 5))
+ cbp |= 3 << 4;
+ else
+ cbp |= 1 << (4 + ff_cavs_aec_decode_decision(&h->aec, AEC_CBP + 5));
+ }
+
+ h->left_cbp = cbp;
+ h->top_cbp[h->mbx] = cbp;
+ return cbp;
+}
+
+/**
+ * Decode mb_qp_delta (table 44 unary, 8.4.4.2 i)) and map the code
+ * number to the signed delta of clause 9.4.8.
+ */
+static int aec_mb_qp_delta(AVSContext *h, int *delta)
+{
+ int ctx = AEC_MB_QP_DELTA + (h->prev_delta_qp != 0);
+ int v = 0;
+
+ while (!ff_cavs_aec_decode_decision(&h->aec, ctx)) {
+ v++;
+ ctx = AEC_MB_QP_DELTA + (v == 1 ? 2 : 3);
+ if (v > 64) {
+ av_log(h->avctx, AV_LOG_ERROR, "mb_qp_delta out of range\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (v)
+ v = (v & 1) ? (v + 1) / 2 : -((v + 1) / 2);
+ if (v < -32 || v > 31) {
+ av_log(h->avctx, AV_LOG_ERROR, "mb_qp_delta out of range\n");
+ return AVERROR_INVALIDDATA;
+ }
+ *delta = v;
+ return 0;
+}
+
+/**
+ * Decode the trans_coefficient pairs of one 8x8 block (8.4.4.2 j) and k)).
+ * @param chroma selects the chroma half of the context sets of table 51
+ */
+static int decode_residual_block_aec(AVSContext *h, int chroma, int qp,
+ uint8_t *dst, ptrdiff_t stride)
+{
+ int16_t level_buf[65];
+ uint8_t run_buf[65];
+ int16_t *block = h->block;
+ int lmax = 0, pos = 0, i, base, ret;
+
+ if (h->pic_structure)
+ base = chroma ? AEC_COEFF_FRAME_CHROMA : AEC_COEFF_FRAME_LUMA;
+ else
+ base = chroma ? AEC_COEFF_FIELD_CHROMA : AEC_COEFF_FIELD_LUMA;
+
+ for (i = 0; i < 65; i++) {
+ const int pri = cavs_aec_pri_idx[FFMIN(lmax, 5)];
+ int ctx_lvl = ff_cavs_aec_ctx_idx(base, AEC_COEFF_NUM_CTX,
+ pri * 3 - (pri != 0));
+ int ctx_run = ff_cavs_aec_ctx_idx(base + AEC_COEFF_RUN,
+ AEC_COEFF_RUN_NUM_CTX, pri * 4);
+ int abs_level, run_val;
+
+ if (ctx_lvl < 0 || ctx_run < 0)
+ return FFMIN(ctx_lvl, ctx_run);
+ if (get_bits_left(&h->gb) <= 0)
+ return AVERROR_INVALIDDATA;
+
+ /* coeffLevel, table 44 unary; secIdx as in IEEE 1857-2023 table 36,
+ * whose lMax == 0 column has no secIdx 2 */
+ if (!lmax) {
+ abs_level = 0;
+ if (!ff_cavs_aec_decode_decision(&h->aec, ctx_lvl)) {
+ do {
+ abs_level++;
+ if (abs_level >= CAVS_MAX_ABS_LEVEL) {
+ av_log(h->avctx, AV_LOG_ERROR, "AbsLevel too large\n");
+ return AVERROR_INVALIDDATA;
+ }
+ } while (!ff_cavs_aec_decode_decision(&h->aec, ctx_lvl + 1));
+ }
+ abs_level++; /* clause 9.5.2 a) */
+ } else {
+ int ctx_w = ff_cavs_aec_ctx_idx(base, AEC_COEFF_NUM_CTX,
+ 14 + (pos >> 1));
+ if (ctx_w < 0)
+ return ctx_w;
+ if (ff_cavs_aec_decode_decision_w(&h->aec, ctx_lvl, ctx_w))
+ break; /* AbsLevel 0, end of block */
+ abs_level = 1;
+ if (!ff_cavs_aec_decode_decision(&h->aec, ctx_lvl + 1)) {
+ do {
+ abs_level++;
+ if (abs_level > CAVS_MAX_ABS_LEVEL) {
+ av_log(h->avctx, AV_LOG_ERROR, "AbsLevel too large\n");
+ return AVERROR_INVALIDDATA;
+ }
+ } while (!ff_cavs_aec_decode_decision(&h->aec, ctx_lvl + 2));
+ }
+ }
+
+ if (ff_cavs_aec_decode_bypass(&h->aec))
+ level_buf[i] = -abs_level;
+ else
+ level_buf[i] = abs_level;
+ if (level_buf[i] < -CAVS_MAX_ABS_LEVEL ||
+ level_buf[i] >= CAVS_MAX_ABS_LEVEL) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "coefficient level out of range\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx_run += abs_level > 1 ? 2 : 0;
+ run_val = 0;
+ if (!ff_cavs_aec_decode_decision(&h->aec, ctx_run)) {
+ do {
+ run_val++;
+ if (run_val > 64) {
+ av_log(h->avctx, AV_LOG_ERROR, "RunVal too large\n");
+ return AVERROR_INVALIDDATA;
+ }
+ } while (!ff_cavs_aec_decode_decision(&h->aec, ctx_run + 1));
+ }
+ run_buf[i] = run_val + 1; /* scan positions consumed, 9.5.3 b) */
+
+ /* lMax is updated with this coefficient before the next pair */
+ lmax = FFMAX(lmax, abs_level);
+ pos = FFMIN(pos + run_val + 1, 63);
+ }
+
+ ret = dequant(h, level_buf, run_buf, block, dequant_mul[qp],
+ dequant_shift[qp], i);
+ if (ret >= 0)
+ h->cdsp.cavs_idct8_add(dst, block, stride);
+ h->bdsp.clear_block(block);
+ return ret;
+}
+
+
/**
* Tell whether the byte aligned 00 00 01 at @p offset is a start code: in a
* de-emulated payload it may be a coincidence (annex A).
@@ -626,17 +875,74 @@ static int is_start_code_offset(AVSContext *h, int offset)
return 0;
}
+/**
+ * Position the reader on the start code that ends an AEC slice: the first
+ * one at or after the slice's own payload. The reader position is not
+ * reliable: the arithmetic decoder's look ahead has run past it.
+ */
+static void aec_end_of_slice(AVSContext *h)
+{
+ GetBitContext *gb = &h->gb;
+ const uint8_t *buf = gb->buffer;
+ int size = gb->size_in_bits >> 3;
+ int i = h->aec_start;
+
+ /* release gb; check_for_slice() waits for this */
+ h->aec.gb = NULL;
+
+ for (; i + 2 < size; i++)
+ if (!buf[i] && !buf[i + 1] && buf[i + 2] == 1 &&
+ is_start_code_offset(h, i))
+ break;
+ if (init_get_bits8(gb, buf, size) >= 0)
+ skip_bits_long(gb, i * 8);
+}
+
+/**
+ * Read mb_qp_delta when the macroblock has coefficients and the picture's qp
+ * is not fixed, and keep PreviousDeltaQP for the AEC contexts (clause 9.4.8).
+ */
+static int decode_mb_qp_delta(AVSContext *h)
+{
+ int delta = 0;
+
+ if (h->cbp && !h->qp_fixed) {
+ if (h->aec_enable) {
+ int ret = aec_mb_qp_delta(h, &delta);
+ if (ret < 0)
+ return ret;
+ } else {
+ delta = get_se_golomb(&h->gb);
+ }
+ h->qp = (h->qp + (unsigned)delta) & 63;
+ }
+ h->prev_delta_qp = delta;
+ return 0;
+}
+
+/** Decode one 8x8 block's residual with the picture's entropy coder. */
+static int decode_residual(AVSContext *h, const struct dec_2dvlc *r,
+ int esc_golomb_order, int chroma, int qp,
+ uint8_t *dst, ptrdiff_t stride)
+{
+ if (h->aec_enable)
+ return decode_residual_block_aec(h, chroma, qp, dst, stride);
+ return decode_residual_block(h, &h->gb, r, esc_golomb_order, qp, dst,
+ stride);
+}
+
static inline int decode_residual_chroma(AVSContext *h)
{
+ const int qp = ff_cavs_chroma_qp[h->qp];
+ int ret;
+
if (h->cbp & (1 << 4)) {
- int ret = decode_residual_block(h, &h->gb, chroma_dec, 0,
- ff_cavs_chroma_qp[h->qp], h->cu, h->c_stride);
+ ret = decode_residual(h, chroma_dec, 0, 1, qp, h->cu, h->c_stride);
if (ret < 0)
return ret;
}
if (h->cbp & (1 << 5)) {
- int ret = decode_residual_block(h, &h->gb, chroma_dec, 0,
- ff_cavs_chroma_qp[h->qp], h->cv, h->c_stride);
+ ret = decode_residual(h, chroma_dec, 0, 1, qp, h->cv, h->c_stride);
if (ret < 0)
return ret;
}
@@ -708,29 +1014,41 @@ static int decode_mb_i(AVSContext *h, int cbp_code)
predpred = FFMIN(nA, nB);
if (predpred == NOT_AVAIL) // if either is not available
predpred = INTRA_L_LP;
- if (!get_bits1(gb)) {
+ if (h->aec_enable) {
+ predpred = aec_intra_luma_pred_mode(h, predpred);
+ } else if (!get_bits1(gb)) {
int rem_mode = get_bits(gb, 2);
predpred = rem_mode + (rem_mode >= predpred);
}
h->pred_mode_Y[pos] = predpred;
}
- pred_mode_uv = get_ue_golomb_31(gb);
- if (pred_mode_uv > 6) {
- av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");
- return AVERROR_INVALIDDATA;
+ if (h->aec_enable) {
+ pred_mode_uv = aec_intra_chroma_pred_mode(h);
+ } else {
+ pred_mode_uv = get_ue_golomb_31(gb);
+ if (pred_mode_uv > 6) {
+ av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");
+ return AVERROR_INVALIDDATA;
+ }
}
ff_cavs_modify_mb_i(h, &pred_mode_uv);
/* get coded block pattern */
- if (h->cur.f->pict_type == AV_PICTURE_TYPE_I)
- cbp_code = get_ue_golomb(gb);
- if (cbp_code > 63U) {
- av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n");
- return AVERROR_INVALIDDATA;
+ if (h->aec_enable) {
+ /* under AEC an intra MB codes cbp too (table 26, clause 9.4.7) */
+ h->cbp = aec_cbp(h);
+ } else {
+ if (h->cur.f->pict_type == AV_PICTURE_TYPE_I)
+ cbp_code = get_ue_golomb(gb);
+ if (cbp_code > 63U) {
+ av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n");
+ return AVERROR_INVALIDDATA;
+ }
+ h->cbp = cbp_tab[cbp_code][0];
}
- h->cbp = cbp_tab[cbp_code][0];
- if (h->cbp && !h->qp_fixed)
- h->qp = (h->qp + (unsigned)get_se_golomb(gb)) & 63; //qp_delta
+ ret = decode_mb_qp_delta(h);
+ if (ret < 0)
+ return ret;
/* luma intra prediction interleaved with residual decode/transform/add */
for (block = 0; block < 4; block++) {
@@ -739,7 +1057,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code)
h->intra_pred_l[h->pred_mode_Y[scan3x3[block]]]
(d, top, left, h->l_stride);
if (h->cbp & (1<<block)) {
- ret = decode_residual_block(h, gb, intra_dec, 1, h->qp, d, h->l_stride);
+ ret = decode_residual(h, intra_dec, 1, 0, h->qp, d, h->l_stride);
if (ret < 0)
return ret;
}
@@ -1014,6 +1332,9 @@ static inline int check_for_slice(AVSContext *h)
if (h->mbx)
return 0;
+ /* an AEC slice ends with its stuffing bit, not at a start code (7.2.4) */
+ if (h->aec_enable && h->aec.gb)
+ return 0;
align = (-get_bits_count(gb)) & 7;
/* check for stuffing byte */
if (!align && (show_bits(gb, 8) == 0x80))
@@ -1037,6 +1358,13 @@ static inline int check_for_slice(AVSContext *h)
ret = decode_slice_header(h, gb);
if (ret < 0)
return ret;
+ if (h->aec_enable) {
+ /* aec_byte_alignment_bit padding, then 8.4.1 */
+ align_get_bits(gb);
+ h->aec_start = get_bits_count(gb) >> 3;
+ ff_cavs_aec_init(&h->aec, gb);
+ h->prev_delta_qp = 0; /* reset with PreviousQP, clause 9.3 */
+ }
return 1;
}
return 0;
@@ -1134,6 +1462,9 @@ static int decode_pic(AVSContext *h)
h->pic_structure = 1;
if (!h->progressive)
h->pic_structure = get_bits1(&h->gb);
+ /* a field coded picture uses inverse block scan method 2 (9.5.3 c)) */
+ h->scantable = h->pic_structure ? h->permutated_scantable
+ : h->permutated_scantable_field;
if (!h->pic_structure && h->stc == PIC_PB_START_CODE)
skip_bits1(&h->gb); //advanced_pred_mode_disable
skip_bits1(&h->gb); //top_field_first
@@ -1175,12 +1506,19 @@ static int decode_pic(AVSContext *h)
}
ret = 0;
+ h->aec.gb = NULL; /* started by the first slice header */
h->pic_data_end = 0;
if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
do {
ret = check_for_slice(h);
if (ret < 0)
break;
+ if (h->aec_enable && !h->aec.gb) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "AEC picture without a slice header\n");
+ ret = AVERROR_INVALIDDATA;
+ break;
+ }
if (h->pic_data_end) {
av_log(h->avctx, AV_LOG_ERROR,
"picture data ended before MB %d\n", h->mbidx);
@@ -1190,6 +1528,8 @@ static int decode_pic(AVSContext *h)
ret = decode_mb_i(h, 0);
if (ret < 0)
break;
+ if (h->aec_enable && ff_cavs_aec_decode_stuffing_bit(&h->aec))
+ aec_end_of_slice(h);
} while (ff_cavs_next_mb(h));
} else if (h->cur.f->pict_type == AV_PICTURE_TYPE_P) {
do {