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 496974A785 for ; Mon, 6 May 2024 18:47:29 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8A63368D6A7; Mon, 6 May 2024 21:47:18 +0300 (EEST) Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7991B68D64B for ; Mon, 6 May 2024 21:47:10 +0300 (EEST) Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-41e82b78387so16024975e9.0 for ; Mon, 06 May 2024 11:47:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20230601.gappssmtp.com; s=20230601; t=1715021230; x=1715626030; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=pWv1kT6FJuVFb+PVp3xrg8CgFiTWBdBNDW1dIRBgaGw=; b=BIXYoxb4erp3k+wNDyvX9sVlxDH611dI04buwpFBHwNaJBnrxa7BMtwUAtRP3qbm8q QeH3M6Xn9RXYR/Xnvl+lob3zoZRmTfkIndqL0dbGVOHPgodb9UfexiJBHnE/d+MAW15C MBQjasqwi7U2KAiX/uLDjNk+drDoKJlFtw2YtfjoL8tfMTQQtcp7dmUACx1ui+wckmWO itJ8WE5d9QQ1ZCJtbl/MLyD5kcDS7+/DKlDn1wUz9Rhk+3KtVuvceBJsKmERMgahpEyH 43j47JrQqQ+nKBAAtwD9U1F6i6+YTcgDQsP/kRAosnNpM7CNywi3EplyFpC7xDxe6QXX O+Cw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715021230; x=1715626030; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pWv1kT6FJuVFb+PVp3xrg8CgFiTWBdBNDW1dIRBgaGw=; b=WOfETaX80ZMXQxJxPc/ybESrhyW0g3fbkbY3O+59JSgxgGS4TFRhy/yIc1drOjKYAj 7+buauYZR/NMkC6z6QLPEHN/0p3acfm6K3LOmgtBKbYmcds/kLbjqvmIq80rFetIi5ax G1QdWvvDdpGDGZbuZZeunMdibisjdZ96GHIYzYcDx71ygOg+iF7wno8jcRJDuaSDY5LI NwJgw2+DKkRLhnICf8BI3nUjgeKGlJQ1c5nE2etiNsPyKnMCTugIK9v9SQC+x+3U/hIf 4E1Rjh0+Bi1M5VCl1/sFmpAjS7M2NAat3KX6pbuYQ1ZIKilgLZjd5ykku5f6jALMlI1n Znbw== X-Gm-Message-State: AOJu0Yz9s7BDumFk8bpyQ+PI2bUQopn9UJxtE/CRyxXs9xTsRD/ftfrP JZZF0ge+38REXQSrWdkTdWpZIP3wmDEwm1QzQHf3IxzbVy5YrmQirSUbdkDepPn45DyQ/gZJRFE A X-Google-Smtp-Source: AGHT+IFjwtoAuW+nFapXEAhlUelq+Pm36fgHM/zyEBzvMz3EZCKwgpAWSOe34IA2tv+RGgU3RvTVIw== X-Received: by 2002:a05:600c:45cc:b0:41b:e416:43d3 with SMTP id s12-20020a05600c45cc00b0041be41643d3mr8302171wmo.35.1715021229391; Mon, 06 May 2024 11:47:09 -0700 (PDT) Received: from localhost.localdomain (cpc92302-cmbg19-2-0-cust1183.5-4.cable.virginm.net. [82.1.212.160]) by smtp.gmail.com with ESMTPSA id n20-20020a05600c501400b0041aa79f27a0sm16987184wmr.38.2024.05.06.11.47.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 11:47:09 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Mon, 6 May 2024 19:47:20 +0100 Message-ID: <20240506184726.826159-2-sw@jkqxz.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240506184726.826159-1-sw@jkqxz.net> References: <20240506184726.826159-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 2/3] lavc: Add test for H.265 profile handling 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: --- libavcodec/Makefile | 2 +- libavcodec/tests/.gitignore | 1 + libavcodec/tests/h265_profiles.c | 440 +++++++++++++++++++++++++++++++ tests/fate/libavcodec.mak | 5 + 4 files changed, 447 insertions(+), 1 deletion(-) create mode 100644 libavcodec/tests/h265_profiles.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index cff6347bdb..15e38ded28 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1307,7 +1307,7 @@ TESTPROGS-$(CONFIG_MJPEG_ENCODER) += mjpegenc_huffman TESTPROGS-$(HAVE_MMX) += motion TESTPROGS-$(CONFIG_MPEGVIDEO) += mpeg12framerate TESTPROGS-$(CONFIG_H264_METADATA_BSF) += h264_levels -TESTPROGS-$(CONFIG_HEVC_METADATA_BSF) += h265_levels +TESTPROGS-$(CONFIG_HEVC_METADATA_BSF) += h265_levels h265_profiles TESTPROGS-$(CONFIG_RANGECODER) += rangecoder TESTPROGS-$(CONFIG_SNOW_ENCODER) += snowenc diff --git a/libavcodec/tests/.gitignore b/libavcodec/tests/.gitignore index 0df4ae10a0..bf29f03911 100644 --- a/libavcodec/tests/.gitignore +++ b/libavcodec/tests/.gitignore @@ -10,6 +10,7 @@ /golomb /h264_levels /h265_levels +/h265_profiles /htmlsubtitles /iirfilter /jpeg2000dwt diff --git a/libavcodec/tests/h265_profiles.c b/libavcodec/tests/h265_profiles.c new file mode 100644 index 0000000000..6a0df58d0b --- /dev/null +++ b/libavcodec/tests/h265_profiles.c @@ -0,0 +1,440 @@ +/* + * 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/bprint.h" +#include "libavutil/common.h" +#include "libavcodec/h265_profile_level.h" + + +enum { + TYPE_MAIN, + TYPE_SP, + TYPE_REXT_INTER, + TYPE_REXT_INTRA, + TYPE_HT, + TYPE_HT_INTRA, + TYPE_SCC, + TYPE_HT_SCC, + TYPE_COUNT, +}; +enum { + DEPTH_8, + DEPTH_10, + DEPTH_12, + DEPTH_14, + DEPTH_16, + DEPTH_COUNT, +}; +enum { + CHROMA_MONO, + CHROMA_420, + CHROMA_422, + CHROMA_444, + CHROMA_COUNT, +}; + +// Table of all profiles indexed by chroma subsampling, bit depth and +// profile type. This is currently only being used to verify that +// profile properties are correct, but if there is some other need for +// this lookup in lavc then the table should be moved to the common +// profile-level code. All profiles should appear exactly once in this +// table (also verified by a test below). +static int profile_table[CHROMA_COUNT][DEPTH_COUNT][TYPE_COUNT] = { + [CHROMA_MONO] = { + [DEPTH_8] = { + [TYPE_REXT_INTER] = H265_PROFILE_MONOCHROME, + }, + [DEPTH_10] = { + [TYPE_REXT_INTER] = H265_PROFILE_MONOCHROME_10, + }, + [DEPTH_12] = { + [TYPE_REXT_INTER] = H265_PROFILE_MONOCHROME_12, + }, + [DEPTH_16] = { + [TYPE_REXT_INTER] = H265_PROFILE_MONOCHROME_16, + }, + }, + [CHROMA_420] = { + [DEPTH_8] = { + [TYPE_MAIN] = H265_PROFILE_MAIN, + [TYPE_SP] = H265_PROFILE_MAIN_STILL_PICTURE, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_INTRA, + [TYPE_SCC] = H265_PROFILE_SCREEN_EXTENDED_MAIN, + }, + [DEPTH_10] = { + [TYPE_MAIN] = H265_PROFILE_MAIN_10, + [TYPE_SP] = H265_PROFILE_MAIN_10_STILL_PICTURE, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_10_INTRA, + [TYPE_SCC] = H265_PROFILE_SCREEN_EXTENDED_MAIN_10, + }, + [DEPTH_12] = { + [TYPE_REXT_INTER] = H265_PROFILE_MAIN_12, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_12_INTRA, + }, + }, + [CHROMA_422] ={ + [DEPTH_10] = { + [TYPE_REXT_INTER] = H265_PROFILE_MAIN_422_10, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_422_10_INTRA, + }, + [DEPTH_12] = { + [TYPE_REXT_INTER] = H265_PROFILE_MAIN_422_12, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_422_12_INTRA, + }, + }, + [CHROMA_444] ={ + [DEPTH_8] = { + [TYPE_SP] = H265_PROFILE_MAIN_444_STILL_PICTURE, + [TYPE_REXT_INTER] = H265_PROFILE_MAIN_444, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_444_INTRA, + [TYPE_HT] = H265_PROFILE_HIGH_THROUGHPUT_444, + [TYPE_SCC] = H265_PROFILE_SCREEN_EXTENDED_MAIN_444, + [TYPE_HT_SCC] = H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444, + }, + [DEPTH_10] = { + [TYPE_REXT_INTER] = H265_PROFILE_MAIN_444_10, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_444_10_INTRA, + [TYPE_HT] = H265_PROFILE_HIGH_THROUGHPUT_444_10, + [TYPE_SCC] = H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10, + [TYPE_HT_SCC] = H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10, + }, + [DEPTH_12] = { + [TYPE_REXT_INTER] = H265_PROFILE_MAIN_444_12, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_444_12_INTRA, + }, + [DEPTH_14] = { + [TYPE_HT] = H265_PROFILE_HIGH_THROUGHPUT_444_14, + [TYPE_HT_SCC] = H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14, + }, + [DEPTH_16] = { + [TYPE_SP] = H265_PROFILE_MAIN_444_16_STILL_PICTURE, + [TYPE_REXT_INTRA] = H265_PROFILE_MAIN_444_16_INTRA, + [TYPE_HT_INTRA] = H265_PROFILE_HIGH_THROUGHPUT_444_16_INTRA, + }, + }, +}; + +static int check_flags(const H265ProfileDescriptor *desc, + int chroma, int depth) +{ + int errors = 0; + if (chroma > CHROMA_MONO && desc->max_monochrome == 1) { + av_log(NULL, AV_LOG_ERROR, "%s requires monochrome.\n", + desc->name); + ++errors; + } + if (chroma > CHROMA_422 && desc->max_420chroma == 1) { + av_log(NULL, AV_LOG_ERROR, "%s requires 4:2:0.\n", + desc->name); + ++errors; + } + if (chroma > CHROMA_444 && desc->max_422chroma == 1) { + av_log(NULL, AV_LOG_ERROR, "%s requires 4:2:2.\n", + desc->name); + ++errors; + } + if (depth > DEPTH_8 && desc->max_8bit == 1) { + av_log(NULL, AV_LOG_ERROR, "%s requires 8-bit.\n", + desc->name); + ++errors; + } + if (depth > DEPTH_10 && desc->max_10bit == 1) { + av_log(NULL, AV_LOG_ERROR, "%s requires 10-bit.\n", + desc->name); + ++errors; + } + if (depth > DEPTH_12 && desc->max_12bit == 1) { + av_log(NULL, AV_LOG_ERROR, "%s requires 12-bit.\n", + desc->name); + ++errors; + } + if (depth > DEPTH_14 && desc->max_14bit == 1) { + av_log(NULL, AV_LOG_ERROR, "%s requires 14-bit.\n", + desc->name); + ++errors; + } + return errors; +} + +static int check_profile_table(void) +{ + // Ensure that the profile table contains every non-still-picture + // profile exactly once, and that a profile for a given chroma mode + // and depth actually supports that chroma mode and depth. + int errors = 0; + + for (int p = H265_PROFILE_MONOCHROME; p < H265_PROFILE_COUNT; p++) { + const H265ProfileDescriptor *desc = ff_h265_get_profile(p); + int found = 0; + + for (int type= 0; type < TYPE_COUNT; type++) { + for (int chroma = 0; chroma < CHROMA_COUNT; chroma++) { + for (int depth = 0; depth < DEPTH_COUNT; depth++) { + if (profile_table[chroma][depth][type] == p) { + ++found; + errors += check_flags(desc, chroma, depth); + } + } + } + } + + if (found != 1) { + av_log(NULL, AV_LOG_ERROR, + "%s appears %d times in the profile table.\n", + desc->name, found); + + ++errors; + } + } + return errors; +} + +static int get_profile(int type, int chroma, int depth) +{ + av_assert0(type >= 0 && type < TYPE_COUNT); + av_assert0(chroma >= 0 && chroma < CHROMA_COUNT); + av_assert0(depth >= 0 && depth < DEPTH_COUNT); + return profile_table[chroma][depth][type]; +} + +static void minimal_ptl_from_desc(H265RawProfileTierLevel *ptl, + const H265ProfileDescriptor *desc) +{ + *ptl = (H265RawProfileTierLevel) { + .general_profile_space = 0, + .general_profile_idc = desc->profile_idc, + // Tier/interlace/stereo/layering/level flags are ignored in + // this test. + }; + + ptl->general_profile_compatibility_flag[desc->profile_idc] = 1; + +#define FLAG(name) do { \ + ptl->general_ ## name ## _constraint_flag = desc->name; \ + } while (0) + + FLAG(max_14bit); + FLAG(max_12bit); + FLAG(max_10bit); + FLAG(max_8bit); + FLAG(max_422chroma); + FLAG(max_420chroma); + FLAG(max_monochrome); + FLAG(intra); + FLAG(one_picture_only); + FLAG(lower_bit_rate); + +#undef FLAG +} + +static void bprint_ptl(AVBPrint *buf, const H265RawProfileTierLevel *ptl) +{ + av_bprintf(buf, "profile_space %d tier %d profile_idc %d", + ptl->general_profile_space, + ptl->general_tier_flag, + ptl->general_profile_idc); + + av_bprintf(buf, " profile_compatibility { "); + for (int i = 0; i < 32; i++) + av_bprintf(buf, "%d", + ptl->general_profile_compatibility_flag[i]); + av_bprintf(buf, " }"); + + av_bprintf(buf, " progressive %d interlaced %d", + ptl->general_progressive_source_flag, + ptl->general_interlaced_source_flag); + av_bprintf(buf, " non_packed %d frame_only %d", + ptl->general_non_packed_constraint_flag, + ptl->general_frame_only_constraint_flag); + +#define profile_compatible(x) (ptl->general_profile_idc == (x) || \ + ptl->general_profile_compatibility_flag[x]) + if (profile_compatible(4) || profile_compatible(5) || + profile_compatible(6) || profile_compatible(7) || + profile_compatible(8) || profile_compatible(9) || + profile_compatible(10) || profile_compatible(11)) { + + av_bprintf(buf, " 12bit %d", ptl->general_max_12bit_constraint_flag); + av_bprintf(buf, " 10bit %d", ptl->general_max_10bit_constraint_flag); + av_bprintf(buf, " 8bit %d", ptl->general_max_8bit_constraint_flag); + av_bprintf(buf, " 422chroma %d", ptl->general_max_422chroma_constraint_flag); + av_bprintf(buf, " 420chroma %d", ptl->general_max_420chroma_constraint_flag); + av_bprintf(buf, " monochrome %d", ptl->general_max_monochrome_constraint_flag); + av_bprintf(buf, " intra %d", ptl->general_intra_constraint_flag); + av_bprintf(buf, " one_picture %d", ptl->general_one_picture_only_constraint_flag); + av_bprintf(buf, " lower_bit_rate %d", ptl->general_lower_bit_rate_constraint_flag); + + if (profile_compatible(5) || profile_compatible(9) || + profile_compatible(10) || profile_compatible(11)) { + av_bprintf(buf, " 14bit %d", ptl->general_max_14bit_constraint_flag); + } + + if (profile_compatible(1) || profile_compatible(2) || + profile_compatible(3) || profile_compatible(4) || + profile_compatible(5) || profile_compatible(9) || + profile_compatible(11)) { + av_bprintf(buf, " inbld %d", ptl->general_inbld_flag); + } + } +#undef profile_compatible + + av_bprintf(buf, " level %d", ptl->general_level_idc); +} + + +#define CHECK_COMPATIBILITY(expected, ptl, profile) do { \ + if (expected == !ff_h265_profile_compatible(ptl, profile)) { \ + AVBPrint buf; \ + char *str; \ + const H265ProfileDescriptor *desc = \ + ff_h265_get_profile(profile); \ + av_log(NULL, AV_LOG_ERROR, expected ? \ + "Incorrectly incompatible with %s:\n" : \ + "Incorrectly compatible with %s:\n", \ + desc->name); \ + av_bprint_init(&buf, 1024, -1); \ + bprint_ptl(&buf, ptl); \ + av_bprint_finalize(&buf, &str); \ + av_log(NULL, AV_LOG_ERROR, "%s\n", str); \ + return 1; \ + } \ + } while (0) + +static int check_simple_rext_profiles(void) +{ + static const H265RawProfileTierLevel rext_420_8 = { + .general_profile_space = 0, + .general_profile_idc = 4, + .general_tier_flag = 0, + .general_profile_compatibility_flag[4] = 1, + .general_max_12bit_constraint_flag = 1, + .general_max_10bit_constraint_flag = 1, + .general_max_8bit_constraint_flag = 1, + .general_max_422chroma_constraint_flag = 1, + .general_max_420chroma_constraint_flag = 1, + .general_max_monochrome_constraint_flag = 0, + .general_intra_constraint_flag = 0, + .general_one_picture_only_constraint_flag = 0, + .general_lower_bit_rate_constraint_flag = 1, + }; + static const H265RawProfileTierLevel rext_420_10 = { + .general_profile_space = 0, + .general_profile_idc = 4, + .general_tier_flag = 0, + .general_profile_compatibility_flag[4] = 1, + .general_max_12bit_constraint_flag = 1, + .general_max_10bit_constraint_flag = 1, + .general_max_8bit_constraint_flag = 0, + .general_max_422chroma_constraint_flag = 1, + .general_max_420chroma_constraint_flag = 1, + .general_max_monochrome_constraint_flag = 0, + .general_intra_constraint_flag = 0, + .general_one_picture_only_constraint_flag = 0, + .general_lower_bit_rate_constraint_flag = 1, + }; + static const H265RawProfileTierLevel rext_422_8 = { + .general_profile_space = 0, + .general_profile_idc = 4, + .general_tier_flag = 0, + .general_profile_compatibility_flag[4] = 1, + .general_max_12bit_constraint_flag = 1, + .general_max_10bit_constraint_flag = 1, + .general_max_8bit_constraint_flag = 1, + .general_max_422chroma_constraint_flag = 1, + .general_max_420chroma_constraint_flag = 0, + .general_max_monochrome_constraint_flag = 0, + .general_intra_constraint_flag = 0, + .general_one_picture_only_constraint_flag = 0, + .general_lower_bit_rate_constraint_flag = 1, + }; + + CHECK_COMPATIBILITY(0, &rext_420_8, H265_PROFILE_MAIN); + CHECK_COMPATIBILITY(0, &rext_420_8, H265_PROFILE_MAIN_10); + CHECK_COMPATIBILITY(1, &rext_420_8, H265_PROFILE_MAIN_12); + CHECK_COMPATIBILITY(1, &rext_420_8, H265_PROFILE_MAIN_422_10); + CHECK_COMPATIBILITY(1, &rext_420_8, H265_PROFILE_MAIN_444); + CHECK_COMPATIBILITY(1, &rext_420_8, H265_PROFILE_MAIN_444_10); + + CHECK_COMPATIBILITY(0, &rext_420_10, H265_PROFILE_MAIN); + CHECK_COMPATIBILITY(0, &rext_420_10, H265_PROFILE_MAIN_10); + CHECK_COMPATIBILITY(1, &rext_420_10, H265_PROFILE_MAIN_12); + CHECK_COMPATIBILITY(1, &rext_420_10, H265_PROFILE_MAIN_422_10); + CHECK_COMPATIBILITY(0, &rext_420_10, H265_PROFILE_MAIN_444); + CHECK_COMPATIBILITY(1, &rext_420_10, H265_PROFILE_MAIN_444_10); + + CHECK_COMPATIBILITY(0, &rext_422_8, H265_PROFILE_MAIN); + CHECK_COMPATIBILITY(0, &rext_422_8, H265_PROFILE_MAIN_10); + CHECK_COMPATIBILITY(0, &rext_422_8, H265_PROFILE_MAIN_12); + CHECK_COMPATIBILITY(1, &rext_422_8, H265_PROFILE_MAIN_422_10); + CHECK_COMPATIBILITY(1, &rext_422_8, H265_PROFILE_MAIN_444); + CHECK_COMPATIBILITY(1, &rext_422_8, H265_PROFILE_MAIN_444_10); + + return 0; +} + +int main(void) +{ + if (check_profile_table()) + return 1; + + if (check_simple_rext_profiles()) + return 1; + + // Check compatibility pairs between all profiles of the same type. + // Profile A should be compatibile with a profile B which supports + // at least the same chroma subsampling and at least the same depth + // (including if A and B are the same). + for (int type = TYPE_REXT_INTER; type < TYPE_COUNT; type++) { + for (int chroma_a = 0; chroma_a < CHROMA_COUNT; chroma_a++) { + for (int depth_a = 0; depth_a < DEPTH_COUNT; depth_a++) { + int profile_a; + const H265ProfileDescriptor *desc_a; + H265RawProfileTierLevel ptl_a; + + profile_a = get_profile(type, chroma_a, depth_a); + if (profile_a == H265_PROFILE_INVALID) + continue; + desc_a = ff_h265_get_profile(profile_a); + minimal_ptl_from_desc(&ptl_a, desc_a); + + for (int chroma_b = 0; chroma_b < CHROMA_COUNT; chroma_b++) { + for (int depth_b = 0; depth_b < DEPTH_COUNT; depth_b++) { + int profile_b; + const H265ProfileDescriptor *desc_b; + int expect_compatible = (depth_b >= depth_a && + chroma_b >= chroma_a); + + profile_b = get_profile(type, chroma_b, depth_b); + if (profile_b == H265_PROFILE_INVALID) + continue; + desc_b = ff_h265_get_profile(profile_b); + + av_log(NULL, AV_LOG_INFO, + "%d: A (%s: %d,%d) B (%s: %d,%d)\n", type, + desc_a->name, chroma_a, depth_a, + desc_b->name, chroma_b, depth_b); + CHECK_COMPATIBILITY(expect_compatible, + &ptl_a, profile_b); + } + } + } + } + } + + return 0; +} diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak index 1a5694fa5f..a47e8b8237 100644 --- a/tests/fate/libavcodec.mak +++ b/tests/fate/libavcodec.mak @@ -71,6 +71,11 @@ fate-h265-levels: libavcodec/tests/h265_levels$(EXESUF) fate-h265-levels: CMD = run libavcodec/tests/h265_levels$(EXESUF) fate-h265-levels: REF = /dev/null +FATE_LIBAVCODEC-$(CONFIG_HEVC_METADATA_BSF) += fate-h265-profiles +fate-h265-profiles: libavcodec/tests/h265_profiles$(EXESUF) +fate-h265-profiles: CMD = run libavcodec/tests/h265_profiles$(EXESUF) +fate-h265-profiles: REF = /dev/null + FATE_LIBAVCODEC-$(CONFIG_IIRFILTER) += fate-iirfilter fate-iirfilter: libavcodec/tests/iirfilter$(EXESUF) fate-iirfilter: CMD = run libavcodec/tests/iirfilter$(EXESUF) -- 2.43.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".