[vlc-devel] [PATCH 4/7] modules: set the interlaced flag in the video format

Steve Lhomme robux4 at ycbcr.xyz
Fri Nov 6 15:42:11 CET 2020


Deinterlacing filters always output a progressive format.
---
 modules/codec/aom.c                       |  1 +
 modules/codec/avcodec/video.c             | 23 ++++++++++++++++++
 modules/codec/dav1d.c                     |  1 +
 modules/codec/libmpeg2.c                  |  4 ++++
 modules/codec/omxil/mediacodec.c          |  2 ++
 modules/codec/rawvideo.c                  |  2 ++
 modules/codec/schroedinger.c              |  3 +++
 modules/codec/theora.c                    |  2 ++
 modules/codec/videotoolbox.c              |  2 ++
 modules/codec/vpx.c                       |  1 +
 modules/codec/xwd.c                       |  1 +
 modules/hw/mmal/codec.c                   | 15 ++++++++++--
 modules/hw/mmal/deinterlace.c             |  2 ++
 modules/hw/nvdec/nvdec.c                  | 29 ++++++++++++++++-------
 modules/hw/vaapi/filters.c                |  2 ++
 modules/hw/vdpau/deinterlace.c            |  1 +
 modules/video_filter/deinterlace/common.c |  1 +
 17 files changed, 82 insertions(+), 10 deletions(-)

diff --git a/modules/codec/aom.c b/modules/codec/aom.c
index 20ec11c75c9..2a87347dbbe 100644
--- a/modules/codec/aom.c
+++ b/modules/codec/aom.c
@@ -242,6 +242,7 @@ static void OutputFrame(decoder_t *dec, const struct aom_image *img)
     dec->fmt_out.video.projection_mode = dec->fmt_in.video.projection_mode;
     dec->fmt_out.video.multiview_mode = dec->fmt_in.video.multiview_mode;
     dec->fmt_out.video.pose = dec->fmt_in.video.pose;
+    dec->fmt_out.video.interlaced = false; /* codec does not support interlacing */
 
     if (decoder_UpdateVideoFormat(dec) == 0)
     {
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 13b00e3f26d..78e05917640 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -233,6 +233,23 @@ static int lavc_GetVideoFormat(decoder_t *dec, video_format_t *restrict fmt,
     }
 
     get_video_color_settings(ctx, fmt);
+    switch (ctx->field_order)
+    {
+        case AV_FIELD_PROGRESSIVE:
+            fmt->interlaced = false;
+            break;
+        case AV_FIELD_TT:
+        case AV_FIELD_BB:
+        case AV_FIELD_TB:
+        case AV_FIELD_BT:
+            fmt->interlaced = true;
+            break;
+        default:
+            // reuse previous value
+            fmt->interlaced = dec->fmt_out.video.interlaced;
+            break;
+    }
+
     return 0;
 }
 
@@ -737,6 +754,12 @@ static int DecodeSidedata( decoder_t *p_dec, const AVFrame *frame, picture_t *p_
     decoder_sys_t *p_sys = p_dec->p_sys;
     bool format_changed = false;
 
+    if (p_dec->fmt_out.video.interlaced != frame->interlaced_frame)
+    {
+        p_dec->fmt_out.video.interlaced = frame->interlaced_frame;
+        format_changed = true;
+    }
+
 #if (LIBAVUTIL_VERSION_MICRO >= 100)
 #define FROM_AVRAT(default_factor, avrat) \
 (uint64_t)(default_factor) * (avrat).num / (avrat).den
diff --git a/modules/codec/dav1d.c b/modules/codec/dav1d.c
index 5d341a367fa..f5a0566bf6a 100644
--- a/modules/codec/dav1d.c
+++ b/modules/codec/dav1d.c
@@ -182,6 +182,7 @@ static int NewPicture(Dav1dPicture *img, void *cookie)
         v->lighting.MaxFALL = cll->max_frame_average_light_level;
     }
 
+    v->interlaced = false; // codec does not support interlacing
     v->projection_mode = dec->fmt_in.video.projection_mode;
     v->multiview_mode = dec->fmt_in.video.multiview_mode;
     v->pose = dec->fmt_in.video.pose;
diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c
index 9896f40ee65..6ea02981728 100644
--- a/modules/codec/libmpeg2.c
+++ b/modules/codec/libmpeg2.c
@@ -681,6 +681,10 @@ static picture_t *GetNewPicture( decoder_t *p_dec )
           p_sys->p_info->sequence->height ) ?
         VLC_CODEC_I420 : VLC_CODEC_I422;
 
+    p_dec->fmt_out.video.interlaced =
+        !p_sys->p_info->sequence->flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE ||
+        ( p_sys->p_info->current_picture && !( p_sys->p_info->current_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME ) );
+
     /* Get a new picture */
     if( decoder_UpdateVideoFormat( p_dec ) )
         return NULL;
diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c
index 041faa9a46e..e6758dbc320 100644
--- a/modules/codec/omxil/mediacodec.c
+++ b/modules/codec/omxil/mediacodec.c
@@ -1198,6 +1198,8 @@ static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out,
                 p_sys->video.i_mpeg_dar_den * p_dec->fmt_out.video.i_width;
         }
 
+        p_dec->fmt_out.video.interlaced = false;
+
         /* If MediaCodec can handle the rotation, reset the orientation to
          * Normal in order to ask the vout not to rotate. */
         if (p_sys->video.i_angle != 0)
diff --git a/modules/codec/rawvideo.c b/modules/codec/rawvideo.c
index 43f864ad29c..b569d35367c 100644
--- a/modules/codec/rawvideo.c
+++ b/modules/codec/rawvideo.c
@@ -241,6 +241,8 @@ static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
 
     decoder_sys_t *p_sys = p_dec->p_sys;
 
+    p_dec->fmt_out.video.interlaced = p_block->i_flags & BLOCK_FLAG_INTERLACED_MASK;
+
     /* Get a new picture */
     picture_t *p_pic = NULL;
     if( !decoder_UpdateVideoFormat( p_dec ) )
diff --git a/modules/codec/schroedinger.c b/modules/codec/schroedinger.c
index 20c708948b8..23fca47d7f9 100644
--- a/modules/codec/schroedinger.c
+++ b/modules/codec/schroedinger.c
@@ -634,6 +634,8 @@ static void SetVideoFormat( decoder_t *p_dec )
         p_sys->p_format->frame_rate_numerator;
     p_dec->fmt_out.video.i_frame_rate_base =
         p_sys->p_format->frame_rate_denominator;
+
+    p_dec->fmt_out.video.interlaced = p_sys->p_format->interlaced;
 }
 
 /*****************************************************************************
@@ -1152,6 +1154,7 @@ static int OpenEncoder( vlc_object_t *p_this )
     p_sys->p_format->height                 = p_enc->fmt_in.video.i_visible_height;
     p_sys->p_format->frame_rate_numerator   = p_enc->fmt_in.video.i_frame_rate;
     p_sys->p_format->frame_rate_denominator = p_enc->fmt_in.video.i_frame_rate_base;
+    p_sys->p_format->interlaced             = p_enc->fmt_in.video.interlaced;
     unsigned u_asr_num, u_asr_den;
     vlc_ureduce( &u_asr_num, &u_asr_den,
                  p_enc->fmt_in.video.i_sar_num,
diff --git a/modules/codec/theora.c b/modules/codec/theora.c
index b038502fd2a..072cd350b1b 100644
--- a/modules/codec/theora.c
+++ b/modules/codec/theora.c
@@ -327,6 +327,8 @@ static int ProcessHeaders( decoder_t *p_dec )
         p_dec->fmt_out.video.i_frame_rate_base = p_sys->ti.fps_denominator;
     }
 
+    p_dec->fmt_out.video.interlaced = false;
+
     msg_Dbg( p_dec, "%dx%d %u/%u fps video, frame content "
              "is %dx%d with offset (%d,%d)",
              p_sys->ti.frame_width, p_sys->ti.frame_height,
diff --git a/modules/codec/videotoolbox.c b/modules/codec/videotoolbox.c
index aae548504bb..9f937b3efea 100644
--- a/modules/codec/videotoolbox.c
+++ b/modules/codec/videotoolbox.c
@@ -2163,6 +2163,8 @@ static void DecoderCallback(void *decompressionOutputRefCon,
     if (p_sys->vtsession_status == VTSESSION_STATUS_ABORT)
         goto end;
 
+    p_dec->fmt_out.video.interlaced = (p_info && !p_info->b_progressive);
+
     if (unlikely(!p_sys->b_format_propagated)) {
         p_sys->b_format_propagated =
             UpdateVideoFormat(p_dec, imageBuffer) == VLC_SUCCESS;
diff --git a/modules/codec/vpx.c b/modules/codec/vpx.c
index cb29f4428db..3d1770ba50c 100644
--- a/modules/codec/vpx.c
+++ b/modules/codec/vpx.c
@@ -263,6 +263,7 @@ static int Decode(decoder_t *dec, block_t *block)
     dec->fmt_out.video.projection_mode = dec->fmt_in.video.projection_mode;
     dec->fmt_out.video.multiview_mode = dec->fmt_in.video.multiview_mode;
     dec->fmt_out.video.pose = dec->fmt_in.video.pose;
+    dec->fmt_out.video.interlaced = false; /* codec does not support interlacing */
 
     if (decoder_UpdateVideoFormat(dec))
         return VLCDEC_SUCCESS;
