[FFmpeg-devel] [PATCH 2/5] avcodec: use the new AVFrame interlace flags in all decoders and encoders
James Almer
jamrial at gmail.com
Mon Apr 24 15:31:34 EEST 2023
Signed-off-by: James Almer <jamrial at gmail.com>
---
libavcodec/cfhd.c | 6 +++---
libavcodec/crystalhd.c | 4 ++--
libavcodec/cuviddec.c | 9 ++++++---
libavcodec/decode.c | 2 ++
libavcodec/dnxhddec.c | 14 +++++++-------
libavcodec/dnxhdenc.c | 3 ++-
libavcodec/dvdec.c | 12 ++++++------
libavcodec/dvenc.c | 4 ++--
libavcodec/encode.c | 5 +++++
libavcodec/ffv1dec.c | 14 +++++++-------
libavcodec/ffv1enc.c | 4 ++--
libavcodec/h264_slice.c | 32 ++++++++++++++++----------------
libavcodec/hevc_refs.c | 7 +++++--
libavcodec/libx264.c | 6 +++---
libavcodec/m101.c | 10 +++++-----
libavcodec/mjpegdec.c | 4 ++--
libavcodec/mmaldec.c | 4 ++--
libavcodec/mpeg12enc.c | 2 +-
libavcodec/mpeg4videoenc.c | 2 +-
libavcodec/mpegvideo_dec.c | 10 +++++-----
libavcodec/nvenc.c | 2 +-
libavcodec/pngdec.c | 2 +-
libavcodec/proresdec2.c | 6 +++---
libavcodec/proresenc_anatoliy.c | 3 ++-
libavcodec/proresenc_kostya.c | 6 +++---
libavcodec/qsvdec.c | 6 +++---
libavcodec/qsvenc.c | 6 +++---
libavcodec/rawdec.c | 8 ++++----
libavcodec/rkmppdec.c | 6 ++++--
libavcodec/utvideodec.c | 2 +-
libavcodec/v210dec.c | 4 ++--
libavcodec/vaapi_hevc.c | 4 ++--
libavcodec/vc1_mc.c | 18 +++++++++---------
libavcodec/vc1dec.c | 4 ++--
34 files changed, 124 insertions(+), 107 deletions(-)
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index c23eb069c6..42d7dcc3f6 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -1087,8 +1087,8 @@ finish:
dst += dst_linesize;
}
} else {
- av_log(avctx, AV_LOG_DEBUG, "interlaced frame ? %d", pic->interlaced_frame);
- pic->interlaced_frame = 1;
+ av_log(avctx, AV_LOG_DEBUG, "interlaced frame ? %d", !!(pic->flags & AV_FRAME_FLAG_INTERLACED));
+ pic->flags |= AV_FRAME_FLAG_INTERLACED;
low = s->plane[plane].subband[0];
high = s->plane[plane].subband[7];
output = s->plane[plane].l_h[6];
@@ -1284,7 +1284,7 @@ finish:
dst += dst_linesize;
}
} else {
- pic->interlaced_frame = 1;
+ pic->flags |= AV_FRAME_FLAG_INTERLACED;
low = s->plane[plane].l_h[7];
high = s->plane[plane].subband[14];
output = s->plane[plane].l_h[6];
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index a48d60f123..86f6cfa6c1 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -543,9 +543,9 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
av_image_copy_plane(dst, dStride, src, sStride, bwidth, height);
}
- frame->interlaced_frame = interlaced;
+ frame->flags |= AV_FRAME_FLAG_INTERLACED * !!interlaced;
if (interlaced)
- frame->top_field_first = !bottom_first;
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !bottom_first;
frame->pts = pkt_pts;
diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
index 76e70aa648..5904cce583 100644
--- a/libavcodec/cuviddec.c
+++ b/libavcodec/cuviddec.c
@@ -631,10 +631,13 @@ FF_DISABLE_DEPRECATION_WARNINGS
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- frame->interlaced_frame = !parsed_frame.is_deinterlacing && !parsed_frame.dispinfo.progressive_frame;
+ if (!parsed_frame.is_deinterlacing && !parsed_frame.dispinfo.progressive_frame) {
+ frame->flags |= AV_FRAME_FLAG_INTERLACED |
+ (AV_FRAME_FLAG_TOP_FIELD_FIRST * !!parsed_frame.dispinfo.top_field_first);
+ }
- if (frame->interlaced_frame)
- frame->top_field_first = parsed_frame.dispinfo.top_field_first;
+ if (frame->flags & AV_FRAME_FLAG_INTERLACED)
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!parsed_frame.dispinfo.top_field_first;
} else if (ctx->decoder_flushing) {
ret = AVERROR_EOF;
} else {
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 40f5a3ba59..73bba99750 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -570,6 +570,8 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
}
if (!ret) {
+ frame->interlaced_frame = !!(frame->flags & AV_FRAME_FLAG_INTERLACED);
+ frame->top_field_first = !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
frame->best_effort_timestamp = guess_correct_pts(avctx,
frame->pts,
frame->pkt_dts);
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 7cc4f94c7f..b98a0237ab 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -195,8 +195,8 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
}
if (buf[5] & 2) { /* interlaced */
ctx->cur_field = first_field ? buf[5] & 1 : !ctx->cur_field;
- frame->interlaced_frame = 1;
- frame->top_field_first = first_field ^ ctx->cur_field;
+ frame->flags |= AV_FRAME_FLAG_INTERLACED;
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!(first_field ^ ctx->cur_field);
av_log(ctx->avctx, AV_LOG_DEBUG,
"interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field);
} else {
@@ -298,7 +298,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
ctx->mb_width = (ctx->width + 15)>> 4;
ctx->mb_height = AV_RB16(buf + 0x16c);
- if ((ctx->height + 15) >> 4 == ctx->mb_height && frame->interlaced_frame)
+ if ((ctx->height + 15) >> 4 == ctx->mb_height && (frame->flags & AV_FRAME_FLAG_INTERLACED))
ctx->height <<= 1;
av_log(ctx->avctx, AV_LOG_VERBOSE, "%dx%d, 4:%s %d bits, MBAFF=%d ACT=%d\n",
@@ -316,7 +316,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
}
ctx->data_offset = 0x280;
}
- if ((ctx->mb_height << frame->interlaced_frame) > (ctx->height + 15) >> 4) {
+ if ((ctx->mb_height << !!(frame->flags & AV_FRAME_FLAG_INTERLACED)) > (ctx->height + 15) >> 4) {
av_log(ctx->avctx, AV_LOG_ERROR,
"mb height too big: %d\n", ctx->mb_height);
return AVERROR_INVALIDDATA;
@@ -530,7 +530,7 @@ static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row,
return AVERROR_INVALIDDATA;
}
- if (frame->interlaced_frame) {
+ if (frame->flags & AV_FRAME_FLAG_INTERLACED) {
dct_linesize_luma <<= 1;
dct_linesize_chroma <<= 1;
}
@@ -539,7 +539,7 @@ static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row,
dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444));
dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444));
- if (frame->interlaced_frame && ctx->cur_field) {
+ if ((frame->flags & AV_FRAME_FLAG_INTERLACED) && ctx->cur_field) {
dest_y += frame->linesize[0];
dest_u += frame->linesize[1];
dest_v += frame->linesize[2];
@@ -659,7 +659,7 @@ decode_coding_unit:
ctx->buf = buf + ctx->data_offset;
avctx->execute2(avctx, dnxhd_decode_row, picture, NULL, ctx->mb_height);
- if (first_field && picture->interlaced_frame) {
+ if (first_field && picture->flags & AV_FRAME_FLAG_INTERLACED) {
buf += ctx->cid_table->coding_unit_size;
buf_size -= ctx->cid_table->coding_unit_size;
first_field = 0;
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 176bf972d8..a1852fa6b7 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -1251,7 +1251,8 @@ static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
}
- ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
+ ctx->cur_field = (frame->flags & AV_FRAME_FLAG_INTERLACED) &&
+ !(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
}
static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index afc4bb0bcd..2b4d70ac3d 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -670,14 +670,14 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame,
/* Determine the codec's field order from the packet */
if ( *vsc_pack == DV_VIDEO_CONTROL ) {
if (avctx->height == 720) {
- frame->interlaced_frame = 0;
- frame->top_field_first = 0;
+ frame->flags &= ~AV_FRAME_FLAG_INTERLACED;
+ frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
} else if (avctx->height == 1080) {
- frame->interlaced_frame = 1;
- frame->top_field_first = (vsc_pack[3] & 0x40) == 0x40;
+ frame->flags |= AV_FRAME_FLAG_INTERLACED;
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * ((vsc_pack[3] & 0x40) == 0x40);
} else {
- frame->interlaced_frame = (vsc_pack[3] & 0x10) == 0x10;
- frame->top_field_first = !(vsc_pack[3] & 0x40);
+ frame->flags |= AV_FRAME_FLAG_INTERLACED * ((vsc_pack[3] & 0x10) == 0x10);
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !(vsc_pack[3] & 0x40);
}
}
diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c
index cd442b524d..7bd50174b7 100644
--- a/libavcodec/dvenc.c
+++ b/libavcodec/dvenc.c
@@ -1048,9 +1048,9 @@ static inline int dv_write_pack(enum DVPackType pack_id, DVEncContext *c,
int fs;
if (c->avctx->height >= 720)
- fs = c->avctx->height == 720 || c->frame->top_field_first ? 0x40 : 0x00;
+ fs = c->avctx->height == 720 || (c->frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x40 : 0x00;
else
- fs = c->frame->top_field_first ? 0x00 : 0x40;
+ fs = (c->frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x00 : 0x40;
if (DV_PROFILE_IS_HD(c->sys) ||
(int)(av_q2d(c->avctx->sample_aspect_ratio) *
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 0f11efc481..dfcdce6a3c 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -192,6 +192,11 @@ int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
av_frame_move_ref(frame, avci->buffer_frame);
+ if (frame->interlaced_frame)
+ frame->flags |= AV_FRAME_FLAG_INTERLACED;
+ if (frame->top_field_first)
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
+
return 0;
}
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index a3f9302233..c49db83b5c 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -217,13 +217,13 @@ static int decode_slice_header(const FFV1Context *f, FFV1Context *fs)
ps = get_symbol(c, state, 0);
if (ps == 1) {
- f->cur->interlaced_frame = 1;
- f->cur->top_field_first = 1;
+ f->cur->flags |= AV_FRAME_FLAG_INTERLACED;
+ f->cur->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
} else if (ps == 2) {
- f->cur->interlaced_frame = 1;
- f->cur->top_field_first = 0;
+ f->cur->flags |= AV_FRAME_FLAG_INTERLACED;
+ f->cur->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
} else if (ps == 3) {
- f->cur->interlaced_frame = 0;
+ f->cur->flags &= ~AV_FRAME_FLAG_INTERLACED;
}
f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0);
f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0);
@@ -881,9 +881,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
if (f->version < 3 && avctx->field_order > AV_FIELD_PROGRESSIVE) {
/* we have interlaced material flagged in container */
- p->interlaced_frame = 1;
+ p->flags |= AV_FRAME_FLAG_INTERLACED;
if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)
- p->top_field_first = 1;
+ p->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
}
f->avctx = avctx;
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index fb12776cc2..746f717568 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -916,10 +916,10 @@ static void encode_slice_header(FFV1Context *f, FFV1Context *fs)
put_symbol(c, state, f->plane[j].quant_table_index, 0);
av_assert0(f->plane[j].quant_table_index == f->context_model);
}
- if (!f->cur_enc_frame->interlaced_frame)
+ if (!(f->cur_enc_frame->flags & AV_FRAME_FLAG_INTERLACED))
put_symbol(c, state, 3, 0);
else
- put_symbol(c, state, 1 + !f->cur_enc_frame->top_field_first, 0);
+ put_symbol(c, state, 1 + !(f->cur_enc_frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST), 0);
put_symbol(c, state, f->cur_enc_frame->sample_aspect_ratio.num, 0);
put_symbol(c, state, f->cur_enc_frame->sample_aspect_ratio.den, 0);
if (f->version > 3) {
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index d05b83a121..f44b60c642 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1155,9 +1155,10 @@ static int h264_export_frame_props(H264Context *h)
const SPS *sps = h->ps.sps;
H264Picture *cur = h->cur_pic_ptr;
AVFrame *out = cur->f;
+ int interlaced_frame = 0, top_field_first = 0;
int ret;
- out->interlaced_frame = 0;
+ out->flags &= ~AV_FRAME_FLAG_INTERLACED;
out->repeat_pict = 0;
/* Signal interlacing information externally. */
@@ -1181,15 +1182,15 @@ static int h264_export_frame_props(H264Context *h)
break;
case H264_SEI_PIC_STRUCT_TOP_FIELD:
case H264_SEI_PIC_STRUCT_BOTTOM_FIELD:
- out->interlaced_frame = 1;
+ interlaced_frame = 1;
break;
case H264_SEI_PIC_STRUCT_TOP_BOTTOM:
case H264_SEI_PIC_STRUCT_BOTTOM_TOP:
if (FIELD_OR_MBAFF_PICTURE(h))
- out->interlaced_frame = 1;
+ interlaced_frame = 1;
else
// try to flag soft telecine progressive
- out->interlaced_frame = h->prev_interlaced_frame;
+ interlaced_frame = !!h->prev_interlaced_frame;
break;
case H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
case H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
@@ -1208,35 +1209,34 @@ static int h264_export_frame_props(H264Context *h)
if ((pt->ct_type & 3) &&
pt->pic_struct <= H264_SEI_PIC_STRUCT_BOTTOM_TOP)
- out->interlaced_frame = (pt->ct_type & (1 << 1)) != 0;
+ interlaced_frame = ((pt->ct_type & (1 << 1)) != 0);
} else {
/* Derive interlacing flag from used decoding process. */
- out->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
+ interlaced_frame = !!FIELD_OR_MBAFF_PICTURE(h);
}
- h->prev_interlaced_frame = out->interlaced_frame;
+ h->prev_interlaced_frame = interlaced_frame;
if (cur->field_poc[0] != cur->field_poc[1]) {
/* Derive top_field_first from field pocs. */
- out->top_field_first = cur->field_poc[0] < cur->field_poc[1];
+ top_field_first = (cur->field_poc[0] < cur->field_poc[1]);
} else {
if (sps->pic_struct_present_flag && h->sei.picture_timing.present) {
/* Use picture timing SEI information. Even if it is a
* information of a past frame, better than nothing. */
if (h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM ||
h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
- out->top_field_first = 1;
- else
- out->top_field_first = 0;
- } else if (out->interlaced_frame) {
+ top_field_first = 1;
+ } else if (interlaced_frame) {
/* Default to top field first when pic_struct_present_flag
* is not set but interlaced frame detected */
- out->top_field_first = 1;
- } else {
+ top_field_first = 1;
+ } // else
/* Most likely progressive */
- out->top_field_first = 0;
- }
}
+ out->flags |= (AV_FRAME_FLAG_INTERLACED * interlaced_frame) |
+ (AV_FRAME_FLAG_TOP_FIELD_FIRST * top_field_first);
+
ret = ff_h2645_sei_to_frame(out, &h->sei.common, AV_CODEC_ID_H264, h->avctx,
&sps->vui, sps->bit_depth_luma, sps->bit_depth_chroma,
cur->poc + (unsigned)(h->poc_offset << 5));
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 96153a2459..e9be02c489 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -111,8 +111,11 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
for (j = 0; j < frame->ctb_count; j++)
frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data;
- frame->frame->top_field_first = s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD;
- frame->frame->interlaced_frame = (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD);
+ if (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD)
+ frame->frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
+ if ((s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) ||
+ (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD))
+ frame->frame->flags |= AV_FRAME_FLAG_INTERLACED;
if (s->avctx->hwaccel) {
const AVHWAccel *hwaccel = s->avctx->hwaccel;
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index cfdd422236..3aea29e995 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -196,9 +196,9 @@ static void reconfig_encoder(AVCodecContext *ctx, const AVFrame *frame)
if (x4->avcintra_class < 0) {
- if (x4->params.b_interlaced && x4->params.b_tff != frame->top_field_first) {
+ if (x4->params.b_interlaced && x4->params.b_tff != !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)) {
- x4->params.b_tff = frame->top_field_first;
+ x4->params.b_tff = !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
x264_encoder_reconfig(x4->enc, &x4->params);
}
if (x4->params.vui.i_sar_height*ctx->sample_aspect_ratio.num != ctx->sample_aspect_ratio.den * x4->params.vui.i_sar_width) {
@@ -339,7 +339,7 @@ static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
}
return 0;
- } else if (frame->interlaced_frame) {
+ } else if (frame->flags & AV_FRAME_FLAG_INTERLACED) {
if (!x4->roi_warned) {
x4->roi_warned = 1;
av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
diff --git a/libavcodec/m101.c b/libavcodec/m101.c
index 3def577b74..2d2855a770 100644
--- a/libavcodec/m101.c
+++ b/libavcodec/m101.c
@@ -68,14 +68,14 @@ static int m101_decode_frame(AVCodecContext *avctx, AVFrame *frame,
return ret;
frame->pict_type = AV_PICTURE_TYPE_I;
frame->key_frame = 1;
- frame->interlaced_frame = ((avctx->extradata[3*4] & 3) != 3);
- if (frame->interlaced_frame)
- frame->top_field_first = avctx->extradata[3*4] & 1;
+ frame->flags |= AV_FRAME_FLAG_INTERLACED * ((avctx->extradata[3*4] & 3) != 3);
+ if (frame->flags & AV_FRAME_FLAG_INTERLACED)
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * (avctx->extradata[3*4] & 1);
for (y = 0; y < avctx->height; y++) {
int src_y = y;
- if (frame->interlaced_frame)
- src_y = ((y&1)^frame->top_field_first) ? y/2 : (y/2 + avctx->height/2);
+ if (frame->flags & AV_FRAME_FLAG_INTERLACED)
+ src_y = ((y&1) ^ !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)) ? y/2 : (y/2 + avctx->height/2);
if (bits == 8) {
uint8_t *line = frame->data[0] + y*frame->linesize[0];
memcpy(line, buf + src_y*stride, 2*avctx->width);
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 9b55002c4b..a710d21793 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -441,8 +441,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
s->height < ((s->orig_height * 3) / 4)) {
s->interlaced = 1;
s->bottom_field = s->interlace_polarity;
- s->picture_ptr->interlaced_frame = 1;
- s->picture_ptr->top_field_first = !s->interlace_polarity;
+ s->picture_ptr->flags |= AV_FRAME_FLAG_INTERLACED;
+ s->picture_ptr->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !s->interlace_polarity;
height *= 2;
}
diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c
index 3092f58510..f4b86af1fe 100644
--- a/libavcodec/mmaldec.c
+++ b/libavcodec/mmaldec.c
@@ -622,8 +622,8 @@ static int ffmal_copy_frame(AVCodecContext *avctx, AVFrame *frame,
MMALDecodeContext *ctx = avctx->priv_data;
int ret = 0;
- frame->interlaced_frame = ctx->interlaced_frame;
- frame->top_field_first = ctx->top_field_first;
+ frame->flags |= AV_FRAME_FLAG_INTERLACED * !!ctx->interlaced_frame;
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!ctx->top_field_first;
if (avctx->pix_fmt == AV_PIX_FMT_MMAL) {
if (!ctx->pool_out)
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index a932b59678..c7438fbe07 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -530,7 +530,7 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s)
if (s->progressive_sequence)
put_bits(&s->pb, 1, 0); /* no repeat */
else
- put_bits(&s->pb, 1, s->current_picture_ptr->f->top_field_first);
+ put_bits(&s->pb, 1, !!(s->current_picture_ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
/* XXX: optimize the generation of this flag with entropy measures */
s->frame_pred_frame_dct = s->progressive_sequence;
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index c3e9ebea45..777635c40c 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1101,7 +1101,7 @@ int ff_mpeg4_encode_picture_header(MpegEncContext *s)
}
put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */
if (!s->progressive_sequence) {
- put_bits(&s->pb, 1, s->current_picture_ptr->f->top_field_first);
+ put_bits(&s->pb, 1, !!(s->current_picture_ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
put_bits(&s->pb, 1, s->alternate_scan);
}
// FIXME sprite stuff
diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c
index 522a0aada5..482f388b99 100644
--- a/libavcodec/mpegvideo_dec.c
+++ b/libavcodec/mpegvideo_dec.c
@@ -331,15 +331,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
s->current_picture_ptr = pic;
// FIXME use only the vars from current_pic
- s->current_picture_ptr->f->top_field_first = s->top_field_first;
+ s->current_picture_ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!s->top_field_first;
if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO ||
s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
if (s->picture_structure != PICT_FRAME)
- s->current_picture_ptr->f->top_field_first =
- (s->picture_structure == PICT_TOP_FIELD) == s->first_field;
+ s->current_picture_ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST *
+ ((s->picture_structure == PICT_TOP_FIELD) == s->first_field);
}
- s->current_picture_ptr->f->interlaced_frame = !s->progressive_frame &&
- !s->progressive_sequence;
+ s->current_picture_ptr->f->flags |= AV_FRAME_FLAG_INTERLACED * (!s->progressive_frame &&
+ !s->progressive_sequence);
s->current_picture_ptr->field_picture = s->picture_structure != PICT_FRAME;
s->current_picture_ptr->f->pict_type = s->pict_type;
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 50a4fa6f69..b2f6253a43 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -2634,7 +2634,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
pic_params.outputBitstream = in_surf->output_surface;
if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
- if (frame->top_field_first)
+ if (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)
pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;
else
pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 8fbb71f60f..03b3efdabc 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -841,7 +841,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
p->pict_type = AV_PICTURE_TYPE_I;
p->key_frame = 1;
- p->interlaced_frame = !!s->interlace_type;
+ p->flags |= AV_FRAME_FLAG_INTERLACED * !!s->interlace_type;
if ((ret = populate_avctx_color_fields(avctx, p)) < 0)
return ret;
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index c821a07849..e9d219000a 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -252,8 +252,8 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
ctx->scan = ctx->progressive_scan; // permuted
} else {
ctx->scan = ctx->interlaced_scan; // permuted
- ctx->frame->interlaced_frame = 1;
- ctx->frame->top_field_first = ctx->frame_type == 1;
+ ctx->frame->flags |= AV_FRAME_FLAG_INTERLACED;
+ ctx->frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * (ctx->frame_type == 1);
}
if (ctx->alpha_info) {
@@ -706,7 +706,7 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
- if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) {
+ if (ctx->frame_type && ctx->first_field ^ !!(ctx->frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)) {
dest_y += pic->linesize[0];
dest_u += pic->linesize[1];
dest_v += pic->linesize[2];
diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c
index 09196c7aa1..fc48c97d5b 100644
--- a/libavcodec/proresenc_anatoliy.c
+++ b/libavcodec/proresenc_anatoliy.c
@@ -746,7 +746,8 @@ static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
if (avctx->profile >= FF_PROFILE_PRORES_4444) /* 4444 or 4444 Xq */
frame_flags |= 0x40; /* 444 chroma */
if (ctx->is_interlaced) {
- if (pict->top_field_first || !pict->interlaced_frame) { /* tff frame or progressive frame interpret as tff */
+ if ((pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) || !(pict->flags & AV_FRAME_FLAG_INTERLACED)) {
+ /* tff frame or progressive frame interpret as tff */
av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, top field first\n");
frame_flags |= 0x04; /* interlaced tff */
is_top_field_first = 1;
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 1940e0378a..77ab524046 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -585,7 +585,7 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
if (ctx->pictures_per_frame == 1)
line_add = 0;
else
- line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
+ line_add = ctx->cur_picture_idx ^ !(pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
if (ctx->force_quant) {
qmat = ctx->quants[0];
@@ -838,7 +838,7 @@ static int find_slice_quant(AVCodecContext *avctx,
if (ctx->pictures_per_frame == 1)
line_add = 0;
else
- line_add = ctx->cur_picture_idx ^ !ctx->pic->top_field_first;
+ line_add = ctx->cur_picture_idx ^ !(ctx->pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
mbs = x + mbs_per_slice;
for (i = 0; i < ctx->num_planes; i++) {
@@ -1045,7 +1045,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
frame_flags = ctx->chroma_factor << 6;
if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
- frame_flags |= pic->top_field_first ? 0x04 : 0x08;
+ frame_flags |= (pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x04 : 0x08;
bytestream_put_byte (&buf, frame_flags);
bytestream_put_byte (&buf, 0); // reserved
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 6bc85116ad..e137a38e3c 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -828,9 +828,9 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
- frame->top_field_first =
- outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
- frame->interlaced_frame =
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST *
+ !!(outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF);
+ frame->flags |= AV_FRAME_FLAG_INTERLACED *
!(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
frame->pict_type = ff_qsv_map_pictype(aframe.frame->dec_info.FrameType);
//Key frame is IDR frame is only suitable for H264. For HEVC, IRAPs are key frames.
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index c975302b4f..0ed1f757d4 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1947,8 +1947,8 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame,
qf->surface.Info = q->param.mfx.FrameInfo;
qf->surface.Info.PicStruct =
- !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
- frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF :
+ !(frame->flags & AV_FRAME_FLAG_INTERLACED) ? MFX_PICSTRUCT_PROGRESSIVE :
+ (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? MFX_PICSTRUCT_FIELD_TFF :
MFX_PICSTRUCT_FIELD_BFF;
if (frame->repeat_pict == 1)
qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
@@ -2402,7 +2402,7 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
goto free;
}
- if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame && frame->interlaced_frame)
+ if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame && (frame->flags & AV_FRAME_FLAG_INTERLACED))
print_interlace_msg(avctx, q);
ret = 0;
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index c20c317fed..5aa1030640 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -234,8 +234,8 @@ static int raw_decode(AVCodecContext *avctx, AVFrame *frame,
return res;
if (context->tff >= 0) {
- frame->interlaced_frame = 1;
- frame->top_field_first = context->tff;
+ frame->flags |= AV_FRAME_FLAG_INTERLACED;
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!context->tff;
}
if ((res = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
@@ -459,9 +459,9 @@ static int raw_decode(AVCodecContext *avctx, AVFrame *frame,
}
if (avctx->field_order > AV_FIELD_PROGRESSIVE) { /* we have interlaced material flagged in container */
- frame->interlaced_frame = 1;
+ frame->flags |= AV_FRAME_FLAG_INTERLACED;
if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)
- frame->top_field_first = 1;
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
}
*got_frame = 1;
diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index 8bf7c6ed16..5768568b00 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -404,8 +404,10 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
frame->colorspace = mpp_frame_get_colorspace(mppframe);
mode = mpp_frame_get_mode(mppframe);
- frame->interlaced_frame = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_DEINTERLACED);
- frame->top_field_first = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST);
+ if ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_DEINTERLACED)
+ frame->flags |= AV_FRAME_FLAG_INTERLACED;
+ if ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST)
+ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
mppformat = mpp_frame_get_fmt(mppframe);
drmformat = rkmpp_get_frameformat(mppformat);
diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index 83120d1b22..52d6e76479 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -871,7 +871,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
frame->key_frame = 1;
frame->pict_type = AV_PICTURE_TYPE_I;
- frame->interlaced_frame = !!c->interlaced;
+ frame->flags |= AV_FRAME_FLAG_INTERLACED * !!c->interlaced;
*got_frame = 1;
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index 43b92f6ec9..26c9841d83 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -207,9 +207,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *pic,
if (avctx->field_order > AV_FIELD_PROGRESSIVE) {
/* we have interlaced material flagged in container */
- pic->interlaced_frame = 1;
+ pic->flags |= AV_FRAME_FLAG_INTERLACED;
if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)
- pic->top_field_first = 1;
+ pic->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
}
*got_frame = 1;
diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index 984af75c84..cd3ca42971 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -60,10 +60,10 @@ static void fill_vaapi_pic(VAPictureHEVC *va_pic, const HEVCFrame *pic, int rps_
if (pic->flags & HEVC_FRAME_FLAG_LONG_REF)
va_pic->flags |= VA_PICTURE_HEVC_LONG_TERM_REFERENCE;
- if (pic->frame->interlaced_frame) {
+ if (pic->frame->flags & AV_FRAME_FLAG_INTERLACED) {
va_pic->flags |= VA_PICTURE_HEVC_FIELD_PIC;
- if (!pic->frame->top_field_first)
+ if (!(pic->frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST))
va_pic->flags |= VA_PICTURE_HEVC_BOTTOM_FIELD;
}
}
diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c
index 1b8d8799b3..8f0b3f6fab 100644
--- a/libavcodec/vc1_mc.c
+++ b/libavcodec/vc1_mc.c
@@ -233,7 +233,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir)
luty = v->last_luty;
lutuv = v->last_lutuv;
use_ic = v->last_use_ic;
- interlace = s->last_picture.f->interlaced_frame;
+ interlace = !!(s->last_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
}
} else {
srcY = s->next_picture.f->data[0];
@@ -242,7 +242,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir)
luty = v->next_luty;
lutuv = v->next_lutuv;
use_ic = v->next_use_ic;
- interlace = s->next_picture.f->interlaced_frame;
+ interlace = !!(s->next_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
}
if (!srcY || !srcU) {
@@ -482,13 +482,13 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
srcY = s->last_picture.f->data[0];
luty = v->last_luty;
use_ic = v->last_use_ic;
- interlace = s->last_picture.f->interlaced_frame;
+ interlace = !!(s->last_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
}
} else {
srcY = s->next_picture.f->data[0];
luty = v->next_luty;
use_ic = v->next_use_ic;
- interlace = s->next_picture.f->interlaced_frame;
+ interlace = !!(s->next_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
}
if (!srcY) {
@@ -708,14 +708,14 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir)
srcV = s->last_picture.f->data[2];
lutuv = v->last_lutuv;
use_ic = v->last_use_ic;
- interlace = s->last_picture.f->interlaced_frame;
+ interlace = !!(s->last_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
}
} else {
srcU = s->next_picture.f->data[1];
srcV = s->next_picture.f->data[2];
lutuv = v->next_lutuv;
use_ic = v->next_use_ic;
- interlace = s->next_picture.f->interlaced_frame;
+ interlace = !!(s->next_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
}
if (!srcU) {
@@ -884,13 +884,13 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
srcV = s->next_picture.f->data[2];
lutuv = v->next_lutuv;
use_ic = v->next_use_ic;
- interlace = s->next_picture.f->interlaced_frame;
+ interlace = !!(s->next_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
} else {
srcU = s->last_picture.f->data[1];
srcV = s->last_picture.f->data[2];
lutuv = v->last_lutuv;
use_ic = v->last_use_ic;
- interlace = s->last_picture.f->interlaced_frame;
+ interlace = !!(s->last_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
}
if (!srcU)
return;
@@ -1034,7 +1034,7 @@ void ff_vc1_interp_mc(VC1Context *v)
srcU = s->next_picture.f->data[1];
srcV = s->next_picture.f->data[2];
- interlace = s->next_picture.f->interlaced_frame;
+ interlace = !!(s->next_picture.f->flags & AV_FRAME_FLAG_INTERLACED);
src_x = s->mb_x * 16 + (mx >> 2);
src_y = s->mb_y * 16 + (my >> 2);
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 18fb616fff..a103a73445 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -1078,8 +1078,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict,
}
v->s.current_picture_ptr->field_picture = v->field_mode;
- v->s.current_picture_ptr->f->interlaced_frame = (v->fcm != PROGRESSIVE);
- v->s.current_picture_ptr->f->top_field_first = v->tff;
+ v->s.current_picture_ptr->f->flags |= AV_FRAME_FLAG_INTERLACED * (v->fcm != PROGRESSIVE);
+ v->s.current_picture_ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!v->tff;
// process pulldown flags
s->current_picture_ptr->f->repeat_pict = 0;
--
2.40.0
More information about the ffmpeg-devel
mailing list