[FFmpeg-devel] [PATCH v2] mpeg2_metadata: support inverse (soft) telecine
Tom Yan
tom.ty89 at gmail.com
Thu Dec 31 02:34:12 EET 2020
Signed-off-by: Tom Yan <tom.ty89 at gmail.com>
---
doc/bitstream_filters.texi | 6 ++++++
libavcodec/mpeg2_metadata_bsf.c | 27 +++++++++++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index 8a2f55cc41..7e178a6912 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -499,6 +499,12 @@ table 6-6).
Set the colour description in the stream (see H.262 section 6.3.6
and tables 6-7, 6-8 and 6-9).
+ at item ivtc
+Inverse (soft) telecine, i.e. mark the sequences as progressive
+and clear the repeat_first_field and top_field_first bits in
+the Picture Coding Extension Data. Works only with sequences
+that are entirely progressive in nature.
+
@end table
@section mpeg4_unpack_bframes
diff --git a/libavcodec/mpeg2_metadata_bsf.c b/libavcodec/mpeg2_metadata_bsf.c
index d0048c0e25..8f89ef4f88 100644
--- a/libavcodec/mpeg2_metadata_bsf.c
+++ b/libavcodec/mpeg2_metadata_bsf.c
@@ -43,6 +43,8 @@ typedef struct MPEG2MetadataContext {
int transfer_characteristics;
int matrix_coefficients;
+ int ivtc;
+
int mpeg1_warned;
} MPEG2MetadataContext;
@@ -55,6 +57,7 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
MPEG2RawSequenceExtension *se = NULL;
MPEG2RawSequenceDisplayExtension *sde = NULL;
int i, se_pos;
+ int last_code = -1;
for (i = 0; i < frag->nb_units; i++) {
if (frag->units[i].type == MPEG2_START_SEQUENCE_HEADER) {
@@ -68,8 +71,25 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
} else if (ext->extension_start_code_identifier ==
MPEG2_EXTENSION_SEQUENCE_DISPLAY) {
sde = &ext->data.sequence_display;
+ } else if (ext->extension_start_code_identifier ==
+ MPEG2_EXTENSION_PICTURE_CODING && last_code ==
+ MPEG2_START_PICTURE) {
+ if (ctx->ivtc) {
+ MPEG2RawPictureCodingExtension *pce = &ext->data.picture_coding;
+ pce->repeat_first_field = 0;
+ pce->top_field_first = 0;
+ if (!pce->frame_pred_frame_dct) {
+ av_log(bsf, AV_LOG_ERROR, "invalid frame_pred_frame_dct\n");
+ return -1;
+ }
+ if (!pce->progressive_frame) {
+ av_log(bsf, AV_LOG_ERROR, "interlaced frame found\n");
+ return -1;
+ }
+ }
}
}
+ last_code = frag->units[i].type;
}
if (!sh || !se) {
@@ -167,6 +187,9 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
}
}
+ if (ctx->ivtc)
+ se->progressive_sequence = 1;
+
return 0;
}
@@ -288,6 +311,10 @@ static const AVOption mpeg2_metadata_options[] = {
OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
{ .i64 = -1 }, -1, 255, FLAGS },
+ { "ivtc", "Inverse (soft) Telecine",
+ OFFSET(ivtc), AV_OPT_TYPE_BOOL,
+ { .i64 = 0 }, 0, 1, FLAGS },
+
{ NULL }
};
--
2.30.0
More information about the ffmpeg-devel
mailing list