From patchwork Thu Mar 28 11:11:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gnattu X-Patchwork-Id: 47579 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:9f96:b0:1a3:b6bb:3029 with SMTP id mm22csp1238805pzb; Thu, 28 Mar 2024 04:12:24 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUd1NvFVZ12Jb6Yfj2YMc/dv+tY1PokQ3BXHit9p78f6kusRciv/lhNOirwSCG2abBY5AzDkiBTGiV2QNfkyy+B/X3F74rhSTgUsg== X-Google-Smtp-Source: AGHT+IEb7ae7Zzblkx/EzSz/exG3/j/SLzQ1PnkxEhxZHOHVkhdqhntKSEJbtIwV8RCAaVtd0AP1 X-Received: by 2002:a05:6512:3493:b0:513:e21:2a64 with SMTP id v19-20020a056512349300b005130e212a64mr1331390lfr.31.1711624344036; Thu, 28 Mar 2024 04:12:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1711624344; cv=none; d=google.com; s=arc-20160816; b=Fb4Zya8djR0yQvU85cB9gVGkL3Bt3Fg58j+74716p3gZp1pHrtMohmNqkDW1mnbCc5 6tDI15PGLvKjMHpB/bkR1Kl9tiNcomjSHOXl1RINov9v36jc8csLNVKjnxnKSbuOd3em WHnJgFAa8SKHmojxpWLgSGDy8ohlDgNG+jFTtweAxtM4wmaLMiv+ezeXy5jvD+7Pg1Ng /40hLfybFUz9Y+4kFkHNKtEqHtIJ5YRcDlmKEK8tfxAU/TDAFg+okDkFabaOOVTWEIm2 zgKISrEYEm5iavRrLUVN/JTVDuen2HkIYy4SyNECxKZwoUe4wNLlszd/vImtzrdJqm1w Sgzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to:from :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to :delivered-to; bh=9CeAj9l8PDhMz8o90LuIJxWva5VgzFYIGyloqLbsEFA=; fh=2gWgGvVN03792RqC4MXCXsB/4cbAJUKJ5Jr7thIsQ3A=; b=boKckJncyWpuPITGF9W7RuwAu1+jyBE+JrKXQvnBOJdx6AO/zI6igDzfw9HE37bcze qtZBnXoxNjm0z9Ub2xELvQY8GNdnZ+thAWnTM6GpOnZZe8wx/Vo5coiidLrJqZauPQAU XHqLnzXXE5g1tcGuooHKMDbQFmu1dKVkfSb6R6xuGFqi1ndRIOaiM/neyqZfpE6sTQpK 95skWVnT5W5NQdJ7q4ULq/oBZ2RBF6RVw1/XPRdFQKu44EuSx/K5qisxtQi+dAMOuABg 5Xt7Xo6NDPZMNA1vky8jTwdNxVZ23kDM0isdkUS8aBVAd9isZj7yWW0GKy1oxW/sYXNY OUow==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id y94-20020a50bb67000000b0056c1a46a4afsi664894ede.382.2024.03.28.04.12.23; Thu, 28 Mar 2024 04:12:24 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9C70668D671; Thu, 28 Mar 2024 13:12:20 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mr85p00im-ztdg06021201.me.com (mr85p00im-ztdg06021201.me.com [17.58.23.189]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3287868D4EF for ; Thu, 28 Mar 2024 13:12:14 +0200 (EET) Received: from Yakumo-Yukari.lan (mr38p00im-dlb-asmtp-mailmevip.me.com [17.57.152.18]) by mr85p00im-ztdg06021201.me.com (Postfix) with ESMTPSA id F25D832067C; Thu, 28 Mar 2024 11:12:10 +0000 (UTC) To: ffmpeg-devel@ffmpeg.org Date: Thu, 28 Mar 2024 19:11:33 +0800 Message-Id: <20240328111132.34419-1-gnattuoc@me.com> X-Mailer: git-send-email 2.39.3 (Apple Git-146) MIME-Version: 1.0 X-Proofpoint-GUID: bUj2q4jIQ46WIpD_YsEW5JDBDeihCW-F X-Proofpoint-ORIG-GUID: bUj2q4jIQ46WIpD_YsEW5JDBDeihCW-F X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-03-28_11,2024-03-27_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 suspectscore=0 adultscore=0 malwarescore=0 spamscore=0 mlxscore=0 clxscore=1015 phishscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2308100000 definitions=main-2403280075 Subject: [FFmpeg-devel] [PATCH] lavc/videotoolboxenc: add MJPEG support 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: , X-Patchwork-Original-From: gnattu via ffmpeg-devel From: gnattu Reply-To: FFmpeg development discussions and patches Cc: gnattu Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 7VK4rABthI+Y For example: ./ffmpeg -hwaccel videotoolbox\ -i INPUT -c:v mjpeg_videotoolbox\ out.mp4 This encoder does not have many options and can only use ``-q:v` to control quality. Signed-off-by: Gnattu OC --- Changelog | 1 + configure | 2 ++ libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/videotoolboxenc.c | 39 +++++++++++++++++++++++++++++++++--- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index e83a00e35c..b73a44f9ad 100644 --- a/Changelog +++ b/Changelog @@ -38,6 +38,7 @@ version 7.0: - ffplay with hwaccel decoding support (depends on vulkan renderer via libplacebo) - dnn filter libtorch backend - Android content URIs protocol +- VideoToolbox MJPEG encoder version 6.1: diff --git a/configure b/configure index 2a1d22310b..52a0ee762f 100755 --- a/configure +++ b/configure @@ -3474,6 +3474,8 @@ hevc_videotoolbox_encoder_deps="pthreads" hevc_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder" prores_videotoolbox_encoder_deps="pthreads" prores_videotoolbox_encoder_select="videotoolbox_encoder" +mjpeg_videotoolbox_encoder_deps="pthreads" +mjpeg_videotoolbox_encoder_select="videotoolbox_encoder" libaom_av1_decoder_deps="libaom" libaom_av1_encoder_deps="libaom" libaom_av1_encoder_select="extract_extradata_bsf" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 9ce6d445c1..f59b2ae691 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -503,6 +503,7 @@ OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o OBJS-$(CONFIG_MJPEG_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_MJPEG_QSV_ENCODER) += qsvenc_jpeg.o OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o +OBJS-$(CONFIG_MJPEG_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o mlp.o OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 2386b450a6..f8a90fdca2 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -879,6 +879,7 @@ extern const FFCodec ff_mpeg4_mediacodec_encoder; extern const FFCodec ff_mpeg4_omx_encoder; extern const FFCodec ff_mpeg4_v4l2m2m_encoder; extern const FFCodec ff_prores_videotoolbox_encoder; +extern const FFCodec ff_mjpeg_videotoolbox_encoder; extern const FFCodec ff_vc1_cuvid_decoder; extern const FFCodec ff_vp8_cuvid_decoder; extern const FFCodec ff_vp8_mediacodec_decoder; diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index 15c34d59c3..0574edab56 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -547,6 +547,7 @@ static CMVideoCodecType get_cm_codec_type(AVCodecContext *avctx, else return MKBETAG('a','p','c','n'); // kCMVideoCodecType_AppleProRes422 } + case AV_CODEC_ID_MJPEG: return kCMVideoCodecType_JPEG; default: return 0; } } @@ -1233,7 +1234,7 @@ static int vtenc_create_encoder(AVCodecContext *avctx, kVTCompressionPropertyKey_Quality, quality_num); CFRelease(quality_num); - } else if (avctx->codec_id != AV_CODEC_ID_PRORES) { + } else if (avctx->codec_id != AV_CODEC_ID_PRORES && avctx->codec_id != AV_CODEC_ID_MJPEG) { bit_rate_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bit_rate); @@ -1347,7 +1348,7 @@ static int vtenc_create_encoder(AVCodecContext *avctx, } } - if (avctx->gop_size > 0 && avctx->codec_id != AV_CODEC_ID_PRORES) { + if (avctx->gop_size > 0 && avctx->codec_id != AV_CODEC_ID_PRORES && avctx->codec_id != AV_CODEC_ID_MJPEG) { CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &avctx->gop_size); @@ -1496,7 +1497,7 @@ static int vtenc_create_encoder(AVCodecContext *avctx, } } - if (!vtctx->has_b_frames && avctx->codec_id != AV_CODEC_ID_PRORES) { + if (!vtctx->has_b_frames && avctx->codec_id != AV_CODEC_ID_PRORES && avctx->codec_id != AV_CODEC_ID_MJPEG) { status = VTSessionSetProperty(vtctx->session, kVTCompressionPropertyKey_AllowFrameReordering, kCFBooleanFalse); @@ -2844,6 +2845,13 @@ static const enum AVPixelFormat prores_pix_fmts[] = { AV_PIX_FMT_NONE }; +static const enum AVPixelFormat mjpeg_pix_fmts[] = { + AV_PIX_FMT_VIDEOTOOLBOX, + AV_PIX_FMT_NV12, + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE +}; + #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM #define COMMON_OPTIONS \ { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \ @@ -3004,3 +3012,28 @@ const FFCodec ff_prores_videotoolbox_encoder = { .p.wrapper_name = "videotoolbox", .hw_configs = vt_encode_hw_configs, }; + +static const AVClass mjpeg_videotoolbox_class = { + .class_name = "mjpeg_videotoolbox", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, +}; + +const FFCodec ff_mjpeg_videotoolbox_encoder = { + .p.name = "mjpeg_videotoolbox", + CODEC_LONG_NAME("VideoToolbox MJPEG Encoder"), + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_MJPEG, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | + AV_CODEC_CAP_HARDWARE, + .priv_data_size = sizeof(VTEncContext), + .p.pix_fmts = prores_pix_fmts, + .init = vtenc_init, + FF_CODEC_ENCODE_CB(vtenc_frame), + .close = vtenc_close, + .p.priv_class = &mjpeg_videotoolbox_class, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .p.wrapper_name = "videotoolbox", + .hw_configs = vt_encode_hw_configs, +};