From 324cf040219977a3ed688272c1e5b984305b406e Mon Sep 17 00:00:00 2001 From: Arnaud de Turckheim Date: Tue, 30 Dec 2025 11:37:28 +0100 Subject: [PATCH] Make progressive and tff attribute a boolean Change uref_pic_progressive and uref_pic_tff attributes from void to boolean. With void attribute, there is no possibility to explicitly set interlaced or bottom field first on a flow definition packet. --- doc/tutorials.mkdoc | 4 +-- examples/extract_pic.c | 4 +-- include/upipe/uref_attr.h | 22 +++++++++++++ include/upipe/uref_pic.h | 5 +-- lib/upipe-av/upipe_av.c | 8 ++--- lib/upipe-av/upipe_avcodec_decode.c | 11 +++---- lib/upipe-av/upipe_avcodec_encode.c | 4 +-- lib/upipe-av/upipe_avfilter.c | 18 +++++----- .../upipe_blackmagic_sink.cpp | 2 +- .../upipe_blackmagic_source.cpp | 17 +++++----- lib/upipe-filters/upipe_audio_bar.c | 2 +- lib/upipe-filters/upipe_audio_graph.c | 4 +-- lib/upipe-filters/upipe_filter_blend.c | 4 +-- lib/upipe-filters/upipe_filter_format.c | 4 +-- lib/upipe-framers/upipe_h264_framer.c | 21 ++++++++---- lib/upipe-framers/upipe_h265_framer.c | 17 +++++++--- lib/upipe-framers/upipe_mpgv_framer.c | 11 +++---- lib/upipe-gl/upipe_glx_sink.c | 2 +- lib/upipe-modules/upipe_rtp_anc_unpack.c | 2 +- lib/upipe-modules/upipe_separate_fields.c | 6 ++-- lib/upipe-modules/upipe_video_blank.c | 6 ++-- lib/upipe-modules/upipe_videocont.c | 33 +++---------------- lib/upipe-swscale/upipe_sws.c | 2 +- lib/upipe-x264/upipe_x264.c | 10 +++--- lib/upipe-x265/upipe_x265.c | 2 +- lib/upipe/udict_inline.c | 5 +-- tests/upipe_blank_source_test.c | 2 +- tests/upipe_blit_test.c | 6 ++-- tests/upipe_separate_fields_test.c | 2 +- tests/upipe_sws_test.c | 4 +-- tests/upipe_x265_test.c | 2 +- 31 files changed, 125 insertions(+), 117 deletions(-) diff --git a/doc/tutorials.mkdoc b/doc/tutorials.mkdoc index f26b1b96e..ea9fd9a4c 100644 --- a/doc/tutorials.mkdoc +++ b/doc/tutorials.mkdoc @@ -154,13 +154,13 @@ static int avcdec_catch(struct uprobe *uprobe, struct upipe *upipe, return UBASE_ERR_UNHANDLED; } wanted_hsize = (hsize * sar.num / sar.den / 2) * 2; - progressive = ubase_check(uref_pic_get_progressive(flow_def)); + progressive = uref_pic_check_progressive(flow_def); struct uref *flow_def2 = uref_dup(flow_def); upipe_use(upipe); if (!progressive) { - uref_pic_set_progressive(flow_def2); + uref_pic_set_progressive(flow_def2, true); struct upipe *deint = upipe_void_alloc_output(upipe, upipe_filter_blend_mgr, uprobe_pfx_alloc(uprobe_use(logger), diff --git a/examples/extract_pic.c b/examples/extract_pic.c index 8eb35d559..412053b8f 100644 --- a/examples/extract_pic.c +++ b/examples/extract_pic.c @@ -153,7 +153,7 @@ static int avcdec_catch(struct uprobe *uprobe, struct upipe *upipe, return UBASE_ERR_UNHANDLED; } wanted_hsize = (hsize * sar.num / sar.den / 2) * 2; - progressive = ubase_check(uref_pic_get_progressive(flow_def)); + progressive = uref_pic_check_progressive(flow_def); /* supported format of the jpeg encoder */ const struct uref_pic_flow_format *supported_formats[] = { @@ -173,7 +173,7 @@ static int avcdec_catch(struct uprobe *uprobe, struct upipe *upipe, struct uref *flow_def2 = uref_dup(flow_def); upipe_use(upipe); - uref_pic_set_progressive(flow_def2); + uref_pic_set_progressive(flow_def2, true); uref_pic_flow_set_hsize(flow_def2, wanted_hsize); if (!supported) uref_pic_flow_set_format(flow_def2, diff --git a/include/upipe/uref_attr.h b/include/upipe/uref_attr.h index 505aaff23..a32d2aaaf 100644 --- a/include/upipe/uref_attr.h +++ b/include/upipe/uref_attr.h @@ -1017,6 +1017,17 @@ static inline int uref_##group##_get_##attr(struct uref *uref, bool *p) \ { \ return uref_attr_get_bool(uref, p, UDICT_TYPE_BOOL, name); \ } \ +/** @This checks if the desc attribute of a uref is set and true. \ + * \ + * @param uref pointer to the uref \ + * @return true is the attribute is set and true \ + */ \ +static inline bool uref_##group##_check_##attr(struct uref *uref) \ +{ \ + bool v = false; \ + int ret = uref_##group##_get_##attr(uref, &v); \ + return ubase_check(ret) && v == true; \ +} \ /** @This sets the desc attribute of a uref. \ * \ * @param uref pointer to the uref \ @@ -1084,6 +1095,17 @@ static inline int uref_##group##_get_##attr(struct uref *uref, bool *p) \ { \ return uref_attr_get_bool(uref, p, type, NULL); \ } \ +/** @This checks if the desc attribute of a uref is set and true. \ + * \ + * @param uref pointer to the uref \ + * @return true is the attribute is set and true \ + */ \ +static inline bool uref_##group##_check_##attr(struct uref *uref) \ +{ \ + bool v = false; \ + int ret = uref_##group##_get_##attr(uref, &v); \ + return ubase_check(ret) && v == true; \ +} \ /** @This sets the desc attribute of a uref. \ * \ * @param uref pointer to the uref \ diff --git a/include/upipe/uref_pic.h b/include/upipe/uref_pic.h index b7129d24e..29d40d239 100644 --- a/include/upipe/uref_pic.h +++ b/include/upipe/uref_pic.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2012-2016 OpenHeadend S.A.R.L. + * Copyright (C) 2026 EasyTools * * Authors: Christophe Massiot * @@ -34,10 +35,10 @@ UREF_ATTR_UNSIGNED_SH(pic, lpadding, UDICT_TYPE_PIC_LPADDING, left padding) UREF_ATTR_UNSIGNED_SH(pic, rpadding, UDICT_TYPE_PIC_RPADDING, right padding) UREF_ATTR_UNSIGNED_SH(pic, tpadding, UDICT_TYPE_PIC_TPADDING, top padding) UREF_ATTR_UNSIGNED_SH(pic, bpadding, UDICT_TYPE_PIC_BPADDING, bottom padding) -UREF_ATTR_VOID_SH(pic, progressive, UDICT_TYPE_PIC_PROGRESSIVE, progressive) +UREF_ATTR_BOOL_SH(pic, progressive, UDICT_TYPE_PIC_PROGRESSIVE, progressive) UREF_ATTR_VOID_SH(pic, tf, UDICT_TYPE_PIC_TF, top field present) UREF_ATTR_VOID_SH(pic, bf, UDICT_TYPE_PIC_BF, bottom field present) -UREF_ATTR_VOID_SH(pic, tff, UDICT_TYPE_PIC_TFF, top field first) +UREF_ATTR_BOOL_SH(pic, tff, UDICT_TYPE_PIC_TFF, top field first) UREF_ATTR_SMALL_UNSIGNED_SH(pic, afd, UDICT_TYPE_PIC_AFD, active format description) UREF_ATTR_OPAQUE_SH(pic, cea_708, UDICT_TYPE_PIC_CEA_708, cea-708 captions) UREF_ATTR_OPAQUE_SH(pic, bar_data, UDICT_TYPE_PIC_BAR_DATA, afd bar data) diff --git a/lib/upipe-av/upipe_av.c b/lib/upipe-av/upipe_av.c index 3fa17ab36..a03bf2019 100644 --- a/lib/upipe-av/upipe_av.c +++ b/lib/upipe-av/upipe_av.c @@ -122,18 +122,18 @@ int upipe_av_set_frame_properties(struct upipe *upipe, { #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(58, 7, 100) frame->key_frame = ubase_check(uref_pic_get_key(uref)); - frame->interlaced_frame = !ubase_check(uref_pic_get_progressive(uref)); - frame->top_field_first = ubase_check(uref_pic_get_tff(uref)); + frame->interlaced_frame = !uref_pic_check_progressive(uref); + frame->top_field_first = uref_pic_check_tff(uref); #else if (ubase_check(uref_pic_get_key(uref))) frame->flags |= AV_FRAME_FLAG_KEY; else frame->flags &= ~AV_FRAME_FLAG_KEY; - if (!ubase_check(uref_pic_get_progressive(uref))) + if (!uref_pic_check_progressive(uref)) frame->flags |= AV_FRAME_FLAG_INTERLACED; else frame->flags &= ~AV_FRAME_FLAG_INTERLACED; - if (ubase_check(uref_pic_get_tff(uref))) + if (uref_pic_check_tff(uref)) frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; else frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; diff --git a/lib/upipe-av/upipe_avcodec_decode.c b/lib/upipe-av/upipe_avcodec_decode.c index f3d0a6c9d..5fcf748dc 100644 --- a/lib/upipe-av/upipe_avcodec_decode.c +++ b/lib/upipe-av/upipe_avcodec_decode.c @@ -1110,7 +1110,7 @@ static void upipe_avcdec_output_sub(struct upipe *upipe, AVSubtitle *sub, !ubase_check(uref_pic_flow_set_bgra(flow_def_attr)) || #endif !ubase_check(uref_flow_set_def(flow_def_attr, UREF_PIC_SUB_FLOW_DEF)) || - !ubase_check(uref_pic_set_progressive(flow_def_attr)) || + !ubase_check(uref_pic_set_progressive(flow_def_attr, true)) || !ubase_check(uref_pic_flow_set_full_range(flow_def_attr)))) { uref_free(flow_def_attr); @@ -1191,7 +1191,7 @@ static void upipe_avcdec_output_sub(struct upipe *upipe, AVSubtitle *sub, return; } - uref_pic_set_progressive(uref); + uref_pic_set_progressive(uref, true); ubuf_pic_clear(ubuf, 0, 0, -1, -1, 1); uref_attach_ubuf(uref, ubuf); @@ -1351,10 +1351,9 @@ static void upipe_avcdec_output_pic(struct upipe *upipe, struct upump **upump_p) UBASE_FATAL(upipe, uref_pic_set_tf(uref)) UBASE_FATAL(upipe, uref_pic_set_bf(uref)) - if (!interlaced_frame) - UBASE_FATAL(upipe, uref_pic_set_progressive(uref)) - else if (top_field_first) - UBASE_FATAL(upipe, uref_pic_set_tff(uref)) + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, !interlaced_frame)) + if (interlaced_frame) + UBASE_FATAL(upipe, uref_pic_set_tff(uref, top_field_first)) uint64_t duration = 0; AVRational uclock_time_base = av_make_q(1, UCLOCK_FREQ); diff --git a/lib/upipe-av/upipe_avcodec_encode.c b/lib/upipe-av/upipe_avcodec_encode.c index d40d52d8c..b9b98846b 100644 --- a/lib/upipe-av/upipe_avcodec_encode.c +++ b/lib/upipe-av/upipe_avcodec_encode.c @@ -1538,10 +1538,10 @@ static int upipe_avcenc_set_flow_def(struct upipe *upipe, struct uref *flow_def) uref_pic_flow_get_matrix_coefficients_val(flow_def, &val))) context->colorspace = val; - if (!ubase_check(uref_pic_get_progressive(flow_def))) { + if (!uref_pic_check_progressive(flow_def)) { context->flags |= AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME; - if (ubase_check(uref_pic_get_tff(flow_def))) + if (uref_pic_check_tff(flow_def)) context->field_order = AV_FIELD_TT; else context->field_order = AV_FIELD_BB; diff --git a/lib/upipe-av/upipe_avfilter.c b/lib/upipe-av/upipe_avfilter.c index 200eaba4d..88eeff716 100644 --- a/lib/upipe-av/upipe_avfilter.c +++ b/lib/upipe-av/upipe_avfilter.c @@ -309,8 +309,7 @@ static int build_video_flow_def(struct uref *flow_def, bool interlaced_frame = frame->flags & AV_FRAME_FLAG_INTERLACED; #endif - if (!interlaced_frame) - UBASE_RETURN(uref_pic_set_progressive(flow_def)) + UBASE_RETURN(uref_pic_set_progressive(flow_def, !interlaced_frame)) if (color_range == AVCOL_RANGE_JPEG) UBASE_RETURN(uref_pic_flow_set_full_range(flow_def)) @@ -577,10 +576,9 @@ upipe_avfilt_sub_frame_to_uref(struct upipe *upipe, AVFrame *frame) bool top_field_first = frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST; #endif - if (!interlaced_frame) - UBASE_ERROR(upipe, uref_pic_set_progressive(uref)) - else if (top_field_first) - UBASE_ERROR(upipe, uref_pic_set_tff(uref)) + UBASE_ERROR(upipe, uref_pic_set_progressive(uref, !interlaced_frame)); + if (interlaced_frame) + UBASE_ERROR(upipe, uref_pic_set_tff(uref, top_field_first)) if (key_frame) UBASE_ERROR(upipe, uref_pic_set_key(uref)) @@ -1992,10 +1990,10 @@ static void upipe_avfilt_output_frame(struct upipe *upipe, bool top_field_first = frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST; #endif - if (!interlaced_frame) - UBASE_ERROR(upipe, uref_pic_set_progressive(uref)) - else if (top_field_first) - UBASE_ERROR(upipe, uref_pic_set_tff(uref)) + UBASE_ERROR(upipe, + uref_pic_set_progressive(uref, !interlaced_frame)) + if (interlaced_frame) + UBASE_ERROR(upipe, uref_pic_set_tff(uref, top_field_first)) if (key_frame) UBASE_ERROR(upipe, uref_pic_set_key(uref)) diff --git a/lib/upipe-blackmagic/upipe_blackmagic_sink.cpp b/lib/upipe-blackmagic/upipe_blackmagic_sink.cpp index c8758449a..5f68bc08a 100644 --- a/lib/upipe-blackmagic/upipe_blackmagic_sink.cpp +++ b/lib/upipe-blackmagic/upipe_blackmagic_sink.cpp @@ -1225,7 +1225,7 @@ uint32_t upipe_bmd_mode_from_flow_def(struct upipe *upipe, struct uref *flow_def return bmdModeUnknown; } - bool interlaced = !ubase_check(uref_pic_get_progressive(flow_def)); + bool interlaced = !uref_pic_check_progressive(flow_def); upipe_notice_va(upipe, "%" PRIu64"x%" PRIu64" %" PRId64"/%" PRIu64" interlaced %d", hsize, vsize, fps.num, fps.den, interlaced); diff --git a/lib/upipe-blackmagic/upipe_blackmagic_source.cpp b/lib/upipe-blackmagic/upipe_blackmagic_source.cpp index 42212636f..8d3d4b451 100644 --- a/lib/upipe-blackmagic/upipe_blackmagic_source.cpp +++ b/lib/upipe-blackmagic/upipe_blackmagic_source.cpp @@ -353,8 +353,8 @@ static int upipe_bmd_src_build_video(struct upipe *upipe, BMDFieldDominance field = mode->GetFieldDominance(); switch (field) { case bmdLowerFieldFirst: - uref_pic_delete_tff(flow_def); - uref_pic_delete_progressive(flow_def); + UBASE_RETURN(uref_pic_set_tff(flow_def, false)); + UBASE_RETURN(uref_pic_set_progressive(flow_def, false)); upipe_bmd_src->tff = false; upipe_bmd_src->progressive = false; break; @@ -362,15 +362,15 @@ static int upipe_bmd_src_build_video(struct upipe *upipe, case bmdUnknownFieldDominance: /* sensible defaults */ case bmdUpperFieldFirst: - UBASE_RETURN(uref_pic_set_tff(flow_def)); - uref_pic_delete_progressive(flow_def); + UBASE_RETURN(uref_pic_set_tff(flow_def, true)); + UBASE_RETURN(uref_pic_set_progressive(flow_def, false)); upipe_bmd_src->tff = true; upipe_bmd_src->progressive = false; break; case bmdProgressiveFrame: case bmdProgressiveSegmentedFrame: uref_pic_delete_tff(flow_def); - UBASE_RETURN(uref_pic_set_progressive(flow_def)); + UBASE_RETURN(uref_pic_set_progressive(flow_def, true)); upipe_bmd_src->tff = false; upipe_bmd_src->progressive = true; break; @@ -530,10 +530,9 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived( uref_clock_set_dts_pts_delay(uref, 0); uref_clock_set_duration(uref, FrameDuration); - if (upipe_bmd_src->progressive) - uref_pic_set_progressive(uref); - else if (upipe_bmd_src->tff) - uref_pic_set_tff(uref); + uref_pic_set_progressive(uref, upipe_bmd_src->progressive); + if (!upipe_bmd_src->progressive) + uref_pic_set_tff(uref, upipe_bmd_src->tff); if (!uqueue_push(&upipe_bmd_src->uqueue, uref)) uref_free(uref); diff --git a/lib/upipe-filters/upipe_audio_bar.c b/lib/upipe-filters/upipe_audio_bar.c index 1a6e28564..2a338835b 100644 --- a/lib/upipe-filters/upipe_audio_bar.c +++ b/lib/upipe-filters/upipe_audio_bar.c @@ -477,7 +477,7 @@ static int upipe_audiobar_set_flow_def(struct upipe *upipe, UBASE_FATAL(upipe, uref_pic_flow_add_plane(flow_def, 2, 1, 1, "u8")) UBASE_FATAL(upipe, uref_pic_flow_add_plane(flow_def, 2, 1, 1, "v8")) UBASE_FATAL(upipe, uref_pic_flow_add_plane(flow_def, 1, 1, 1, "a8")) - UBASE_FATAL(upipe, uref_pic_set_progressive(flow_def)) + UBASE_FATAL(upipe, uref_pic_set_progressive(flow_def, true)) uref_dump(flow_def, upipe->uprobe); upipe_audiobar->hsize = upipe_audiobar->vsize = upipe_audiobar->sep_width = upipe_audiobar->pad_width = UINT64_MAX; diff --git a/lib/upipe-filters/upipe_audio_graph.c b/lib/upipe-filters/upipe_audio_graph.c index f0a95dbba..f99b48495 100644 --- a/lib/upipe-filters/upipe_audio_graph.c +++ b/lib/upipe-filters/upipe_audio_graph.c @@ -244,7 +244,7 @@ static bool upipe_agraph_handle(struct upipe *upipe, struct uref *uref, uref_attr_import(uref, upipe_agraph->flow_def_config)) uref_pic_flow_clear_format(uref); UBASE_FATAL(upipe, uref_pic_flow_set_yuv420p(uref)); - UBASE_FATAL(upipe, uref_pic_set_progressive(uref)) + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, true)) upipe_agraph->hsize = upipe_agraph->vsize = upipe_agraph->sep_width = upipe_agraph->pad_width = UINT64_MAX; @@ -371,7 +371,7 @@ static bool upipe_agraph_handle(struct upipe *upipe, struct uref *uref, if (dst[i]) ubuf_pic_plane_unmap(ubuf, chroma[i], 0, 0, -1, -1); - uref_pic_set_progressive(uref); + uref_pic_set_progressive(uref, true); upipe_agraph_output(upipe, uref, upump_p); return true; } diff --git a/lib/upipe-filters/upipe_filter_blend.c b/lib/upipe-filters/upipe_filter_blend.c index 1421c27d7..9c3c18bd2 100644 --- a/lib/upipe-filters/upipe_filter_blend.c +++ b/lib/upipe-filters/upipe_filter_blend.c @@ -247,7 +247,7 @@ static bool upipe_filter_blend_handle(struct upipe *upipe, struct uref *uref, // Attach new ubuf and output frame uref_attach_ubuf(uref, ubuf_deint); - uref_pic_set_progressive(uref); + uref_pic_set_progressive(uref, true); uref_pic_delete_tff(uref); upipe_filter_blend_output(upipe, uref, upump_p); @@ -327,7 +327,7 @@ static int upipe_filter_blend_set_flow_def(struct upipe *upipe, upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } - UBASE_RETURN(uref_pic_set_progressive(flow_def_dup)) + UBASE_RETURN(uref_pic_set_progressive(flow_def_dup, true)) upipe_input(upipe, flow_def_dup, NULL); return UBASE_ERR_NONE; } diff --git a/lib/upipe-filters/upipe_filter_format.c b/lib/upipe-filters/upipe_filter_format.c index df2ff6446..052577b83 100644 --- a/lib/upipe-filters/upipe_filter_format.c +++ b/lib/upipe-filters/upipe_filter_format.c @@ -374,8 +374,8 @@ static int upipe_ffmt_check_flow_format(struct upipe *upipe, surface_type_out = ""; bool need_deint = ffmt_mgr->deint_mgr && - !ubase_check(uref_pic_get_progressive(flow_def)) && - ubase_check(uref_pic_get_progressive(flow_def_dup)); + !uref_pic_check_progressive(flow_def) && + uref_pic_check_progressive(flow_def_dup); bool need_scale = uref_pic_flow_cmp_hsize(flow_def, flow_def_dup) || uref_pic_flow_cmp_vsize(flow_def, flow_def_dup); diff --git a/lib/upipe-framers/upipe_h264_framer.c b/lib/upipe-framers/upipe_h264_framer.c index 0c9ac0ae3..5ef4cac69 100644 --- a/lib/upipe-framers/upipe_h264_framer.c +++ b/lib/upipe-framers/upipe_h264_framer.c @@ -727,13 +727,14 @@ static bool upipe_h264f_activate_sps(struct upipe *upipe, uint32_t sps_id) upipe_h264f->frame_mbs_only = !!ubuf_block_stream_show_bits(s, 1); ubuf_block_stream_skip_bits(s, 1); uint64_t vsize; + UBASE_FATAL(upipe, uref_pic_set_progressive(flow_def, + !!upipe_h264f->frame_mbs_only)) if (!upipe_h264f->frame_mbs_only) { vsize = map_height * 16 * 2; ubuf_block_stream_skip_bits(s, 1); /* mb_adaptive_frame_field */ - } else { - UBASE_FATAL(upipe, uref_pic_set_progressive(flow_def)) - vsize = map_height * 16; } + else + vsize = map_height * 16; ubuf_block_stream_skip_bits(s, 1); /* direct8x8_inference */ bool frame_cropping = !!ubuf_block_stream_show_bits(s, 1); @@ -1841,35 +1842,43 @@ static int upipe_h264f_prepare_au(struct upipe *upipe, struct uref *uref) switch (upipe_h264f->pic_struct) { case H264SEI_STRUCT_FRAME: - UBASE_RETURN(uref_pic_set_progressive(uref)) + UBASE_RETURN(uref_pic_set_progressive(uref, true)) duration *= 2; break; case H264SEI_STRUCT_TOP: + UBASE_RETURN(uref_pic_set_progressive(uref, false)) UBASE_RETURN(uref_pic_set_tf(uref)) break; case H264SEI_STRUCT_BOT: + UBASE_RETURN(uref_pic_set_progressive(uref, false)) UBASE_RETURN(uref_pic_set_bf(uref)) break; case H264SEI_STRUCT_TOP_BOT: + UBASE_RETURN(uref_pic_set_progressive(uref, false)) UBASE_RETURN(uref_pic_set_tf(uref)) UBASE_RETURN(uref_pic_set_bf(uref)) - UBASE_RETURN(uref_pic_set_tff(uref)) + UBASE_RETURN(uref_pic_set_tff(uref, true)) duration *= 2; break; case H264SEI_STRUCT_BOT_TOP: + UBASE_RETURN(uref_pic_set_progressive(uref, false)) UBASE_RETURN(uref_pic_set_tf(uref)) UBASE_RETURN(uref_pic_set_bf(uref)) + UBASE_RETURN(uref_pic_set_tff(uref, false)) duration *= 2; break; case H264SEI_STRUCT_TOP_BOT_TOP: + UBASE_RETURN(uref_pic_set_progressive(uref, false)) UBASE_RETURN(uref_pic_set_tf(uref)) UBASE_RETURN(uref_pic_set_bf(uref)) - UBASE_RETURN(uref_pic_set_tff(uref)) + UBASE_RETURN(uref_pic_set_tff(uref, true)) duration *= 3; break; case H264SEI_STRUCT_BOT_TOP_BOT: + UBASE_RETURN(uref_pic_set_progressive(uref, false)) UBASE_RETURN(uref_pic_set_tf(uref)) UBASE_RETURN(uref_pic_set_bf(uref)) + UBASE_RETURN(uref_pic_set_tff(uref, false)) duration *= 3; break; case H264SEI_STRUCT_DOUBLE: diff --git a/lib/upipe-framers/upipe_h265_framer.c b/lib/upipe-framers/upipe_h265_framer.c index 1a467cda1..5603662c5 100644 --- a/lib/upipe-framers/upipe_h265_framer.c +++ b/lib/upipe-framers/upipe_h265_framer.c @@ -1222,10 +1222,9 @@ static bool upipe_h265f_activate_sps(struct upipe *upipe, uint32_t sps_id) UBASE_FATAL(upipe, uref_clock_set_latency(flow_def, upipe_h265f->input_latency + upipe_h265f->duration * 2)) + uref_pic_set_progressive(flow_def, !field_seq_flag); if (field_seq_flag) frame_rate.den *= 2; - else - uref_pic_set_progressive(flow_def); urational_simplify(&frame_rate); UBASE_FATAL(upipe, uref_pic_flow_set_fps(flow_def, frame_rate)) @@ -2082,39 +2081,47 @@ static int upipe_h265f_prepare_au(struct upipe *upipe, struct uref *uref) switch (upipe_h265f->pic_struct) { case H265SEI_STRUCT_FRAME: - UBASE_FATAL(upipe, uref_pic_set_progressive(uref)) + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, true)) duration *= 2; break; case H265SEI_STRUCT_TOP: case H265SEI_STRUCT_TOP_PREV_BOT: case H265SEI_STRUCT_TOP_NEXT_BOT: + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, false)) UBASE_FATAL(upipe, uref_pic_set_tf(uref)) break; case H265SEI_STRUCT_BOT: case H265SEI_STRUCT_BOT_PREV_TOP: case H265SEI_STRUCT_BOT_NEXT_TOP: + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, false)) UBASE_FATAL(upipe, uref_pic_set_bf(uref)) break; case H265SEI_STRUCT_TOP_BOT: + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, false)) UBASE_FATAL(upipe, uref_pic_set_tf(uref)) UBASE_FATAL(upipe, uref_pic_set_bf(uref)) - UBASE_FATAL(upipe, uref_pic_set_tff(uref)) + UBASE_FATAL(upipe, uref_pic_set_tff(uref, true)) duration *= 2; break; case H265SEI_STRUCT_BOT_TOP: + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, false)) UBASE_FATAL(upipe, uref_pic_set_tf(uref)) UBASE_FATAL(upipe, uref_pic_set_bf(uref)) + UBASE_FATAL(upipe, uref_pic_set_tff(uref, false)) duration *= 2; break; case H265SEI_STRUCT_TOP_BOT_TOP: + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, false)) UBASE_FATAL(upipe, uref_pic_set_tf(uref)) UBASE_FATAL(upipe, uref_pic_set_bf(uref)) - UBASE_FATAL(upipe, uref_pic_set_tff(uref)) + UBASE_FATAL(upipe, uref_pic_set_tff(uref, true)) duration *= 3; break; case H265SEI_STRUCT_BOT_TOP_BOT: + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, false)) UBASE_FATAL(upipe, uref_pic_set_tf(uref)) UBASE_FATAL(upipe, uref_pic_set_bf(uref)) + UBASE_FATAL(upipe, uref_pic_set_tff(uref, false)) duration *= 3; break; case H265SEI_STRUCT_DOUBLE: diff --git a/lib/upipe-framers/upipe_mpgv_framer.c b/lib/upipe-framers/upipe_mpgv_framer.c index 87da35a5d..0ab5806ec 100644 --- a/lib/upipe-framers/upipe_mpgv_framer.c +++ b/lib/upipe-framers/upipe_mpgv_framer.c @@ -455,8 +455,7 @@ static bool upipe_mpgvf_parse_sequence(struct upipe *upipe) UCLOCK_FREQ * frame_rate.den / frame_rate.num)) UBASE_FATAL(upipe, uref_block_flow_set_max_octetrate(flow_def, max_octetrate)) upipe_mpgvf->progressive_sequence = progressive; - if (progressive) - UBASE_FATAL(upipe, uref_pic_set_progressive(flow_def)) + UBASE_FATAL(upipe, uref_pic_set_progressive(flow_def, progressive)) UBASE_FATAL(upipe, uref_pic_flow_set_macropixel(flow_def, 1)) UBASE_FATAL(upipe, uref_pic_flow_set_planes(flow_def, 0)) UBASE_FATAL(upipe, uref_pic_flow_add_plane(flow_def, 1, 1, 1, "y8")) @@ -861,15 +860,13 @@ static bool upipe_mpgvf_parse_picture(struct upipe *upipe, struct uref *uref, UBASE_FATAL(upipe, uref_pic_set_tf(uref)) if (structure & MP2VPICX_BOTTOM_FIELD) UBASE_FATAL(upipe, uref_pic_set_bf(uref)) - if (tff) - UBASE_FATAL(upipe, uref_pic_set_tff(uref)) - if (progressive) - UBASE_FATAL(upipe, uref_pic_set_progressive(uref)) + UBASE_FATAL(upipe, uref_pic_set_tff(uref, tff)) + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, progressive)) } else { upipe_mpgvf->field_number = 0; UBASE_FATAL(upipe, uref_pic_set_tf(uref)) UBASE_FATAL(upipe, uref_pic_set_bf(uref)) - UBASE_FATAL(upipe, uref_pic_set_progressive(uref)) + UBASE_FATAL(upipe, uref_pic_set_progressive(uref, true)) } UBASE_FATAL(upipe, uref_clock_set_duration(uref, *duration_p)) diff --git a/lib/upipe-gl/upipe_glx_sink.c b/lib/upipe-gl/upipe_glx_sink.c index 82e34def0..69df0b7a2 100644 --- a/lib/upipe-gl/upipe_glx_sink.c +++ b/lib/upipe-gl/upipe_glx_sink.c @@ -500,7 +500,7 @@ static int upipe_glx_sink_provide_flow_format(struct upipe *upipe, uref_pic_flow_add_plane(flow_format, 1, 1, 2, "r5g6b5"); else uref_pic_flow_add_plane(flow_format, 1, 1, 3, "r8g8b8"); - uref_pic_set_progressive(flow_format); + uref_pic_set_progressive(flow_format, true); uref_pic_flow_delete_colour_primaries(flow_format); uref_pic_flow_delete_transfer_characteristics(flow_format); uref_pic_flow_delete_matrix_coefficients(flow_format); diff --git a/lib/upipe-modules/upipe_rtp_anc_unpack.c b/lib/upipe-modules/upipe_rtp_anc_unpack.c index 74e947611..b26a86035 100644 --- a/lib/upipe-modules/upipe_rtp_anc_unpack.c +++ b/lib/upipe-modules/upipe_rtp_anc_unpack.c @@ -179,7 +179,7 @@ static bool upipe_rtp_anc_unpack_handle(struct upipe *upipe, struct uref *uref, switch (f) { case RFC_8331_F_PROGRESSIVE: - uref_pic_set_progressive(uref); + uref_pic_set_progressive(uref, true); break; case RFC_8331_F_FIELD_1: uref_pic_set_tf(uref); diff --git a/lib/upipe-modules/upipe_separate_fields.c b/lib/upipe-modules/upipe_separate_fields.c index 383c2a747..0ff0e0f68 100644 --- a/lib/upipe-modules/upipe_separate_fields.c +++ b/lib/upipe-modules/upipe_separate_fields.c @@ -85,7 +85,7 @@ static int upipe_separate_fields_set_flow_def(struct upipe *upipe, ctx->field_duration = UCLOCK_FREQ * fps.den / fps.num; UBASE_RETURN(uref_pic_flow_set_fps(flow_def_dup, fps)); UBASE_RETURN(uref_pic_flow_set_vsize(flow_def_dup, height)); - if (ubase_check(uref_pic_get_progressive(flow_def_dup))) + if (uref_pic_check_progressive(flow_def_dup)) UBASE_RETURN(uref_pic_delete_progressive(flow_def_dup)); upipe_separate_fields_store_flow_def(upipe, flow_def_dup); @@ -152,8 +152,8 @@ static void upipe_separate_fields_input(struct upipe *upipe, struct uref *uref, return; } - bool has_progressive_attr = ubase_check(uref_pic_get_progressive(uref)); - bool has_tff_attr = ubase_check(uref_pic_get_tff(uref)); + bool has_progressive_attr = uref_pic_check_progressive(uref); + bool has_tff_attr = uref_pic_check_tff(uref); if (has_progressive_attr) upipe_warn(upipe, "picture marked as progressive, separating fields anyway"); diff --git a/lib/upipe-modules/upipe_video_blank.c b/lib/upipe-modules/upipe_video_blank.c index 1d46150d5..2aafb9328 100644 --- a/lib/upipe-modules/upipe_video_blank.c +++ b/lib/upipe-modules/upipe_video_blank.c @@ -254,10 +254,8 @@ static bool upipe_vblk_try_output(struct upipe *upipe, uref_attach_ubuf(uref, ubuf); if (upipe_vblk->pic_attr) uref_attr_import(uref, upipe_vblk->pic_attr); - if (ubase_check(uref_pic_get_progressive(upipe_vblk->flow_def))) - uref_pic_set_progressive(uref); - else if (ubase_check(uref_pic_get_tff(upipe_vblk->flow_def))) - uref_pic_set_tff(uref); + uref_pic_copy_progressive(uref, upipe_vblk->flow_def); + uref_pic_copy_tff(uref, upipe_vblk->flow_def); upipe_vblk_output(upipe, uref, upump_p); return true; diff --git a/lib/upipe-modules/upipe_videocont.c b/lib/upipe-modules/upipe_videocont.c index 2f7fda10d..68febaa8a 100644 --- a/lib/upipe-modules/upipe_videocont.c +++ b/lib/upipe-modules/upipe_videocont.c @@ -402,36 +402,13 @@ static int upipe_videocont_switch_format(struct upipe *upipe, struct uref *out_flow, struct uref *in_flow) { - uint64_t hsize, vsize; - struct urational sar; uref_pic_flow_clear_format(out_flow); uref_pic_flow_copy_format(out_flow, in_flow); - if (likely(ubase_check(uref_pic_flow_get_hsize(in_flow, &hsize)))) { - uref_pic_flow_set_hsize(out_flow, hsize); - } else { - uref_pic_flow_delete_hsize(out_flow); - } - if (likely(ubase_check(uref_pic_flow_get_vsize(in_flow, &vsize)))) { - uref_pic_flow_set_vsize(out_flow, vsize); - } else { - uref_pic_flow_delete_vsize(out_flow); - } - if (likely(ubase_check(uref_pic_flow_get_sar(in_flow, &sar)))) { - uref_pic_flow_set_sar(out_flow, sar); - } else { - uref_pic_flow_delete_sar(out_flow); - } - bool overscan; - if (likely(ubase_check(uref_pic_flow_get_overscan(in_flow, &overscan)))) { - uref_pic_flow_set_overscan(out_flow, overscan); - } else { - uref_pic_flow_delete_overscan(out_flow); - } - if (likely(ubase_check(uref_pic_get_progressive(in_flow)))) { - uref_pic_set_progressive(out_flow); - } else { - uref_pic_delete_progressive(out_flow); - } + uref_pic_flow_copy_hsize(out_flow, in_flow); + uref_pic_flow_copy_vsize(out_flow, in_flow); + uref_pic_flow_copy_sar(out_flow, in_flow); + uref_pic_flow_copy_overscan(out_flow, in_flow); + uref_pic_copy_progressive(out_flow, in_flow); return UBASE_ERR_NONE; } diff --git a/lib/upipe-swscale/upipe_sws.c b/lib/upipe-swscale/upipe_sws.c index c88b79394..f7e77664e 100644 --- a/lib/upipe-swscale/upipe_sws.c +++ b/lib/upipe-swscale/upipe_sws.c @@ -169,7 +169,7 @@ static bool upipe_sws_handle(struct upipe *upipe, struct uref *uref, return true; } - int progressive = ubase_check(uref_pic_get_progressive(uref)) ? 1 : 0; + int progressive = uref_pic_check_progressive(uref) ? 1 : 0; if (unlikely(!progressive && input_vsize % 2)) { upipe_warn(upipe, "interlaced picture has odd vertical size"); progressive = 1; diff --git a/lib/upipe-x264/upipe_x264.c b/lib/upipe-x264/upipe_x264.c index fa75e8e46..d50e5b26e 100644 --- a/lib/upipe-x264/upipe_x264.c +++ b/lib/upipe-x264/upipe_x264.c @@ -399,7 +399,7 @@ static int upipe_x264_open(struct upipe *upipe, struct uref *uref) int ret; uref_pic_size(uref, &width, &height, NULL); - bool tff = ubase_check(uref_pic_get_tff(uref)); + bool tff = uref_pic_check_tff(uref); params->rc.psz_stat_out = NULL; params->rc.psz_stat_in = NULL; @@ -431,7 +431,7 @@ static int upipe_x264_open(struct upipe *upipe, struct uref *uref) params->i_height = height; params->b_tff = tff; params->b_interlaced = - !ubase_check(uref_pic_get_progressive(upipe_x264->flow_def_input)); + !uref_pic_check_progressive(upipe_x264->flow_def_input); const char *content; if (ubase_check(uref_pic_flow_get_video_format( @@ -703,7 +703,7 @@ static int upipe_x264_update(struct upipe *upipe, struct uref *uref) int ret = UBASE_ERR_NONE; uref_pic_size(uref, &width, &height, NULL); - bool tff = ubase_check(uref_pic_get_tff(uref)); + bool tff = uref_pic_check_tff(uref); if (upipe_x264->encoder) { #ifdef HAVE_X264_MPEG2 @@ -880,8 +880,8 @@ static bool upipe_x264_handle(struct upipe *upipe, struct uref *uref, } #ifdef HAVE_X264_MPEG2 - if (!ubase_check(uref_pic_get_progressive(uref))) - pic.b_tff = ubase_check(uref_pic_get_tff(uref)); + if (!uref_pic_check_progressive(uref)) + pic.b_tff = uref_pic_check_tff(uref); #endif /* map */ diff --git a/lib/upipe-x265/upipe_x265.c b/lib/upipe-x265/upipe_x265.c index ddec9b774..149d134ff 100644 --- a/lib/upipe-x265/upipe_x265.c +++ b/lib/upipe-x265/upipe_x265.c @@ -401,7 +401,7 @@ static void apply_params(struct upipe *upipe, x265_param *params) params->internalCsp = upipe_x265->color_space; params->interlaceMode = - !ubase_check(uref_pic_get_progressive(flow_def)); + !uref_pic_check_progressive(flow_def); upipe_x265_set_option(upipe, params, "range", ubase_check(uref_pic_flow_get_full_range(flow_def)) ? diff --git a/lib/upipe/udict_inline.c b/lib/upipe/udict_inline.c index 58db72ba8..d7ad37b33 100644 --- a/lib/upipe/udict_inline.c +++ b/lib/upipe/udict_inline.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2012-2017 OpenHeadend S.A.R.L. + * Copyright (C) 2026 EasyTools * * Authors: Christophe Massiot * @@ -79,10 +80,10 @@ static const struct inline_shorthand inline_shorthands[] = { { "p.bpadding", UDICT_TYPE_UNSIGNED }, { "p.sar", UDICT_TYPE_RATIONAL }, { "p.overscan", UDICT_TYPE_BOOL }, - { "p.progressive", UDICT_TYPE_VOID }, + { "p.progressive", UDICT_TYPE_BOOL }, { "p.tf", UDICT_TYPE_VOID }, { "p.bf", UDICT_TYPE_VOID }, - { "p.tff", UDICT_TYPE_VOID }, + { "p.tff", UDICT_TYPE_BOOL }, { "p.afd", UDICT_TYPE_SMALL_UNSIGNED }, { "p.cea_708", UDICT_TYPE_OPAQUE }, { "p.bar_data", UDICT_TYPE_OPAQUE }, diff --git a/tests/upipe_blank_source_test.c b/tests/upipe_blank_source_test.c index 8362b7858..8c8cbe937 100644 --- a/tests/upipe_blank_source_test.c +++ b/tests/upipe_blank_source_test.c @@ -116,7 +116,7 @@ static void test_input(struct upipe *upipe, struct uref *uref, uref_free(flow); struct uref *uref = uref_alloc(uref_mgr); - uref_pic_set_progressive(uref); + uref_pic_set_progressive(uref, true); upipe_input(blksrc, uref, NULL); } diff --git a/tests/upipe_blit_test.c b/tests/upipe_blit_test.c index 683c4bd02..98f83223c 100644 --- a/tests/upipe_blit_test.c +++ b/tests/upipe_blit_test.c @@ -152,7 +152,7 @@ static void setup_sub(struct upipe *sub, struct uref_mgr *uref_mgr, struct uref *uref = uref_pic_alloc(uref_mgr, pic_mgr, SUBSIZE, SUBSIZE); assert(uref != NULL); - uref_pic_set_progressive(uref); + uref_pic_set_progressive(uref, true); fill_in(uref, "y8", val); fill_in(uref, "u8", val); fill_in(uref, "v8", val); @@ -312,7 +312,7 @@ int main(int argc, char **argv) struct uref *uref; uref = uref_pic_alloc(uref_mgr, pic_mgr, BGSIZE, BGSIZE); assert(uref != NULL); - uref_pic_set_progressive(uref); + uref_pic_set_progressive(uref, true); fill_in(uref, "y8", 0); fill_in(uref, "u8", 0); fill_in(uref, "v8", 0); @@ -343,7 +343,7 @@ int main(int argc, char **argv) uref = uref_pic_alloc(uref_mgr, pic_mgr, BGSIZE, BGSIZE); assert(uref != NULL); - uref_pic_set_progressive(uref); + uref_pic_set_progressive(uref, true); fill_in(uref, "y8", 0); fill_in(uref, "u8", 0); fill_in(uref, "v8", 0); diff --git a/tests/upipe_separate_fields_test.c b/tests/upipe_separate_fields_test.c index 6ceb72d82..89545911e 100644 --- a/tests/upipe_separate_fields_test.c +++ b/tests/upipe_separate_fields_test.c @@ -278,7 +278,7 @@ int main(int argc, char **argv) ubase_assert(uref_pic_flow_add_plane(flow, 1, 1, 1, "y8")); ubase_assert(uref_pic_flow_add_plane(flow, 2, 2, 1, "u8")); ubase_assert(uref_pic_flow_add_plane(flow, 2, 2, 1, "v8")); - ubase_assert(uref_pic_set_tff(flow)); + ubase_assert(uref_pic_set_tff(flow, true)); ubase_assert(uref_pic_flow_set_hsize(flow, WIDTH)); ubase_assert(uref_pic_flow_set_vsize(flow, HEIGHT)); ubase_assert(uref_pic_flow_set_fps(flow, fps)); diff --git a/tests/upipe_sws_test.c b/tests/upipe_sws_test.c index 28cfffa52..6af965c80 100644 --- a/tests/upipe_sws_test.c +++ b/tests/upipe_sws_test.c @@ -310,7 +310,7 @@ int main(int argc, char **argv) uref1 = uref_pic_alloc(uref_mgr, ubuf_mgr, SRCSIZE, SRCSIZE); assert(uref1 != NULL); assert(uref1->ubuf != NULL); - ubase_assert(uref_pic_set_progressive(uref1)); + ubase_assert(uref_pic_set_progressive(uref1, true)); /* fill reference picture */ fill_in(uref1, "y8", 1, 1, 1); @@ -323,7 +323,7 @@ int main(int argc, char **argv) uref2 = uref_pic_alloc(uref_mgr, ubuf_mgr, DSTSIZE, DSTSIZE); assert(uref2); assert(uref2->ubuf); - ubase_assert(uref_pic_set_progressive(uref2)); + ubase_assert(uref_pic_set_progressive(uref2, true)); img_convert_ctx = sws_getCachedContext(NULL, SRCSIZE, SRCSIZE, AV_PIX_FMT_YUV420P, diff --git a/tests/upipe_x265_test.c b/tests/upipe_x265_test.c index 49dff409e..bd66d8709 100644 --- a/tests/upipe_x265_test.c +++ b/tests/upipe_x265_test.c @@ -219,7 +219,7 @@ int main(int argc, char **argv) ubase_assert(uref_pic_flow_set_vsize(flow_def, HEIGHT)); struct urational fps = { .num = 25, .den = 1 }; ubase_assert(uref_pic_flow_set_fps(flow_def, fps)); - ubase_assert(uref_pic_set_progressive(flow_def)); + ubase_assert(uref_pic_set_progressive(flow_def, true)); /* x265 pipe */ struct upipe *x265 = upipe_void_alloc(upipe_x265_mgr,