Signed-off-by: James Almer <jamr...@gmail.com> --- libavcodec/avcodec.c | 2 ++ libavcodec/avcodec.h | 5 +++++ libavcodec/decode.c | 42 +++++++++++++++++++++++++++++++++++++- libavcodec/internal.h | 2 ++ libavcodec/lcevcdec.c | 2 ++ libavcodec/options_table.h | 1 + libavcodec/pthread_frame.c | 7 +++++++ 7 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 6065f1b689..380df267a0 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -446,6 +446,8 @@ av_cold void ff_codec_close(AVCodecContext *avctx) ff_refstruct_unref(&avci->pool); ff_refstruct_pool_uninit(&avci->progress_frame_pool); + av_buffer_unref(&avci->lcevc); + ff_hwaccel_uninit(avctx); av_bsf_free(&avci->bsf); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 7a67300134..f6e01da738 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 << 4) /** * The decoder will keep a reference to the frame and may reuse it later. diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 27dba8a1f3..dc868714ac 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -48,6 +48,7 @@ #include "hwaccel_internal.h" #include "hwconfig.h" #include "internal.h" +#include "lcevcdec.h" #include "packet_internal.h" #include "progressframe.h" #include "refstruct.h" @@ -1599,6 +1600,7 @@ int ff_attach_decode_data(AVFrame *frame) int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) { const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel); + int lcevc = 0, width = 0, height = 0; int override_dimensions = 1; int ret; @@ -1639,8 +1641,17 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) ret = hwaccel->alloc_frame(avctx, frame); goto end; } - } else + } else { avctx->sw_pix_fmt = avctx->pix_fmt; + lcevc = CONFIG_LIBLCEVC_DEC && avctx->codec_type == AVMEDIA_TYPE_VIDEO && + avctx->internal->lcevc && av_frame_get_side_data(frame, AV_FRAME_DATA_LCEVC); + if (lcevc) { + width = frame->width; + height = frame->height; + frame->width = frame->width * 2 / FFMAX(frame->sample_aspect_ratio.den, 1); + frame->height = frame->height * 2 / FFMAX(frame->sample_aspect_ratio.num, 1); + } + } ret = avctx->get_buffer2(avctx, frame, flags); if (ret < 0) @@ -1652,6 +1663,20 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) if (ret < 0) goto fail; + if (CONFIG_LIBLCEVC_DEC && lcevc) { + FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data; + fdd->post_process_opaque = av_buffer_ref(avctx->internal->lcevc); + + frame->width = width; + frame->height = height; + if (!fdd->post_process_opaque) { + ret = AVERROR(ENOMEM); + goto fail; + } + fdd->post_process_opaque_free = ff_lcevc_unref; + fdd->post_process = ff_lcevc_process; + } + end: if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions && !(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) { @@ -1949,6 +1974,21 @@ int ff_decode_preinit(AVCodecContext *avctx) if (ret < 0) return ret; + if (CONFIG_LIBLCEVC_DEC && !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS)) { + FFLCEVCContext *lcevc = av_mallocz(sizeof(*lcevc)); + + if (!lcevc || !(avci->lcevc = av_buffer_create((uint8_t *)lcevc, sizeof(*lcevc), + ff_lcevc_free, lcevc, 0))) { + int explode = avctx->err_recognition & AV_EF_EXPLODE; + av_log(avctx, explode ? AV_LOG_ERROR: AV_LOG_WARNING, + "Error allocating LCEVC context\n"); + if (explode) { + av_free(lcevc); + return AVERROR(ENOMEM); + } + } + } + #if FF_API_DROPCHANGED if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) av_log(avctx, AV_LOG_WARNING, "The dropchanged flag is deprecated.\n"); diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 98ab2797ce..aae78854cc 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -158,6 +158,8 @@ typedef struct AVCodecInternal { FFIccContext icc; /* used to read and write embedded ICC profiles */ #endif + AVBufferRef *lcevc; + /** * Set when the user has been warned about a failed allocation from * a fixed frame pool. diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c index ae1d150986..47fdaaa9ef 100644 --- a/libavcodec/lcevcdec.c +++ b/libavcodec/lcevcdec.c @@ -229,6 +229,8 @@ int ff_lcevc_process(void *logctx, AVFrame *frame) if (ret < 0) return ret; + av_frame_remove_side_data(frame, AV_FRAME_DATA_LCEVC); + return 0; } diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 33f1bce887..332f354fa6 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -93,6 +93,7 @@ static const AVOption avcodec_options[] = { {"prft", "export Producer Reference Time through packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_PRFT}, INT_MIN, INT_MAX, A|V|S|E, .unit = "export_side_data"}, {"venc_params", "export video encoding parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS}, INT_MIN, INT_MAX, V|D, .unit = "export_side_data"}, {"film_grain", "export film grain parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_FILM_GRAIN}, INT_MIN, INT_MAX, V|D, .unit = "export_side_data"}, +{"enhancements", "export film grain parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_ENHANCEMENTS}, INT_MIN, INT_MAX, V|D, .unit = "export_side_data"}, {"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, INT_MAX}, {"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E}, {"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 019e33b7b2..00ad93cbdf 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -782,6 +782,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) ff_refstruct_unref(&ctx->internal->pool); av_packet_free(&ctx->internal->in_pkt); av_packet_free(&ctx->internal->last_pkt_props); + av_buffer_unref(&ctx->internal->lcevc); av_freep(&ctx->internal); av_buffer_unref(&ctx->hw_frames_ctx); av_frame_side_data_free(&ctx->decoded_side_data, @@ -878,6 +879,12 @@ static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, if (!copy->internal->in_pkt) return AVERROR(ENOMEM); + if (avctx->internal->lcevc) { + copy->internal->lcevc = av_buffer_ref(avctx->internal->lcevc); + if (!copy->internal->lcevc) + return AVERROR(ENOMEM); + } + copy->internal->last_pkt_props = av_packet_alloc(); if (!copy->internal->last_pkt_props) return AVERROR(ENOMEM); -- 2.46.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".