From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 909A34C106 for ; Mon, 22 Jul 2024 11:16:31 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 06B7468D519; Mon, 22 Jul 2024 14:16:29 +0300 (EEST) Received: from sender-op-o17.zoho.eu (sender-op-o17.zoho.eu [136.143.169.17]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A4A3C68D519 for ; Mon, 22 Jul 2024 14:16:22 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; t=1721646979; cv=none; d=zohomail.eu; s=zohoarc; b=hLC102B/7utDKGE+Ej7+gbdaAIke4gaSPjRKzD3C2c3mxu3zbsj2NXDf3eZnTzBO3D1bgnXiDusIMyAgK121gkZE8h9t8sagw3aRUzldeYQ4H7E6VLTejg27Do50+o5YpFvPGUOHXbRe6Wy7IDX2ggwG8B0zQXvD6goA4jCTKuY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.eu; s=zohoarc; t=1721646979; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To:Cc; bh=NSq0kwnjE8fTgZR0XlsBUIHKZFt16x42ehFWem/0IZk=; b=eDMNG8JcP/YzZVtdzeu411lZGdMHrMztzz6LJhYEXJQTYoZLoS+i8xFs2rWxxFG1ExS3eqJRYG8t5LXTu6TaA2At8c+0QjrDqJ4meotTiVMEweYi+XoNg0WktzJoP4GbJQHTiaNCKPmJvrjs5kCq8SkxeBRLYGXBAh7AUoSJKqo= ARC-Authentication-Results: i=1; mx.zohomail.eu; dkim=pass header.i=frankplowman.com; spf=pass smtp.mailfrom=post@frankplowman.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1721646979; s=zmail; d=frankplowman.com; i=post@frankplowman.com; h=Message-ID:Date:Date:MIME-Version:Subject:Subject:To:To:References:From:From:In-Reply-To:Content-Type:Content-Transfer-Encoding:Message-Id:Reply-To:Cc; bh=NSq0kwnjE8fTgZR0XlsBUIHKZFt16x42ehFWem/0IZk=; b=Nx7pbGWkFUB+rzQyz6UBUSts9UwnvcdTu/UHKMoC28DqzWsUlTdL/zQijYAI2uYX pajeoFy6T0XnUFyfk/Gpq1aHbXgUgZ8/vJqiPUv687g3LAtX2U07K2m2SwFJ587quQi WNdoDBAwwhLbiGxiOdm8jY+9MTws16siRHJYvH/k= Received: by mx.zoho.eu with SMTPS id 172164697461295.07594386037636; Mon, 22 Jul 2024 13:16:14 +0200 (CEST) Message-ID: <4dd89474-bc7a-45b5-b0f7-a524a9ada859@frankplowman.com> Date: Mon, 22 Jul 2024 12:16:13 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-GB To: ffmpeg-devel@ffmpeg.org References: <20240721225350.298-1-jamrial@gmail.com> <20240721225350.298-3-jamrial@gmail.com> From: Frank Plowman In-Reply-To: <20240721225350.298-3-jamrial@gmail.com> X-ZohoMailClient: External Subject: Re: [FFmpeg-devel] [PATCH 3/4 v2] avcodec: add LCEVC decoding support via LCEVCdec X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: On 21/07/2024 23:53, James Almer wrote: > Signed-off-by: James Almer > --- > configure | 3 + > doc/general_contents.texi | 13 ++ > libavcodec/Makefile | 1 + > libavcodec/lcevcdec.c | 276 ++++++++++++++++++++++++++++++++++++++ > libavcodec/lcevcdec.h | 44 ++++++ > 5 files changed, 337 insertions(+) > create mode 100644 libavcodec/lcevcdec.c > create mode 100644 libavcodec/lcevcdec.h > > diff --git a/configure b/configure > index f6f5c29fea..d1f32684a6 100755 > --- a/configure > +++ b/configure > @@ -225,6 +225,7 @@ External library support: > --enable-libcdio enable audio CD grabbing with libcdio [no] > --enable-libcodec2 enable codec2 en/decoding using libcodec2 [no] > --enable-libdav1d enable AV1 decoding via libdav1d [no] > + --enable-liblcevc_dec enable LCEVC decoding via liblcevc_dec [no] > --enable-libdavs2 enable AVS2 decoding via libdavs2 [no] > --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394 > and libraw1394 [no] > @@ -1914,6 +1915,7 @@ EXTERNAL_LIBRARY_LIST=" > libcelt > libcodec2 > libdav1d > + liblcevc_dec > libdc1394 > libflite > libfontconfig > @@ -6854,6 +6856,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && > enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas > enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2 > enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.5.0" "dav1d/dav1d.h" dav1d_version > +enabled liblcevc_dec && require_pkg_config liblcevc_dec "lcevc_dec >= 2.0.0" "LCEVC/lcevc_dec.h" LCEVC_CreateDecoder > enabled libdavs2 && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open > enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new > enabled libdrm && check_pkg_config libdrm libdrm xf86drm.h drmGetVersion > diff --git a/doc/general_contents.texi b/doc/general_contents.texi > index e7cf4f8239..ecaf3979ce 100644 > --- a/doc/general_contents.texi > +++ b/doc/general_contents.texi > @@ -245,6 +245,19 @@ Go to @url{https://github.com/google/liblc3/} and follow the instructions for > installing the library. > Then pass @code{--enable-liblc3} to configure to enable it. > > +@section LCEVCdec > + > +FFmpeg can make use of the liblcevc_dec library for LCEVC enhacement layer > +decoding on supported bitstreams. > + > +Go to @url{https://github.com/v-novaltd/LCEVCdec} and follow the instructions > +for installing the library. Then pass @code{--enable-libvpx} to configure to ^ Should be --enable-liblcevc_dec > +enable it. > + > +@float NOTE > +LCEVCdec is under the BSD-3-Clause-Clear License. > +@end float > + > @section OpenH264 > > FFmpeg can make use of the OpenH264 library for H.264 decoding and encoding. > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index 771e2b597e..71bc3c8075 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -121,6 +121,7 @@ OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o msmpeg4_vc1_dat > OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o > OBJS-$(CONFIG_JNI) += ffjni.o jni.o > OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o > +OBJS-$(CONFIG_LIBLCEVC_DEC) += lcevcdec.o > OBJS-$(CONFIG_LCMS2) += fflcms2.o > OBJS-$(CONFIG_LLAUDDSP) += lossless_audiodsp.o > OBJS-$(CONFIG_LLVIDDSP) += lossless_videodsp.o > diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c > new file mode 100644 > index 0000000000..4edb0b72dc > --- /dev/null > +++ b/libavcodec/lcevcdec.c > @@ -0,0 +1,276 @@ > +/* > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include "libavutil/avassert.h" > +#include "libavutil/frame.h" > +#include "libavutil/imgutils.h" > +#include "libavutil/log.h" > +#include "libavutil/mem.h" > +#include "decode.h" > +#include "lcevcdec.h" > + > +static LCEVC_ColorFormat map_format(int format) > +{ > + switch (format) { > + case AV_PIX_FMT_YUV420P: > + return LCEVC_I420_8; > + case AV_PIX_FMT_YUV420P10: > + return LCEVC_I420_10_LE; > + case AV_PIX_FMT_NV12: > + return LCEVC_NV12_8; > + case AV_PIX_FMT_NV21: > + return LCEVC_NV21_8; > + case AV_PIX_FMT_GRAY8: > + return LCEVC_GRAY_8; > + } > + > + return LCEVC_ColorFormat_Unknown; > +} > + > +static int alloc_base_frame(void *logctx, LCEVC_DecoderHandle decoder, > + const AVFrame *frame, LCEVC_PictureHandle *picture) > +{ > + LCEVC_PictureDesc desc; > + LCEVC_ColorFormat fmt = map_format(frame->format); > + LCEVC_PictureLockHandle lock; > + uint8_t *data[4] = { NULL }; > + int linesizes[4] = { 0 }; > + uint32_t planes; > + LCEVC_ReturnCode res; > + > + res = LCEVC_DefaultPictureDesc(&desc, fmt, frame->width, frame->height); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + desc.cropTop = frame->crop_top; > + desc.cropBottom = frame->crop_bottom; > + desc.cropLeft = frame->crop_left; > + desc.cropRight = frame->crop_right; > + desc.sampleAspectRatioNum = frame->sample_aspect_ratio.num; > + desc.sampleAspectRatioDen = frame->sample_aspect_ratio.den; > + > + /* Allocate LCEVC Picture */ > + res = LCEVC_AllocPicture(decoder, &desc, picture); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + res = LCEVC_LockPicture(decoder, *picture, LCEVC_Access_Write, &lock); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + res = LCEVC_GetPicturePlaneCount(decoder, *picture, &planes); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + for (unsigned i = 0; i < planes; i++) { > + LCEVC_PicturePlaneDesc plane; > + > + res = LCEVC_GetPictureLockPlaneDesc(decoder, lock, i, &plane); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + data[i] = plane.firstSample; > + linesizes[i] = plane.rowByteStride; > + } > + > + av_image_copy2(data, linesizes, frame->data, frame->linesize, > + frame->format, frame->width, frame->height); > + > + res = LCEVC_UnlockPicture(decoder, lock); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + return 0; > +} > + > +static int alloc_enhanced_frame(void *logctx, LCEVC_DecoderHandle decoder, > + const AVFrame *frame, LCEVC_PictureHandle *picture) > +{ > + LCEVC_PictureDesc desc ; > + LCEVC_ColorFormat fmt = map_format(frame->format); > + LCEVC_PicturePlaneDesc planes[4] = { 0 }; > + int width = frame->width * 2 / FFMAX(frame->sample_aspect_ratio.den, 1); > + int height = frame->height * 2 / FFMAX(frame->sample_aspect_ratio.num, 1); > + LCEVC_ReturnCode res; > + > + res = LCEVC_DefaultPictureDesc(&desc, fmt, width, height); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + /* Set plane description */ > + for (int i = 0; i < 4; i++) { > + planes[i].firstSample = frame->data[i]; > + planes[i].rowByteStride = frame->linesize[i]; > + } > + > + /* Allocate LCEVC Picture */ > + res = LCEVC_AllocPictureExternal(decoder, &desc, NULL, planes, picture); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + return 0; > +} > + > +int ff_lcevc_send_frame(void *logctx, FFLCEVCContext *lcevc, const AVFrame *in) > +{ > + const AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_LCEVC); > + LCEVC_PictureHandle picture; > + LCEVC_ReturnCode res; > + int ret = 0; > + > + if (!sd) > + return 0; > + > + res = LCEVC_SendDecoderEnhancementData(lcevc->decoder, in->pts, 0, sd->data, sd->size); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + ret = alloc_base_frame(logctx, lcevc->decoder, in, &picture); > + if (ret < 0) > + return ret; > + > + res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, 0, picture, -1, NULL); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + memset(&picture, 0, sizeof(picture)); > + ret = alloc_enhanced_frame(logctx, lcevc->decoder, in, &picture); > + if (ret < 0) > + return ret; > + > + res = LCEVC_SendDecoderPicture(lcevc->decoder, picture); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + return 0; > +} > + > +static int generate_output(void *logctx, FFLCEVCContext *lcevc, AVFrame *out) > +{ > + LCEVC_PictureDesc desc; > + LCEVC_DecodeInformation info; > + LCEVC_PictureHandle picture; > + LCEVC_ReturnCode res; > + > + res = LCEVC_ReceiveDecoderPicture(lcevc->decoder, &picture, &info); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + res = LCEVC_GetPictureDesc(lcevc->decoder, picture, &desc); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + out->crop_top = desc.cropTop; > + out->crop_bottom = desc.cropBottom; > + out->crop_left = desc.cropLeft; > + out->crop_right = desc.cropRight; > + out->sample_aspect_ratio.num = desc.sampleAspectRatioNum; > + out->sample_aspect_ratio.den = desc.sampleAspectRatioDen; > + out->width = desc.width + out->crop_left + out->crop_right; > + out->height = desc.height + out->crop_top + out->crop_bottom; > + > + return 0; > +} > + > +int ff_lcevc_receive_frame(void *logctx, FFLCEVCContext *lcevc, AVFrame *out) > +{ > + LCEVC_PictureHandle picture; > + LCEVC_ReturnCode res; > + int ret; > + > + ret = generate_output(logctx, lcevc, out); > + if (ret < 0) > + return ret; > + > + res = LCEVC_ReceiveDecoderBase (lcevc->decoder, &picture); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + res = LCEVC_FreePicture(lcevc->decoder, picture); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + return 0; > +} > + > +int ff_lcevc_process(void *logctx, AVFrame *frame) > +{ > + FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data; > + AVBufferRef *ref = (AVBufferRef*)fdd->post_process_opaque; > + FFLCEVCContext *lcevc = (FFLCEVCContext*)ref->data; > + int ret; > + > + ret = ff_lcevc_send_frame(logctx, lcevc, frame); > + if (ret < 0) > + return ret; > + > + ff_lcevc_receive_frame(logctx, lcevc, frame); > + if (ret < 0) > + return ret; > + > + return 0; > +} > + > +static void event_callback(LCEVC_DecoderHandle dec, LCEVC_Event event, > + LCEVC_PictureHandle pic, const LCEVC_DecodeInformation *info, > + const uint8_t *data, uint32_t size, void *logctx) > +{ > + switch (event) { > + case LCEVC_Log: > + av_log(logctx, AV_LOG_INFO, "%s\n", data); > + break; > + default: > + break; > + } > +} > + > +int ff_lcevc_init(FFLCEVCContext *lcevc, void *logctx) > +{ > + LCEVC_AccelContextHandle dummy = { 0 }; > + > + int32_t events[] = { LCEVC_Log }; > + > + if (LCEVC_CreateDecoder(&lcevc->decoder, dummy) != LCEVC_Success) { > + av_log(logctx, AV_LOG_ERROR, "Failed to create LCEVC decoder\n"); > + return AVERROR_EXTERNAL; > + } > + > + LCEVC_ConfigureDecoderInt(lcevc->decoder, "log_level", 4); > + LCEVC_ConfigureDecoderIntArray(lcevc->decoder, "events", FF_ARRAY_ELEMS(events), events); > + LCEVC_SetDecoderEventCallback(lcevc->decoder, event_callback, logctx); > + > + if (LCEVC_InitializeDecoder(lcevc->decoder) != LCEVC_Success) { > + av_log(logctx, AV_LOG_ERROR, "Failed to initialize LCEVC decoder\n"); > + return AVERROR_EXTERNAL; > + } > + > + return 0; > +} > + > +void ff_lcevc_free(void *opaque, uint8_t *data) > +{ > + FFLCEVCContext *lcevc = opaque; > + LCEVC_DestroyDecoder(lcevc->decoder); > + av_free(data); > +} > + > +void ff_lcevc_unref(void *opaque) > +{ > + AVBufferRef *ref = opaque; > + av_buffer_unref(&ref); > +} > diff --git a/libavcodec/lcevcdec.h b/libavcodec/lcevcdec.h > new file mode 100644 > index 0000000000..fe105371d3 > --- /dev/null > +++ b/libavcodec/lcevcdec.h > @@ -0,0 +1,44 @@ > +/* > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#ifndef AVCODEC_LCEVCDEC_H > +#define AVCODEC_LCEVCDEC_H > + > +#include "config_components.h" > + > +#include > +#if CONFIG_LIBLCEVC_DEC > +#include > +#else > +typedef uintptr_t LCEVC_DecoderHandle; > +#endif > + > +typedef struct FFLCEVCContext { > + LCEVC_DecoderHandle decoder; > +} FFLCEVCContext; > + > +struct AVFrame; > + > +int ff_lcevc_process(void *logctx, struct AVFrame *frame); > +int ff_lcevc_send_frame(void *logctx, FFLCEVCContext *lcevc, const AVFrame *in); > +int ff_lcevc_receive_frame(void *logctx, FFLCEVCContext *lcevc, AVFrame *out); > +int ff_lcevc_init(FFLCEVCContext *lcevc, void *logctx); > +void ff_lcevc_unref(void *opaque); > +void ff_lcevc_free(void *opaque, uint8_t *data); > + > +#endif /* AVCODEC_LCEVCDEC_H */ _______________________________________________ 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".