[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