From: James Almer <jamrial@gmail.com> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 4/4] avcodec/h264dec: add support for LCEVC enhancement Date: Sat, 20 Jul 2024 09:45:10 -0300 Message-ID: <20240720124510.1689-4-jamrial@gmail.com> (raw) In-Reply-To: <20240720124510.1689-1-jamrial@gmail.com> Signed-off-by: James Almer <jamrial@gmail.com> --- libavcodec/Makefile | 2 +- libavcodec/avcodec.h | 5 ++++ libavcodec/h264_picture.c | 1 + libavcodec/h264_slice.c | 19 ++++++++++++++++ libavcodec/h264dec.c | 48 ++++++++++++++++++++++++++++++++++++--- libavcodec/h264dec.h | 3 +++ 6 files changed, 74 insertions(+), 4 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 771e2b597e..69492eee10 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -407,7 +407,7 @@ OBJS-$(CONFIG_H263_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \ h264_direct.o h264_loopfilter.o \ h264_mb.o h264_picture.o \ - h264_refs.o \ + h264_refs.o lcevcdec.o \ h264_slice.o h264data.o h274.o OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 2da63c87ea..ff20d22545 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -418,6 +418,11 @@ typedef struct RcOverride{ * Do not apply film grain, export it instead. */ #define AV_CODEC_EXPORT_DATA_FILM_GRAIN (1 << 3) +/** + * Decoding only. + * Do not apply picture enhancement layers, export them instead. + */ +#define AV_CODEC_EXPORT_DATA_ENHANCEMENTS (1 << 3) /** * The decoder will keep a reference to the frame and may reuse it later. diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c index 3234141dbd..1cdb926d15 100644 --- a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@ -103,6 +103,7 @@ static void h264_copy_picture_params(H264Picture *dst, const H264Picture *src) dst->mb_height = src->mb_height; dst->mb_stride = src->mb_stride; dst->needs_fg = src->needs_fg; + dst->needs_lcevc = src->needs_lcevc; } int ff_h264_ref_picture(H264Picture *dst, const H264Picture *src) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index a66b75ca80..263172e600 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -191,6 +191,13 @@ static int alloc_picture(H264Context *h, H264Picture *pic) av_assert0(!pic->f->data[0]); +#if CONFIG_LIBLCEVC_DEC + if (pic->needs_lcevc) { + pic->f->width = FFMAX(h->avctx->width, h->avctx->coded_width) * 2 / FFMAX(h->avctx->sample_aspect_ratio.den, 1); + pic->f->height = FFMAX(h->avctx->height, h->avctx->coded_height) * 2 / FFMAX(h->avctx->sample_aspect_ratio.num, 1); + } +#endif + pic->tf.f = pic->f; ret = ff_thread_get_ext_buffer(h->avctx, &pic->tf, pic->reference ? AV_GET_BUFFER_FLAG_REF : 0); @@ -206,6 +213,13 @@ static int alloc_picture(H264Context *h, H264Picture *pic) goto fail; } +#if CONFIG_LIBLCEVC_DEC + if (pic->needs_lcevc) { + pic->f->width = FFMAX(h->avctx->width, h->avctx->coded_width); + pic->f->height = FFMAX(h->avctx->height, h->avctx->coded_height); + } +#endif + ret = ff_hwaccel_frame_priv_alloc(h->avctx, &pic->hwaccel_picture_private); if (ret < 0) goto fail; @@ -459,6 +473,8 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->recovery_frame = h1->recovery_frame; h->non_gray = h1->non_gray; + av_buffer_replace(&h->lcevc, h1->lcevc); + return err; } @@ -519,6 +535,9 @@ static int h264_frame_start(H264Context *h) pic->needs_fg = h->sei.common.film_grain_characteristics.present && !h->avctx->hwaccel && !(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN); + pic->needs_lcevc = h->sei.common.lcevc.info && !h->avctx->hwaccel && + !(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS); + if ((ret = alloc_picture(h, pic)) < 0) return ret; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index e186bc18dc..a80d8e16d5 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -57,6 +57,10 @@ #include "thread.h" #include "threadframe.h" +#if CONFIG_LIBLCEVC_DEC +#include "lcevcdec.h" +#endif + const uint16_t ff_h264_mb_sizes[4] = { 256, 384, 512, 768 }; int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx) @@ -378,6 +382,8 @@ static av_cold int h264_decode_end(AVCodecContext *avctx) h264_free_pic(h, &h->cur_pic); h264_free_pic(h, &h->last_pic_for_ec); + av_buffer_unref(&h->lcevc); + return 0; } @@ -405,6 +411,9 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif if (!avctx->internal->is_copy) { +#if CONFIG_LIBLCEVC_DEC + FFLCEVCContext *lcevc; +#endif if (avctx->extradata_size > 0 && avctx->extradata) { ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size, &h->ps, &h->is_avc, &h->nal_length_size, @@ -419,6 +428,21 @@ FF_ENABLE_DEPRECATION_WARNINGS ret = 0; } } +#if CONFIG_LIBLCEVC_DEC + lcevc = av_mallocz(sizeof(FFLCEVCContext)); + ret = ff_lcevc_init(lcevc, avctx); + if (ret < 0) { + int explode = avctx->err_recognition & AV_EF_EXPLODE; + av_log(avctx, explode ? AV_LOG_ERROR: AV_LOG_WARNING, + "Error initializing LCEVC\n"); + if (explode) { + av_free(lcevc); + return ret; + } + ret = 0; + } + h->lcevc = av_buffer_create(lcevc, sizeof(FFLCEVCContext), ff_lcevc_free, lcevc, 0); +#endif } if (h->ps.sps && h->ps.sps->bitstream_restriction_flag && @@ -668,9 +692,23 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) h->setup_finished = 1; } - if (h->avctx->hwaccel && - (ret = FF_HW_CALL(h->avctx, start_frame, buf, buf_size)) < 0) - goto end; + if (h->avctx->hwaccel) { + ret = FF_HW_CALL(h->avctx, start_frame, buf, buf_size); + if (ret < 0) + goto end; + } +#if CONFIG_LIBLCEVC_DEC + else if (h->cur_pic_ptr->needs_lcevc) { + FrameDecodeData *fdd = (FrameDecodeData*)h->cur_pic_ptr->f->private_ref->data; + fdd->post_process_opaque = av_buffer_ref(h->lcevc); + if (!fdd->post_process_opaque) { + ret = -1; + goto end; + } + fdd->post_process_opaque_free = ff_lcevc_unref; + fdd->post_process = ff_lcevc_process; + } +#endif } max_slice_ctx = avctx->hwaccel ? 1 : h->nb_slice_ctx; @@ -905,6 +943,10 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) if (!(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN)) av_frame_remove_side_data(dst, AV_FRAME_DATA_FILM_GRAIN_PARAMS); +#if CONFIG_LIBLCEVC_DEC + if (!(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS)) + av_frame_remove_side_data(dst, AV_FRAME_DATA_LCEVC); +#endif return 0; fail: diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index ccd7583bf4..419d699bab 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -154,6 +154,7 @@ typedef struct H264Picture { int invalid_gap; int sei_recovery_frame_cnt; int needs_fg; ///< whether picture needs film grain synthesis (see `f_grain`) + int needs_lcevc; ///< whether picture needs LCEVC enhancement const PPS *pps; @@ -580,6 +581,8 @@ typedef struct H264Context { int non_gray; ///< Did we encounter a intra frame after a gray gap frame int noref_gray; int skip_gray; + + AVBufferRef *lcevc; // FFLCEVCContext } H264Context; extern const uint16_t ff_h264_mb_sizes[4]; -- 2.45.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2024-07-20 12:45 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-07-20 12:45 [FFmpeg-devel] [PATCH 1/4] avutil/frame: add an LCEVC enhancement data payload side data type James Almer 2024-07-20 12:45 ` [FFmpeg-devel] [PATCH 2/4] libavcodec/h2645_sei: export raw LCEVC metadata James Almer 2024-07-20 23:38 ` Michael Niedermayer 2024-07-20 23:40 ` Gagan Sidhu via ffmpeg-devel 2024-07-21 0:17 ` James Almer 2024-07-21 0:18 ` Gagan Sidhu via ffmpeg-devel 2024-07-20 12:45 ` [FFmpeg-devel] [PATCH 3/4] avcodec: add LCEVC decoding support via LCEVCdec James Almer 2024-07-20 12:45 ` James Almer [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240720124510.1689-4-jamrial@gmail.com \ --to=jamrial@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git