[FFmpeg-devel] [PATCH] mpeg2_metadata: support inverse (soft) telecine

Tom Yan tom.ty89 at gmail.com
Wed Dec 30 05:49:52 EET 2020


Signed-off-by: Tom Yan <tom.ty89 at gmail.com>
---
 doc/bitstream_filters.texi      |  5 +++++
 libavcodec/mpeg2_metadata_bsf.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index 8a2f55cc41..7831abc120 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -499,6 +499,11 @@ 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.
+
 @end table
 
 @section mpeg4_unpack_bframes
diff --git a/libavcodec/mpeg2_metadata_bsf.c b/libavcodec/mpeg2_metadata_bsf.c
index d0048c0e25..735680a28b 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;
 
@@ -54,7 +56,10 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
     MPEG2RawSequenceHeader            *sh = NULL;
     MPEG2RawSequenceExtension         *se = NULL;
     MPEG2RawSequenceDisplayExtension *sde = NULL;
+    MPEG2RawPictureCodingExtension   *pce = NULL;
     int i, se_pos;
+    int last_code = -1;
+    int prog_seq = 1;
 
     for (i = 0; i < frag->nb_units; i++) {
         if (frag->units[i].type == MPEG2_START_SEQUENCE_HEADER) {
@@ -68,8 +73,26 @@ 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) {
+                pce = &ext->data.picture_coding;
+                if (ctx->ivtc) {
+                    pce->repeat_first_field = 0;
+                    pce->top_field_first = 0;
+                    if (!pce->frame_pred_frame_dct) {
+                        if (pce->progressive_frame) {
+                            pce->frame_pred_frame_dct = 1;
+                        } else if (prog_seq) {
+                            av_log(bsf, AV_LOG_ERROR, "applying ivtc "
+                                   "to non-progressive sequence\n");
+                            prog_seq = 0;
+                        }
+                    }
+                }
             }
         }
+        last_code = frag->units[i].type;
     }
 
     if (!sh || !se) {
@@ -167,6 +190,9 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
         }
     }
 
+    if (ctx->ivtc)
+        se->progressive_sequence = 1;
+
     return 0;
 }
 
@@ -288,6 +314,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.29.2



More information about the ffmpeg-devel mailing list