From patchwork Sun Sep 30 22:26:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 10533 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:ab0:73d2:0:0:0:0:0 with SMTP id m18csp1002939uaq; Sun, 30 Sep 2018 15:33:15 -0700 (PDT) X-Google-Smtp-Source: ACcGV63sRsJma6iwHLHNijKpDehlce1MM6jhJyf9vA8n/bAfq48sTsvYU4VAAfgU59RNx/vCMFiX X-Received: by 2002:a1c:f516:: with SMTP id t22-v6mr7000290wmh.103.1538346795656; Sun, 30 Sep 2018 15:33:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538346795; cv=none; d=google.com; s=arc-20160816; b=iHls36t+fNwHDShxmUD/dhAPm+GdiB2mK5oyaB03hEIRtPmp7fX17xnIvG/UscD3+A Ke5BDpqdEHb7H8hd7vKgZzexCZO8wCXP3sHEOOjaD263Lg7/i3+u5gA0ZSZaqCzwM50M oW9/3gwdvftLBBP2b3gm56+t0G6NTYxLDs64w46nhYsZ8vf3SGLhzD3TYjmKGLpydeA6 5ZBfJ09xIGl4hO15TzFpblo1Q2InGP7+or038VskQaQso3WAO4ps3yizumWwlp7OHUV5 JXNXO9HfmtNmdjdR/jPpvQ/ZKoOzdhNL/t33mVI0Y6+kCPzwjWZ570G9XLE6ID2x8Xpt 3ySQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to; bh=X22BsrQA/WTOY8/MCQjzhru/zmiOyfAOEZghNaBPNqE=; b=UPQQt1+MGvTexjoxt2ai8enP392Fy2kj+VaB715Z7nwsOX6rA0YZpNOCGJUNHFzvY0 GviiG2eWITDvAlm7Jp0G7CFBmJIZd+GTcytX1+yx4UHOHFXc13O43FZMa+e0dAAQnDLg mxXkEcbsbEH+kJxJSyR/BktWZqSpOkiJbN/p96eQZ948pJSGetzEN7taNOhx6G1zVWWN H12b0U7t+7P2fl4vMJRBH9T1ID8h6nKjBiQwvZMBISbwY+f+fGJcjpD/0VOG5RSldxFr sbH0Mc7Xk4MTeUYXKKHMapmvq3yZZDrdgowLjULmzwqD3c7vZtW7JGuIqOhD6rVbPJwy k3AQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=oMlb3JKQ; 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 u9-v6si5984414wrd.317.2018.09.30.15.33.15; Sun, 30 Sep 2018 15:33:15 -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; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=oMlb3JKQ; 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 D3E67689EB0; Mon, 1 Oct 2018 01:32:55 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 86EC7689AF7 for ; Mon, 1 Oct 2018 01:32:49 +0300 (EEST) Received: by mail-wm1-f50.google.com with SMTP id 206-v6so6833395wmb.5 for ; Sun, 30 Sep 2018 15:33:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=wZ2PsFNyPrSZhMSS290JO2EO8+BY62GdYzY6g5p+Rok=; b=oMlb3JKQe+d1nBHXwpOosIFfFqmz0tXFnOENos4qLuePdVJp8NlkQBZDJS4DkOBXcO DNO2zqzSvha5L6VKkIttIMN0mSxmGiHeWERQXENZEpGB3F7Hf/KEICHXVxyQrtUBxvtm uIQnGisdyMnl1JxQggRV4UjwwGf59d7SIWisQO09K/fF0MzuXEWbSrz/wictIW6a8WHW Q5TpYVVBxsXTZsfRMpRLAcmRCvhJDu2Fo7aVYuDE4+iH3UsEPQwM0eMiXRyPUxvHB8Q0 u1p5JAaBF3xDiwaipVwMPJ7yqQqtpUP35lqp3hU/47qPxAmsS62n9kLOXdsBK3IjuzDe kddQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=wZ2PsFNyPrSZhMSS290JO2EO8+BY62GdYzY6g5p+Rok=; b=HefJa8S3JkjXcqw9EM3p6YfmWsVRkTbXc+oT/5H5rmnlj9T9OSkFgD3/J2OUetqQ6j N4nKSpZfJvY1nWhhci4Z+NbSyJK9Inq1tiGVntfdnr0pYNZiKhF/6O3J7miVKBL5Vblk FnwHIeIUwa8fkgn4/GiSdXkvIkUsetiKhX51eoUjJxBrV9Q+AivVs5ZdbQSz/5oD102q H5+yPiK8ivQ//GSWgdNnivSg6ZZyTskjrHo3wRkAreRYC9+WE7qMdGBWA0nkvkZ0fLWE n0lVkX9rFh3LLfu+yqb6Q5fnsStqj5AzLkjiv9wRSbUtOJKb2hnSQ2bJKThdP9aW4/VP exFw== X-Gm-Message-State: ABuFfoiIWisqfUXFf0hdAKyU6IU7idsANke+mdMVLqujiOzmPu4L3aRF pPk9BIjTunMnsvuvs1X/zI/mCwWTAhs= X-Received: by 2002:a1c:6a08:: with SMTP id f8-v6mr7374815wmc.49.1538346380495; Sun, 30 Sep 2018 15:26:20 -0700 (PDT) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id w4-v6sm4260773wra.83.2018.09.30.15.26.19 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 30 Sep 2018 15:26:19 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 30 Sep 2018 23:26:12 +0100 Message-Id: <20180930222612.26550-5-sw@jkqxz.net> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180930222612.26550-1-sw@jkqxz.net> References: <0446bc23-5dcb-515a-4963-f676ec6d80dc@jkqxz.net> <20180930222612.26550-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH v2 5/5] lavc/h265_profile_level: Add unit test X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Operates in the same way as the h264-levels test. --- libavcodec/Makefile | 1 + libavcodec/tests/h265_levels.c | 297 +++++++++++++++++++++++++++++++++ tests/fate/libavcodec.mak | 5 + 3 files changed, 303 insertions(+) create mode 100644 libavcodec/tests/h265_levels.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b9cc20b5ef..0cc435d201 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1143,6 +1143,7 @@ TESTPROGS-$(CONFIG_IIRFILTER) += iirfilter TESTPROGS-$(HAVE_MMX) += motion TESTPROGS-$(CONFIG_MPEGVIDEO) += mpeg12framerate TESTPROGS-$(CONFIG_H264_METADATA_BSF) += h264_levels +TESTPROGS-$(CONFIG_HEVC_METADATA_BSF) += h265_levels TESTPROGS-$(CONFIG_RANGECODER) += rangecoder TESTPROGS-$(CONFIG_SNOW_ENCODER) += snowenc diff --git a/libavcodec/tests/h265_levels.c b/libavcodec/tests/h265_levels.c new file mode 100644 index 0000000000..66d72c63a3 --- /dev/null +++ b/libavcodec/tests/h265_levels.c @@ -0,0 +1,297 @@ +/* + * 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/common.h" +#include "libavcodec/h265_profile_level.h" + +static const struct { + int width; + int height; + int level_idc; +} test_sizes[] = { + // First level usable at standard sizes, from H.265 table A.9. + { 176, 144, 30 }, // QCIF + { 352, 288, 60 }, // CIF + { 640, 480, 90 }, // VGA + { 720, 480, 90 }, // NTSC + { 720, 576, 90 }, // PAL + { 1024, 768, 93 }, // XGA + { 1280, 720, 93 }, // 720p + { 1280, 1024, 120 }, // SXGA + { 1920, 1080, 120 }, // 1080p + { 2048, 1080, 120 }, // 2Kx1080 + { 2048, 1536, 150 }, // 4XGA + { 3840, 2160, 150 }, // 4K + { 7680, 4320, 180 }, // 8K + + // Overly wide or tall sizes. + { 1, 512, 30 }, + { 1, 1024, 63 }, + { 1, 2048, 90 }, + { 1, 4096, 120 }, + { 1, 8192, 150 }, + { 1, 16384, 180 }, + { 1, 32768, 0 }, + { 512, 1, 30 }, + { 1024, 1, 63 }, + { 2048, 1, 90 }, + { 4096, 1, 120 }, + { 8192, 1, 150 }, + { 16384, 1, 180 }, + { 32768, 1, 0 }, + { 2800, 256, 93 }, + { 2816, 128, 120 }, + { 256, 4208, 120 }, + { 128, 4224, 150 }, + { 8432, 256, 150 }, + { 8448, 128, 180 }, + { 256, 16880, 180 }, + { 128, 16896, 0 }, +}; + +static const struct { + int width; + int height; + int dpb_size; + int level_idc; +} test_dpb[] = { + // First level usable for some DPB sizes. + + // L1: 176 * 144 = 25344 <= 36864 * 3/4 = 27648 + // L2: <= 122880 * 1/4 = 30720 + { 176, 144, 8, 30 }, + { 176, 144, 9, 60 }, + + // L2: 352 * 288 = 101376 <= 122880 + // L2.1: <= 245760 * 1/2 = 122880 + // L3: <= 552960 * 1/4 = 138240 + { 352, 288, 6, 60 }, + { 352, 288, 7, 63 }, + { 352, 288, 13, 90 }, + + // L3.1: 1280 * 720 = 921600 <= 983040 + // L4: <= 2228224 * 1/2 = 1114112 + // L5: <= 8912896 * 1/4 = 2228224 + { 1280, 720, 6, 93 }, + { 1280, 720, 12, 120 }, + { 1280, 720, 16, 150 }, + + // L5: 3840 * 2160 = 8294400 <= 8912896 + // L6: <= 35651584 * 1/4 = 8912896 + { 3840, 2160, 6, 150 }, + { 3840, 2160, 7, 180 }, + { 3840, 2160, 16, 180 }, +}; + +static const H265RawProfileTierLevel profile_main = { + // CpbNalFactor = 1100 + .general_profile_space = 0, + .general_profile_idc = 1, + .general_tier_flag = 0, + .general_profile_compatibility_flag[1] = 1, +}; + +static const H265RawProfileTierLevel profile_main_12 = { + // CpbNalFactor = 1650 + .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 = 0, + .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 profile_main_422_12_intra = { + // CpbNalFactor = 2200 + .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 = 0, + .general_max_8bit_constraint_flag = 0, + .general_max_422chroma_constraint_flag = 1, + .general_max_420chroma_constraint_flag = 0, + .general_max_monochrome_constraint_flag = 0, + .general_intra_constraint_flag = 1, + .general_one_picture_only_constraint_flag = 0, +}; + +static const H265RawProfileTierLevel profile_ht_444_14 = { + // CpbNalFactor = 3850 + .general_profile_space = 0, + .general_profile_idc = 5, + .general_tier_flag = 0, + .general_profile_compatibility_flag[5] = 1, + .general_max_14bit_constraint_flag = 1, + .general_max_12bit_constraint_flag = 0, + .general_max_10bit_constraint_flag = 0, + .general_max_8bit_constraint_flag = 0, + .general_max_422chroma_constraint_flag = 0, + .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, +}; + +static const H265RawProfileTierLevel profile_main_high_tier = { + // CpbNalFactor = 1100 + .general_profile_space = 0, + .general_profile_idc = 1, + .general_tier_flag = 1, + .general_profile_compatibility_flag[1] = 1, +}; + +static const struct { + int64_t bitrate; + const H265RawProfileTierLevel *ptl; + int level_idc; +} test_bitrate[] = { + // First level usable for some bitrates and profiles. + + // L2.1: 3000 * 1100 = 3300000 + // L3: 6000 * 1100 = 6600000 + { 4000000, &profile_main, 90 }, + // L2: 1500 * 1650 = 2475000 + // L2.1: 3000 * 1650 = 4950000 + { 4000000, &profile_main_12, 63 }, + // L1: 350 * 2200 * 2 = 1540000 + // L2: 1500 * 2200 * 2 = 6600000 + { 4000000, &profile_main_422_12_intra, 60 }, + + // L5.1: 40000 * 1100 = 44000000 + // L5.2: 60000 * 1100 = 66000000 + { 50000000, &profile_main, 156 }, + // L5: 25000 * 1650 = 41250000 + // L5.1: 40000 * 1650 = 66000000 + { 50000000, &profile_main_12, 153 }, + // L3.1: 10000 * 2200 * 2 = 44000000 + // L4: 12000 * 2200 * 2 = 52800000 + { 50000000, &profile_main_422_12_intra, 120 }, + // L2: 1500 * 3850 * 6 = 34650000 + // L2.1: 3000 * 3850 * 6 = 69300000 + { 50000000, &profile_ht_444_14, 63 }, + + // Level changes based on tier. + { 1000, &profile_main, 30 }, + { 1000, &profile_main_high_tier, 120 }, + { 40000000, &profile_main, 153 }, + { 40000000, &profile_main_high_tier, 123 }, + { 200000000, &profile_main, 186 }, + { 200000000, &profile_main_high_tier, 156 }, + + // Overflowing 32-bit integers. + // L6: 60000 * 3850 * 6 = 1386000000 + // L6.1: 120000 * 3850 * 6 = 2772000000 + // L6.2: 240000 * 3850 * 6 = 5544000000 + { INT64_C(2700000000), &profile_ht_444_14, 183 }, + { INT64_C(4200000000), &profile_ht_444_14, 186 }, + { INT64_C(5600000000), &profile_ht_444_14, 0 }, +}; + +static const struct { + int slice_segments; + int tile_rows; + int tile_cols; + int level_idc; +} test_fragments[] = { + // Slices. + { 4, 1, 1, 30 }, + { 32, 1, 1, 93 }, + { 70, 1, 1, 120 }, + { 80, 1, 1, 150 }, + { 201, 1, 1, 180 }, + { 600, 1, 1, 180 }, + { 601, 1, 1, 0 }, + + // Tiles. + { 1, 2, 1, 90 }, + { 1, 1, 2, 90 }, + { 1, 3, 3, 93 }, + { 1, 4, 2, 120 }, + { 1, 2, 4, 120 }, + { 1, 11, 10, 150 }, + { 1, 10, 11, 180 }, + { 1, 22, 20, 180 }, + { 1, 20, 22, 0 }, +}; + +int main(void) +{ + const H265ProfileDescriptor *profile; + const H265LevelDescriptor *level; + int i; + +#define CHECK(expected, format, ...) do { \ + if (expected ? (!level || level->level_idc != expected) \ + : !!level) { \ + av_log(NULL, AV_LOG_ERROR, "Incorrect level for " \ + format ": expected %d, got %d.\n", __VA_ARGS__, \ + expected, level ? level->level_idc : -1); \ + return 1; \ + } \ + } while (0) + + for (i = 0; i < FF_ARRAY_ELEMS(test_sizes); i++) { + level = ff_h265_guess_level(&profile_main, 0, + test_sizes[i].width, + test_sizes[i].height, + 0, 0, 0, 0); + CHECK(test_sizes[i].level_idc, "size %dx%d", + test_sizes[i].width, test_sizes[i].height); + } + + for (i = 0; i < FF_ARRAY_ELEMS(test_dpb); i++) { + level = ff_h265_guess_level(&profile_main, 0, + test_dpb[i].width, + test_dpb[i].height, + 0, 0, 0, test_dpb[i].dpb_size); + CHECK(test_dpb[i].level_idc, "size %dx%d dpb %d", + test_dpb[i].width, test_dpb[i].height, + test_dpb[i].dpb_size); + } + + for (i = 0; i < FF_ARRAY_ELEMS(test_bitrate); i++) { + profile = ff_h265_get_profile(test_bitrate[i].ptl); + level = ff_h265_guess_level(test_bitrate[i].ptl, + test_bitrate[i].bitrate, + 0, 0, 0, 0, 0, 0); + CHECK(test_bitrate[i].level_idc, "bitrate %"PRId64" profile %s", + test_bitrate[i].bitrate, profile->name); + } + + for (i = 0; i < FF_ARRAY_ELEMS(test_fragments); i++) { + level = ff_h265_guess_level(&profile_main, 0, 0, 0, + test_fragments[i].slice_segments, + test_fragments[i].tile_rows, + test_fragments[i].tile_cols, 0); + CHECK(test_fragments[i].level_idc, "%d slices %dx%d tiles", + test_fragments[i].slice_segments, + test_fragments[i].tile_cols, test_fragments[i].tile_rows); + } + + return 0; +} diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak index 5dde1243fa..e0eb7cd4dc 100644 --- a/tests/fate/libavcodec.mak +++ b/tests/fate/libavcodec.mak @@ -51,6 +51,11 @@ fate-h264-levels: libavcodec/tests/h264_levels$(EXESUF) fate-h264-levels: CMD = run libavcodec/tests/h264_levels fate-h264-levels: REF = /dev/null +FATE_LIBAVCODEC-$(CONFIG_HEVC_METADATA_BSF) += fate-h265-levels +fate-h265-levels: libavcodec/tests/h265_levels$(EXESUF) +fate-h265-levels: CMD = run libavcodec/tests/h265_levels +fate-h265-levels: REF = /dev/null + FATE_LIBAVCODEC-$(CONFIG_IIRFILTER) += fate-iirfilter fate-iirfilter: libavcodec/tests/iirfilter$(EXESUF) fate-iirfilter: CMD = run libavcodec/tests/iirfilter