[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