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 79C984830D for ; Thu, 23 May 2024 07:09:30 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id EDDFD68D3CA; Thu, 23 May 2024 10:09:18 +0300 (EEST) Received: from out203-205-221-210.mail.qq.com (out203-205-221-210.mail.qq.com [203.205.221.210]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4838668D2B3 for ; Thu, 23 May 2024 10:09:09 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foxmail.com; s=s201512; t=1716448139; bh=5JjFKdHQT8UBsSc7YJEhW9o1xuSaJdfIUKLBMaF5kgM=; h=From:To:Cc:Subject:Date; b=X1dyf6f9ZT2HcS2ciCXz/0sHpV7i6koscF8F8aODq0eePbD37gGYORBzXm8/twLYN qX3hWroTGEGEHGfrbYSCet6smcROdJCDboQhtYOVtzFCCn65IzyFXLoFCgXR7l6wXD 0i1yXV9aj6E2UDWjfUr8bNWDopahUNxrCJrI9kBM= Received: from ZHILIZHAO-MB1.tencent.com ([119.147.10.190]) by newxmesmtplogicsvrszb9-0.qq.com (NewEsmtp) with SMTP id 23A264EF; Thu, 23 May 2024 15:08:58 +0800 X-QQ-mid: xmsmtpt1716448138t08unfzue Message-ID: X-QQ-XMAILINFO: NkBK3x0tNc75cfUNBAogeo+mMzNM4gax/EOv1Uc2zWNaMT1hJ5hhIh5xLGgb7e q90GsUIlPGPCYgVf2geGt6PSX6FdeVXg2A4WsW3LWVSuBf0d417ZOU+4RiyO5xcBFjDnszCjnb4K GPfSjY8VtWG2m6tTlNL87auQuw/kcp1q4ALGOUVI6uCgudhOEsYH7zeleFd4s883A0HD4KHKIIEj 2tPjmBmsZY64H+Ce3r1+YZxp4h4V5zukuooXprVtiFsoAif7vbyj+Bm9AGw7AF1VLYS1XWSbrM5b kKo8t/7yY/Wght7kpobC0UQEbkWzVU2jj/PGgSpK5braA1Q9KWwNwFVRY+GyxJzXEkLo/Iydrb0o Wl5rZve/dWqBU0dqwFFcknlWQimZ9hwMsPGPo1O8Fv+97M8HSbqmQDT/H/WW+EL/2oMlPa/xTZ9K LSajQR1e9A4sYKjMjz0mkSKt75MP9Ag4EZUfSacTTy/T09nb8oeinGh4T/9LJFBBO9tVI27oy+cH nYfbK4ipnjrJAyQNnQ3D4hPhMua9Uccyuon/youQrhWHYFoGZPdiF9shuVqgpiTd9ePRvMUkCHLX kHpuh7TQK9rZFs/zhUJZ1YbnpmFFRK9o1WwtGa4v0rHaU7eR/4EKrdArMuF6BtGygtJwE0J3EZQs uEaZlE86X45qXPGu9k9fOHG1ExgVEhpSEanZP2u42nWRyrnkgb3j7PC8L8FjB1xa0GVBfP4j8lor egGlqurqO7Faq4OAby71n4tGVQv1lO85c52+MnEYdmDlYSDjhKDxzfKRpU/480/cpjL0jbAEapQM AvtIwzsOdFQVbFBXY3ZfHM+eYq+5Rxje3xG82D/BfWMXuoTJHF3bAELV5ozTUlXVQZtkY4IkqGew O+85bi5uwqXi4W8WwOZSNkt278Rij433uH3maQrDuEyY01dv5ff8J84t2Oh3ppsGXtjWGo/yixgr zsrj6EJ1JMGU1p2DVJA8PC1d83Snh088f9ZDca7T2yqSaWT5PvKKDvpJc1phip X-QQ-XMRINFO: MSVp+SPm3vtS1Vd6Y4Mggwc= From: Zhao Zhili To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 May 2024 15:08:54 +0800 X-OQ-MSGID: <20240523070856.60655-1-quinkblack@foxmail.com> X-Mailer: git-send-email 2.42.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/3] avcodec/h265_metadata: Add options to set width/height after crop 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 Cc: Zhao Zhili 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: From: Zhao Zhili It's a common usecase to request a video size after crop. Before this patch, user must know the video size before crop, then set crop_right/crop_bottom accordingly. Since HEVC can have different CTU size, it's not easy to get/deduce the video size before crop. With the new width/height options, there is no such requirement. Signed-off-by: Zhao Zhili --- doc/bitstream_filters.texi | 4 ++ libavcodec/bsf/h265_metadata.c | 101 ++++++++++++++++++++++++++++++++- libavcodec/version.h | 2 +- 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi index 3d4dda04fc..c03f04f858 100644 --- a/doc/bitstream_filters.texi +++ b/doc/bitstream_filters.texi @@ -456,6 +456,10 @@ will replace the current ones if the stream is already cropped. These fields are set in pixels. Note that some sizes may not be representable if the chroma is subsampled (H.265 section 7.4.3.2.1). +@item width +@item height +Set width and height after crop. + @item level Set the level in the VPS and SPS. See H.265 section A.4 and tables A.6 and A.7. diff --git a/libavcodec/bsf/h265_metadata.c b/libavcodec/bsf/h265_metadata.c index c9e1cc3eed..eba00c20d5 100644 --- a/libavcodec/bsf/h265_metadata.c +++ b/libavcodec/bsf/h265_metadata.c @@ -58,6 +58,8 @@ typedef struct H265MetadataContext { int crop_right; int crop_top; int crop_bottom; + int width; + int height; int level; int level_guess; @@ -187,12 +189,94 @@ static int h265_metadata_update_vps(AVBSFContext *bsf, return 0; } +static int h265_metadata_deduce_crop(AVBSFContext *bsf, const H265RawSPS *sps, + int *crop_left, int *crop_right, + int *crop_top, int *crop_bottom) +{ + const H265MetadataContext *ctx = bsf->priv_data; + int left = ctx->crop_left; + int right = ctx->crop_right; + int top = ctx->crop_top; + int bottom = ctx->crop_bottom; + + if (ctx->width > 0) { + if (ctx->width > sps->pic_width_in_luma_samples) { + av_log(bsf, AV_LOG_ERROR, + "The width option value %d is larger than picture width %d\n", + ctx->width, sps->pic_width_in_luma_samples); + return AVERROR(EINVAL); + } + + if (left < 0) { + if (right > 0) + left = sps->pic_width_in_luma_samples - ctx->width - right; + else + left = 0; + } + + if (right < 0) + right = sps->pic_width_in_luma_samples - ctx->width - left; + + if (left < 0 || right < 0 || (left + right + ctx->width) != + sps->pic_width_in_luma_samples) { + av_log(bsf, AV_LOG_ERROR, + "Invalid value for crop_left %d, crop_right %d, width after " + "crop %d, with picture width %d\n", + ctx->crop_left, ctx->crop_right, ctx->width, + sps->pic_width_in_luma_samples); + return AVERROR(EINVAL); + } + } + + if (ctx->height > 0) { + if (ctx->height > sps->pic_height_in_luma_samples) { + av_log(bsf, AV_LOG_ERROR, + "The height option value %d is larger than picture height %d\n", + ctx->height, sps->pic_height_in_luma_samples); + return AVERROR(EINVAL); + } + + if (top < 0) { + if (bottom > 0) + top = sps->pic_height_in_luma_samples - ctx->height - bottom; + else + top = 0; + } + + if (bottom < 0) + bottom = sps->pic_height_in_luma_samples - ctx->height - top; + + if (top < 0 || bottom < 0 || (top + bottom + ctx->height) != + sps->pic_height_in_luma_samples) { + av_log(bsf, AV_LOG_ERROR, + "Invalid value for crop_top %d, crop_bottom %d, height after " + "crop %d, with picture height %d\n", + ctx->crop_top, ctx->crop_bottom, ctx->height, + sps->pic_height_in_luma_samples); + return AVERROR(EINVAL); + } + } + + *crop_left = left; + *crop_right = right; + *crop_top = top; + *crop_bottom = bottom; + + return 0; +} + static int h265_metadata_update_sps(AVBSFContext *bsf, H265RawSPS *sps) { H265MetadataContext *ctx = bsf->priv_data; int need_vui = 0; int crop_unit_x, crop_unit_y; + /* Use local variables to avoid modifying context fields in case of video + * resolution changed. Crop doesn't work well with resolution change, this + * is the best we can do. + */ + int crop_left, crop_right, crop_top, crop_bottom; + int ret; if (ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) { int num, den, i; @@ -289,6 +373,11 @@ static int h265_metadata_update_sps(AVBSFContext *bsf, } } + ret = h265_metadata_deduce_crop(bsf, sps, &crop_left, &crop_right, + &crop_top, &crop_bottom); + if (ret < 0) + return ret; + if (sps->separate_colour_plane_flag || sps->chroma_format_idc == 0) { crop_unit_x = 1; crop_unit_y = 1; @@ -297,14 +386,14 @@ static int h265_metadata_update_sps(AVBSFContext *bsf, crop_unit_y = 1 + (sps->chroma_format_idc < 2); } #define CROP(border, unit) do { \ - if (ctx->crop_ ## border >= 0) { \ - if (ctx->crop_ ## border % unit != 0) { \ + if (crop_ ## border >= 0) { \ + if (crop_ ## border % unit != 0) { \ av_log(bsf, AV_LOG_ERROR, "Invalid value for crop_%s: " \ "must be a multiple of %d.\n", #border, unit); \ return AVERROR(EINVAL); \ } \ sps->conf_win_ ## border ## _offset = \ - ctx->crop_ ## border / unit; \ + crop_ ## border / unit; \ sps->conformance_window_flag = 1; \ } \ } while (0) @@ -453,6 +542,12 @@ static const AVOption h265_metadata_options[] = { { "crop_bottom", "Set bottom border crop offset", OFFSET(crop_bottom), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, HEVC_MAX_HEIGHT, FLAGS }, + { "width", "Set width after crop", + OFFSET(width), AV_OPT_TYPE_INT, + { .i64 = -1 }, -1, HEVC_MAX_WIDTH, FLAGS }, + { "height", "Set height after crop", + OFFSET(height), AV_OPT_TYPE_INT, + { .i64 = -1 }, -1, HEVC_MAX_HEIGHT, FLAGS }, { "level", "Set level (tables A.6 and A.7)", OFFSET(level), AV_OPT_TYPE_INT, diff --git a/libavcodec/version.h b/libavcodec/version.h index 3d2de546b3..f9b09b4b25 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -30,7 +30,7 @@ #include "version_major.h" #define LIBAVCODEC_VERSION_MINOR 5 -#define LIBAVCODEC_VERSION_MICRO 104 +#define LIBAVCODEC_VERSION_MICRO 105 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- 2.42.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-request@ffmpeg.org with subject "unsubscribe".