diff --git a/modules/codec/xwd.c b/modules/codec/xwd.c
index f75c1d513b2..813b3e2c4fe 100644
--- a/modules/codec/xwd.c
+++ b/modules/codec/xwd.c
@@ -95,6 +95,7 @@ static int Decode (decoder_t *dec, block_t *block)
                        ntohl(hdr->pixmap_width), ntohl(hdr->pixmap_height),
                        dec->fmt_in.video.i_sar_num,
                        dec->fmt_in.video.i_sar_den);
+    dec->fmt_out.video.interlaced = false;
 
     const size_t copy = dec->fmt_out.video.i_width
                         * (dec->fmt_out.video.i_bits_per_pixel / 8);
diff --git a/modules/hw/mmal/codec.c b/modules/hw/mmal/codec.c
index e3bdeffc16b..387870198cb 100644
--- a/modules/hw/mmal/codec.c
+++ b/modules/hw/mmal/codec.c
@@ -68,7 +68,6 @@ typedef struct
     MMAL_ES_FORMAT_T *output_format;
 
     MMAL_STATUS_T err_stream;
-    bool b_progressive;
 
     bool b_flushed;
 
@@ -363,7 +362,19 @@ apply_fmt:
         msg_Warn(dec, "Failed to query interlace type from decoder output port (status=%"PRIx32" %s)",
                 status, mmal_status_to_string(status));
     } else {
-        sys->b_progressive = (interlace_type.eMode == MMAL_InterlaceProgressive);
+        switch (interlace_type.eMode)
+        {
+            case MMAL_InterlaceProgressive:
+                dec->fmt_out.video.interlaced = false;
+                break;
+            case MMAL_InterlaceFieldSingleUpperFirst:
+            case MMAL_InterlaceFieldSingleLowerFirst:
+                dec->fmt_out.video.interlaced = true;
+                break;
+            default:
+                dec->fmt_out.video.interlaced = true;
+                break;
+        }
     }
 
     // Tell the rest of the world we have changed format
diff --git a/modules/hw/mmal/deinterlace.c b/modules/hw/mmal/deinterlace.c
index 70814303bb6..d6b1ee420fb 100644
--- a/modules/hw/mmal/deinterlace.c
+++ b/modules/hw/mmal/deinterlace.c
@@ -536,6 +536,8 @@ static int OpenMmalDeinterlace(filter_t *filter)
         }
     }
 
+    filter->fmt_out.video.interlaced = false;
+
     sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)filter;
     status = mmal_port_enable(sys->component->control, control_port_cb);
     if (status != MMAL_SUCCESS) {
diff --git a/modules/hw/nvdec/nvdec.c b/modules/hw/nvdec/nvdec.c
index f16702f89ae..a0bcd8f5588 100644
--- a/modules/hw/nvdec/nvdec.c
+++ b/modules/hw/nvdec/nvdec.c
@@ -377,6 +377,10 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)
 
     CALL_CUDA_DEC(cuCtxPopCurrent, NULL);
 
+    if ( p_sys->deintMode == cudaVideoDeinterlaceMode_Weave )
+        // the picture has not been deinterlaced, forward the field parameters
+        p_dec->fmt_out.video.interlaced = !p_format->progressive_sequence;
+
     ret = decoder_UpdateVideoOutput(p_dec, p_sys->vctx_out);
     return (ret == VLC_SUCCESS);
 
@@ -975,6 +979,23 @@ static int OpenDecoder(vlc_object_t *p_this)
         goto error;
     }
 
+    int deinterlace_mode    = var_InheritInteger(p_dec, "nvdec-deint");
+    if (deinterlace_mode <= 0)
+    {
+        p_sys->deintMode = cudaVideoDeinterlaceMode_Weave;
+        p_dec->fmt_out.video.interlaced = p_dec->fmt_in.video.interlaced;
+    }
+    else if (deinterlace_mode == 1)
+    {
+        p_sys->deintMode = cudaVideoDeinterlaceMode_Bob;
+        p_dec->fmt_out.video.interlaced = false;
+    }
+    else
+    {
+        p_sys->deintMode = cudaVideoDeinterlaceMode_Adaptive;
+        p_dec->fmt_out.video.interlaced = false;
+    }
+
     vlc_fourcc_t output_chromas[3];
     size_t chroma_idx = 0;
     output_chromas[chroma_idx++] = MapSurfaceOpaqueChroma(cudaChroma, i_depth_luma);
@@ -995,14 +1016,6 @@ static int OpenDecoder(vlc_object_t *p_this)
     if (result != VLC_SUCCESS)
         goto error;
 
-    int deinterlace_mode    = var_InheritInteger(p_dec, "nvdec-deint");
-    if (deinterlace_mode <= 0)
-        p_sys->deintMode = cudaVideoDeinterlaceMode_Weave;
-    else if (deinterlace_mode == 1)
-        p_sys->deintMode = cudaVideoDeinterlaceMode_Bob;
-    else
-        p_sys->deintMode = cudaVideoDeinterlaceMode_Adaptive;
-
     p_dec->pf_decode = DecodeBlock;
 
     p_sys->b_nvparser_success = true;
diff --git a/modules/hw/vaapi/filters.c b/modules/hw/vaapi/filters.c
index 9174e21cd4d..fa800399f02 100644
--- a/modules/hw/vaapi/filters.c
+++ b/modules/hw/vaapi/filters.c
@@ -317,6 +317,8 @@ Open(filter_t * filter,
     filter_sys->va.dpy = filter_sys->va.dec_device->opaque;
     assert(filter_sys->va.dec_device);
 
+    filter->fmt_out.video.interlaced = false;
+
     filter_sys->dest_pics =
         vlc_vaapi_PoolNew(VLC_OBJECT(filter), filter->vctx_in,
                           filter_sys->va.dpy, DEST_PICS_POOL_SZ,
diff --git a/modules/hw/vdpau/deinterlace.c b/modules/hw/vdpau/deinterlace.c
index 842110c87aa..510892cba04 100644
--- a/modules/hw/vdpau/deinterlace.c
+++ b/modules/hw/vdpau/deinterlace.c
@@ -136,6 +136,7 @@ static int Open(filter_t *filter)
     filter->ops = &filter_ops;
     filter->p_sys = sys;
     filter->fmt_out.video.i_frame_rate *= 2;
+    filter->fmt_out.video.interlaced = false;
     filter->vctx_out = vlc_video_context_Hold(filter->vctx_in);
     return VLC_SUCCESS;
 }
diff --git a/modules/video_filter/deinterlace/common.c b/modules/video_filter/deinterlace/common.c
index 94a6280e37e..a1bab1f1c50 100644
--- a/modules/video_filter/deinterlace/common.c
+++ b/modules/video_filter/deinterlace/common.c
@@ -120,6 +120,7 @@ void GetDeinterlacingOutput( const struct deinterlace_ctx *p_context,
     {
         p_dst->i_frame_rate *= 2;
     }
+    p_dst->interlaced = false;
 }
 
 #define CUSTOM_PTS -1
-- 
2.26.2



More information about the vlc-devel mailing list