From patchwork Sat Sep 14 10:45:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51579 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp300536vqy; Sat, 14 Sep 2024 04:11:48 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCW4hQ52wn2oHO7fTFBGoFx9IVpsGrR2pXIf/0/MmU73aKJgsRewi7SEgm6J5+FAN9jhYKg0UtDM+B/XpBq6bTFI@gmail.com X-Google-Smtp-Source: AGHT+IEQPLqtnLzEDpsU5A4jryb9mo5Ye24r/AUp3e7wW3IJ2ApbczIQVdm3Suiqx8TwViTeUMFY X-Received: by 2002:a17:907:3fa4:b0:a86:9e3f:fdc8 with SMTP id a640c23a62f3a-a902941dc78mr415330866b.4.1726312307680; Sat, 14 Sep 2024 04:11:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312307; cv=none; d=google.com; s=arc-20240605; b=fn2emSFI7gYJfdEszLmKGAg7QURCKzM6o89IjRSXRIdM41yYZHNUb+nfaxkwvPkVoS NNyIR+h7Nqa4mJOLIC0oi3rWjQlpwl1KJlu9D+09q2Y9d9j9zsXLZy3TtsksBdXOUouo Bu4azFH8x8LGfKhiRFMjJm7/1BjTN22G64jAwt1Mao+ZM0zoiXN0jua6liew4q8TCOxC qoSDY8HF7by6Nz0M8DB9e3zeUb1lJYkygwi96dowYorQl85mrbDOe7CZyJSFcxIkq2v5 26m2F+G/DeJ+iDnH6lGgYrdoD/RAYy+go8mMX3jHN5R/I1YoEWdrc9zAv4b+VY/2GFVx ogyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=b9TkWWlJD/aCT0VouSon/XKdssV31IHcO/aLsxG9+vU=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=F7MVigLRgX7x0zVF917NuohvopSAK71LC6l2Vx17bmbeIcPV4T/Y2xsonYCorQcE/n xoLMzGw/lOkMas+463A8uetVBPLUnaUigxa1wlDx8UK3/qoDM2V4yMhUbC+SFGsxYoB9 3IaAVQFvp+PmLUsNzGrlDgF/39MT46AkJzgLQlqoXHsDKVzca0aE1aCLDcXSZ+zVnVpJ s37j+AKX4tSguksnONe/H3OuPw8ND7l4PQxIaAuy9Ce2SqnGojCIwXmksZtnqIO8MCMq jDU7xpBsjnrB3erXyzfu+AL0uDtZOc5qnzJGqQyJntohpKJVtwrQo1RBN1dxdRr/ycEw Co6g==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=Kc+mBysr; 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 a640c23a62f3a-a90612e92bcsi85991266b.514.2024.09.14.04.11.47; Sat, 14 Sep 2024 04:11:47 -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=@khirnov.net header.s=mail header.b=Kc+mBysr; 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 C619368DDB7; Sat, 14 Sep 2024 14:10:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AD30768DADD for ; Sat, 14 Sep 2024 14:10:48 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=Kc+mBysr; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 3FCAB4E0F for ; Sat, 14 Sep 2024 13:10:48 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id RS_Wi67EqTik for ; Sat, 14 Sep 2024 13:10:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=spFZHE3kg9oeYAHZkuoQut9Re3MXk22NT6PMETBti0M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Kc+mBysreKEIIjoK5ZpjCaGTphatZWRxbawErMMPiX+aDkNE1qfb8sFojQNaWuyLo eY70jJpQk9I8sSwlyATe7OdgkH/dribdlqUiVsF3gBciuiLXFHSFQk4ASjhJ0Ev5Ey hY8yL9IokhpRrizm2KZ+rMJU77tY7t5IMuDFFDJ36Oxrb58F9FFky1iHEx0hioA1q2 Ya5hNGsbyK5EwWq3u3RKtDhZNhSgsBxzmDQaST6jM9/4yWGg3ShFvZSQ1eWwz4wjKp U5KBcVkluOXWNa0pJMd5uSHuMGtqnPiuaGzeApHMZNX9RNUKyV1nUwUrVVYVOaE47u QC5psNVaHRi2A== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 336884DDE for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id DA51D3A086F for ; Sat, 14 Sep 2024 13:10:40 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:26 +0200 Message-ID: <20240914111036.17164-2-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 01/23] compat: drop gcc, suncc, and pthreads stdatomic emulation 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: mGZNqm5OQb0K Since we now require a C11-compliant compiler, there should be no supported configurations where any of these is used. --- compat/atomics/gcc/stdatomic.h | 173 ------------------------- compat/atomics/pthread/stdatomic.c | 39 ------ compat/atomics/pthread/stdatomic.h | 197 ----------------------------- compat/atomics/suncc/stdatomic.h | 186 --------------------------- configure | 19 +-- 5 files changed, 1 insertion(+), 613 deletions(-) delete mode 100644 compat/atomics/gcc/stdatomic.h delete mode 100644 compat/atomics/pthread/stdatomic.c delete mode 100644 compat/atomics/pthread/stdatomic.h delete mode 100644 compat/atomics/suncc/stdatomic.h diff --git a/compat/atomics/gcc/stdatomic.h b/compat/atomics/gcc/stdatomic.h deleted file mode 100644 index e13ed0e068..0000000000 --- a/compat/atomics/gcc/stdatomic.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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 - */ - -/* - * based on vlc_atomic.h from VLC - * Copyright (C) 2010 Rémi Denis-Courmont - */ - -#ifndef COMPAT_ATOMICS_GCC_STDATOMIC_H -#define COMPAT_ATOMICS_GCC_STDATOMIC_H - -#include -#include - -#define ATOMIC_FLAG_INIT 0 - -#define ATOMIC_VAR_INIT(value) (value) - -#define atomic_init(obj, value) \ -do { \ - *(obj) = (value); \ -} while(0) - -#define kill_dependency(y) ((void)0) - -#define atomic_thread_fence(order) \ - __sync_synchronize() - -#define atomic_signal_fence(order) \ - ((void)0) - -#define atomic_is_lock_free(obj) 0 - -typedef _Bool atomic_flag; -typedef _Bool atomic_bool; -typedef char atomic_char; -typedef signed char atomic_schar; -typedef unsigned char atomic_uchar; -typedef short atomic_short; -typedef unsigned short atomic_ushort; -typedef int atomic_int; -typedef unsigned int atomic_uint; -typedef long atomic_long; -typedef unsigned long atomic_ulong; -typedef long long atomic_llong; -typedef unsigned long long atomic_ullong; -typedef wchar_t atomic_wchar_t; -typedef int_least8_t atomic_int_least8_t; -typedef uint_least8_t atomic_uint_least8_t; -typedef int_least16_t atomic_int_least16_t; -typedef uint_least16_t atomic_uint_least16_t; -typedef int_least32_t atomic_int_least32_t; -typedef uint_least32_t atomic_uint_least32_t; -typedef int_least64_t atomic_int_least64_t; -typedef uint_least64_t atomic_uint_least64_t; -typedef int_fast8_t atomic_int_fast8_t; -typedef uint_fast8_t atomic_uint_fast8_t; -typedef int_fast16_t atomic_int_fast16_t; -typedef uint_fast16_t atomic_uint_fast16_t; -typedef int_fast32_t atomic_int_fast32_t; -typedef uint_fast32_t atomic_uint_fast32_t; -typedef int_fast64_t atomic_int_fast64_t; -typedef uint_fast64_t atomic_uint_fast64_t; -typedef intptr_t atomic_intptr_t; -typedef uintptr_t atomic_uintptr_t; -typedef size_t atomic_size_t; -typedef ptrdiff_t atomic_ptrdiff_t; -typedef intmax_t atomic_intmax_t; -typedef uintmax_t atomic_uintmax_t; - -#define atomic_store(object, desired) \ -do { \ - *(object) = (desired); \ - __sync_synchronize(); \ -} while (0) - -#define atomic_store_explicit(object, desired, order) \ - atomic_store(object, desired) - -#define atomic_load(object) \ - (__sync_synchronize(), *(object)) - -#define atomic_load_explicit(object, order) \ - atomic_load(object) - -#define atomic_exchange(object, desired) \ -({ \ - __typeof__(object) _obj = (object); \ - __typeof__(*object) _old; \ - do \ - _old = atomic_load(_obj); \ - while (!__sync_bool_compare_and_swap(_obj, _old, (desired))); \ - _old; \ -}) - -#define atomic_exchange_explicit(object, desired, order) \ - atomic_exchange(object, desired) - -#define atomic_compare_exchange_strong(object, expected, desired) \ -({ \ - __typeof__(object) _exp = (expected); \ - __typeof__(*object) _old = *_exp; \ - *_exp = __sync_val_compare_and_swap((object), _old, (desired)); \ - *_exp == _old; \ -}) - -#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ - atomic_compare_exchange_strong(object, expected, desired) - -#define atomic_compare_exchange_weak(object, expected, desired) \ - atomic_compare_exchange_strong(object, expected, desired) - -#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ - atomic_compare_exchange_weak(object, expected, desired) - -#define atomic_fetch_add(object, operand) \ - __sync_fetch_and_add(object, operand) - -#define atomic_fetch_add_explicit(object, operand, order) \ - atomic_fetch_add(object, operand) - -#define atomic_fetch_sub(object, operand) \ - __sync_fetch_and_sub(object, operand) - -#define atomic_fetch_sub_explicit(object, operand, order) \ - atomic_fetch_sub(object, operand) - -#define atomic_fetch_or(object, operand) \ - __sync_fetch_and_or(object, operand) - -#define atomic_fetch_or_explicit(object, operand, order) \ - atomic_fetch_or(object, operand) - -#define atomic_fetch_xor(object, operand) \ - __sync_fetch_and_xor(object, operand) - -#define atomic_fetch_xor_explicit(object, operand, order) \ - atomic_fetch_xor(object, operand) - -#define atomic_fetch_and(object, operand) \ - __sync_fetch_and_and(object, operand) - -#define atomic_fetch_and_explicit(object, operand, order) \ - atomic_fetch_and(object, operand) - -#define atomic_flag_test_and_set(object) \ - atomic_exchange(object, 1) - -#define atomic_flag_test_and_set_explicit(object, order) \ - atomic_flag_test_and_set(object) - -#define atomic_flag_clear(object) \ - atomic_store(object, 0) - -#define atomic_flag_clear_explicit(object, order) \ - atomic_flag_clear(object) - -#endif /* COMPAT_ATOMICS_GCC_STDATOMIC_H */ diff --git a/compat/atomics/pthread/stdatomic.c b/compat/atomics/pthread/stdatomic.c deleted file mode 100644 index 9fca98980b..0000000000 --- a/compat/atomics/pthread/stdatomic.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 - */ - -/* - * based on vlc_atomic.h from VLC - * Copyright (C) 2010 Rémi Denis-Courmont - */ - -#include -#include - -#include "stdatomic.h" - -static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER; - -void avpriv_atomic_lock(void) -{ - pthread_mutex_lock(&atomic_lock); -} - -void avpriv_atomic_unlock(void) -{ - pthread_mutex_unlock(&atomic_lock); -} diff --git a/compat/atomics/pthread/stdatomic.h b/compat/atomics/pthread/stdatomic.h deleted file mode 100644 index 81a60f102b..0000000000 --- a/compat/atomics/pthread/stdatomic.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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 - */ - -/* - * based on vlc_atomic.h from VLC - * Copyright (C) 2010 Rémi Denis-Courmont - */ - -#ifndef COMPAT_ATOMICS_PTHREAD_STDATOMIC_H -#define COMPAT_ATOMICS_PTHREAD_STDATOMIC_H - -#include - -#define ATOMIC_FLAG_INIT 0 - -#define ATOMIC_VAR_INIT(value) (value) - -#define atomic_init(obj, value) \ -do { \ - *(obj) = (value); \ -} while(0) - -#define kill_dependency(y) ((void)0) - -#define atomic_signal_fence(order) \ - ((void)0) - -#define atomic_is_lock_free(obj) 0 - -typedef intptr_t atomic_flag; -typedef intptr_t atomic_bool; -typedef intptr_t atomic_char; -typedef intptr_t atomic_schar; -typedef intptr_t atomic_uchar; -typedef intptr_t atomic_short; -typedef intptr_t atomic_ushort; -typedef intptr_t atomic_int; -typedef intptr_t atomic_uint; -typedef intptr_t atomic_long; -typedef intptr_t atomic_ulong; -typedef intptr_t atomic_llong; -typedef intptr_t atomic_ullong; -typedef intptr_t atomic_wchar_t; -typedef intptr_t atomic_int_least8_t; -typedef intptr_t atomic_uint_least8_t; -typedef intptr_t atomic_int_least16_t; -typedef intptr_t atomic_uint_least16_t; -typedef intptr_t atomic_int_least32_t; -typedef intptr_t atomic_uint_least32_t; -typedef intptr_t atomic_int_least64_t; -typedef intptr_t atomic_uint_least64_t; -typedef intptr_t atomic_int_fast8_t; -typedef intptr_t atomic_uint_fast8_t; -typedef intptr_t atomic_int_fast16_t; -typedef intptr_t atomic_uint_fast16_t; -typedef intptr_t atomic_int_fast32_t; -typedef intptr_t atomic_uint_fast32_t; -typedef intptr_t atomic_int_fast64_t; -typedef intptr_t atomic_uint_fast64_t; -typedef intptr_t atomic_intptr_t; -typedef intptr_t atomic_uintptr_t; -typedef intptr_t atomic_size_t; -typedef intptr_t atomic_ptrdiff_t; -typedef intptr_t atomic_intmax_t; -typedef intptr_t atomic_uintmax_t; - -void avpriv_atomic_lock(void); -void avpriv_atomic_unlock(void); - -static inline void atomic_thread_fence(int order) -{ - avpriv_atomic_lock(); - avpriv_atomic_unlock(); -} - -static inline void atomic_store(intptr_t *object, intptr_t desired) -{ - avpriv_atomic_lock(); - *object = desired; - avpriv_atomic_unlock(); -} - -#define atomic_store_explicit(object, desired, order) \ - atomic_store(object, desired) - -static inline intptr_t atomic_load(intptr_t *object) -{ - intptr_t ret; - avpriv_atomic_lock(); - ret = *object; - avpriv_atomic_unlock(); - return ret; -} - -#define atomic_load_explicit(object, order) \ - atomic_load(object) - -static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired) -{ - intptr_t ret; - avpriv_atomic_lock(); - ret = *object; - *object = desired; - avpriv_atomic_unlock(); - return ret; -} - -#define atomic_exchange_explicit(object, desired, order) \ - atomic_exchange(object, desired) - -static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected, - intptr_t desired) -{ - int ret; - avpriv_atomic_lock(); - if (*object == *expected) { - ret = 1; - *object = desired; - } else { - ret = 0; - *expected = *object; - } - avpriv_atomic_unlock(); - return ret; -} - -#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ - atomic_compare_exchange_strong(object, expected, desired) - -#define atomic_compare_exchange_weak(object, expected, desired) \ - atomic_compare_exchange_strong(object, expected, desired) - -#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ - atomic_compare_exchange_weak(object, expected, desired) - -#define FETCH_MODIFY(opname, op) \ -static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \ -{ \ - intptr_t ret; \ - avpriv_atomic_lock(); \ - ret = *object; \ - *object = *object op operand; \ - avpriv_atomic_unlock(); \ - return ret; \ -} - -FETCH_MODIFY(add, +) -FETCH_MODIFY(sub, -) -FETCH_MODIFY(or, |) -FETCH_MODIFY(xor, ^) -FETCH_MODIFY(and, &) - -#undef FETCH_MODIFY - -#define atomic_fetch_add_explicit(object, operand, order) \ - atomic_fetch_add(object, operand) - -#define atomic_fetch_sub_explicit(object, operand, order) \ - atomic_fetch_sub(object, operand) - -#define atomic_fetch_or_explicit(object, operand, order) \ - atomic_fetch_or(object, operand) - -#define atomic_fetch_xor_explicit(object, operand, order) \ - atomic_fetch_xor(object, operand) - -#define atomic_fetch_and_explicit(object, operand, order) \ - atomic_fetch_and(object, operand) - -#define atomic_flag_test_and_set(object) \ - atomic_exchange(object, 1) - -#define atomic_flag_test_and_set_explicit(object, order) \ - atomic_flag_test_and_set(object) - -#define atomic_flag_clear(object) \ - atomic_store(object, 0) - -#define atomic_flag_clear_explicit(object, order) \ - atomic_flag_clear(object) - -#endif /* COMPAT_ATOMICS_PTHREAD_STDATOMIC_H */ diff --git a/compat/atomics/suncc/stdatomic.h b/compat/atomics/suncc/stdatomic.h deleted file mode 100644 index 0cf89e0f78..0000000000 --- a/compat/atomics/suncc/stdatomic.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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 COMPAT_ATOMICS_SUNCC_STDATOMIC_H -#define COMPAT_ATOMICS_SUNCC_STDATOMIC_H - -#include -#include -#include -#include - -#define ATOMIC_FLAG_INIT 0 - -#define ATOMIC_VAR_INIT(value) (value) - -#define atomic_init(obj, value) \ -do { \ - *(obj) = (value); \ -} while(0) - -#define kill_dependency(y) ((void)0) - -#define atomic_thread_fence(order) \ - __machine_rw_barrier(); - -#define atomic_signal_fence(order) \ - ((void)0) - -#define atomic_is_lock_free(obj) 0 - -typedef intptr_t atomic_flag; -typedef intptr_t atomic_bool; -typedef intptr_t atomic_char; -typedef intptr_t atomic_schar; -typedef intptr_t atomic_uchar; -typedef intptr_t atomic_short; -typedef intptr_t atomic_ushort; -typedef intptr_t atomic_int; -typedef intptr_t atomic_uint; -typedef intptr_t atomic_long; -typedef intptr_t atomic_ulong; -typedef intptr_t atomic_llong; -typedef intptr_t atomic_ullong; -typedef intptr_t atomic_wchar_t; -typedef intptr_t atomic_int_least8_t; -typedef intptr_t atomic_uint_least8_t; -typedef intptr_t atomic_int_least16_t; -typedef intptr_t atomic_uint_least16_t; -typedef intptr_t atomic_int_least32_t; -typedef intptr_t atomic_uint_least32_t; -typedef intptr_t atomic_int_least64_t; -typedef intptr_t atomic_uint_least64_t; -typedef intptr_t atomic_int_fast8_t; -typedef intptr_t atomic_uint_fast8_t; -typedef intptr_t atomic_int_fast16_t; -typedef intptr_t atomic_uint_fast16_t; -typedef intptr_t atomic_int_fast32_t; -typedef intptr_t atomic_uint_fast32_t; -typedef intptr_t atomic_int_fast64_t; -typedef intptr_t atomic_uint_fast64_t; -typedef intptr_t atomic_intptr_t; -typedef intptr_t atomic_uintptr_t; -typedef intptr_t atomic_size_t; -typedef intptr_t atomic_ptrdiff_t; -typedef intptr_t atomic_intmax_t; -typedef intptr_t atomic_uintmax_t; - -static inline void atomic_store(intptr_t *object, intptr_t desired) -{ - *object = desired; - __machine_rw_barrier(); -} - -#define atomic_store_explicit(object, desired, order) \ - atomic_store(object, desired) - -static inline intptr_t atomic_load(intptr_t *object) -{ - __machine_rw_barrier(); - return *object; -} - -#define atomic_load_explicit(object, order) \ - atomic_load(object) - -#define atomic_exchange(object, desired) \ - atomic_swap_ptr(object, desired) - -#define atomic_exchange_explicit(object, desired, order) \ - atomic_exchange(object, desired) - -static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected, - intptr_t desired) -{ - intptr_t old = *expected; - *expected = (intptr_t)atomic_cas_ptr(object, (void *)old, (void *)desired); - return *expected == old; -} - -#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ - atomic_compare_exchange_strong(object, expected, desired) - -#define atomic_compare_exchange_weak(object, expected, desired) \ - atomic_compare_exchange_strong(object, expected, desired) - -#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ - atomic_compare_exchange_weak(object, expected, desired) - -static inline intptr_t atomic_fetch_add(intptr_t *object, intptr_t operand) -{ - return atomic_add_ptr_nv(object, operand) - operand; -} - -#define atomic_fetch_sub(object, operand) \ - atomic_fetch_add(object, -(operand)) - -static inline intptr_t atomic_fetch_or(intptr_t *object, intptr_t operand) -{ - intptr_t old; - do { - old = atomic_load(object); - } while (!atomic_compare_exchange_strong(object, old, old | operand)); - return old; -} - -static inline intptr_t atomic_fetch_xor(intptr_t *object, intptr_t operand) -{ - intptr_t old; - do { - old = atomic_load(object); - } while (!atomic_compare_exchange_strong(object, old, old ^ operand)); - return old; -} - -static inline intptr_t atomic_fetch_and(intptr_t *object, intptr_t operand) -{ - intptr_t old; - do { - old = atomic_load(object); - } while (!atomic_compare_exchange_strong(object, old, old & operand)); - return old; -} - -#define atomic_fetch_add_explicit(object, operand, order) \ - atomic_fetch_add(object, operand) - -#define atomic_fetch_sub_explicit(object, operand, order) \ - atomic_fetch_sub(object, operand) - -#define atomic_fetch_or_explicit(object, operand, order) \ - atomic_fetch_or(object, operand) - -#define atomic_fetch_xor_explicit(object, operand, order) \ - atomic_fetch_xor(object, operand) - -#define atomic_fetch_and_explicit(object, operand, order) \ - atomic_fetch_and(object, operand) - -#define atomic_flag_test_and_set(object) \ - atomic_exchange(object, 1) - -#define atomic_flag_test_and_set_explicit(object, order) \ - atomic_flag_test_and_set(object) - -#define atomic_flag_clear(object) \ - atomic_store(object, 0) - -#define atomic_flag_clear_explicit(object, order) \ - atomic_flag_clear(object) - -#endif /* COMPAT_ATOMICS_SUNCC_STDATOMIC_H */ diff --git a/configure b/configure index d3bd46f382..337172a6c6 100755 --- a/configure +++ b/configure @@ -2117,8 +2117,6 @@ THREADS_LIST=" " ATOMICS_LIST=" - atomics_gcc - atomics_suncc atomics_win32 " @@ -2249,13 +2247,10 @@ ARCH_FEATURES=" " BUILTIN_LIST=" - atomic_cas_ptr - machine_rw_barrier MemoryBarrier mm_empty rdtsc sem_timedwait - sync_val_compare_and_swap " HAVE_LIST_CMDLINE=" inline_asm @@ -2834,8 +2829,6 @@ valgrind_backtrace_conflict="optimizations" valgrind_backtrace_deps="valgrind_valgrind_h" # threading support -atomics_gcc_if="sync_val_compare_and_swap" -atomics_suncc_if="atomic_cas_ptr machine_rw_barrier" atomics_win32_if="MemoryBarrier" atomics_native_if_any="$ATOMICS_LIST" w32threads_deps="atomics_native" @@ -6507,10 +6500,7 @@ if ! disabled network; then fi fi -check_builtin atomic_cas_ptr atomic.h "void **ptr; void *oldval, *newval; atomic_cas_ptr(ptr, oldval, newval)" -check_builtin machine_rw_barrier mbarrier.h "__machine_rw_barrier()" check_builtin MemoryBarrier windows.h "MemoryBarrier()" -check_builtin sync_val_compare_and_swap "" "int *ptr; int oldval, newval; __sync_val_compare_and_swap(ptr, oldval, newval)" check_builtin gmtime_r time.h "time_t *time; struct tm *tm; gmtime_r(time, tm)" check_builtin localtime_r time.h "time_t *time; struct tm *tm; localtime_r(time, tm)" @@ -7768,15 +7758,8 @@ for thread in $THREADS_LIST; do done if disabled stdatomic; then - if enabled atomics_gcc; then - add_cppflags '-I\$(SRC_PATH)/compat/atomics/gcc' - elif enabled atomics_win32; then + if enabled atomics_win32; then add_cppflags '-I\$(SRC_PATH)/compat/atomics/win32' - elif enabled atomics_suncc; then - add_cppflags '-I\$(SRC_PATH)/compat/atomics/suncc' - elif enabled pthreads; then - add_compat atomics/pthread/stdatomic.o - add_cppflags '-I\$(SRC_PATH)/compat/atomics/pthread' else enabled threads && die "Threading is enabled, but no atomics are available" add_cppflags '-I\$(SRC_PATH)/compat/atomics/dummy' From patchwork Sat Sep 14 10:45:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51580 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp300305vqy; Sat, 14 Sep 2024 04:11:15 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVCRj6gqg3jZLT2DsKafL8vMLWhRRr8SZlz3vvdg7tLiUlxUtc9Px/7ZRcopQuyRPoe8hZd54MbgJkmTPK0Yuf/@gmail.com X-Google-Smtp-Source: AGHT+IHANZCGDkjONQ8lhvSqBQSJf3dYTTYfmC4SzfZ8ooDhjvkYT+yC2QqCAFPUrgv3uhp2f7m2 X-Received: by 2002:a2e:9017:0:b0:2f5:c13:bd11 with SMTP id 38308e7fff4ca-2f787dcdaf0mr42455691fa.17.1726312274833; Sat, 14 Sep 2024 04:11:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312274; cv=none; d=google.com; s=arc-20240605; b=WxaoPXpEcKtm2XUvUfkPvxY3K1s/a5U51A9NV2rc+COr7M0B+b9jnQeU1JtnPv12VT Ff8F3gwvUqhUGRxbnGdiQFayf6FyXuLGpaTMNfO4aNubl4YDEp5aJli0Y6XWA1SjHeJH xPAomoeMxhKR7AX93JcNm8kJAqfhBsNwj+H/6BFPNv1PJ+GhepYYDceUMPLy5TBMaGLF VUdKAcDvDmxwg4dWbhaIM5ScEqMkkdYyzfyvrX+JwAx8GlCB3l2lwQfE6+NAcDVYWDeY XWizs1/8ThLHJXsQoHHmp7nJg/rGJYB/daM2oiQ6yheRG+hz2wjQkin1tQjL2EEVvmfZ R5hQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=UL+ogkclR+GoO4z2ZDp2bY/ytaRA3FZf+pRYHQp+iDQ=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=lndXgFH7E5yYW6v9lvo4AmUji7/aY9n8e8hSWcLKW+e3mAekqWcaHUvdAL3A1fOAoB LYEkM5N323eA4kAgnQFORVLZ5hRJiZZMNrW3kL0Qei2cSOOGaPn6hpvHlh4sK0oF3jOJ AzvUnLvbP26HmQR7gd2VCjNvwXG0eVQCoeHovEfKLkghgYWSxnYTHrYe98siFPLzlZyA eA1N0/RbuZU1SvrHw0r7WlCLv4HmtMmYdYtp1kblT1XxQ7b+E3coFptcvuEITfn+NIAf v5CUb4O2qjGvqB6+LGApdWo47h55H609CKDfs9fhOUwyK2lgG/Ye3eQqFcKFL+dFZKkl j13w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=qBVVgbNa; 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 38308e7fff4ca-2f79d488dd8si3899051fa.604.2024.09.14.04.11.14; Sat, 14 Sep 2024 04:11:14 -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=@khirnov.net header.s=mail header.b=qBVVgbNa; 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 A296368DC6D; Sat, 14 Sep 2024 14:10:55 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0566668DA8C for ; Sat, 14 Sep 2024 14:10:47 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=qBVVgbNa; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 4D3B44E19 for ; Sat, 14 Sep 2024 13:10:47 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id GfFXR51kmqOb for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=3WKBBwQj5Lf2Vmi+HMnv/gRohFCjNuRZQU2lzJmVMl8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=qBVVgbNaN7Uv0wa7QJkdwEIXjW2eFwu6pW4VpKQDocl+1VC8NbmJn88WLBD+qZWKk 7h0v1TXai2xh+ExSH2/DXkauUAb46632lkldHkmWmsrbBndJD/7FlMJsNaDgrLiDLy gJJNoyTDDSoTw8suxkZdj4GICQsL20SbUyTWsU0cczG9HcYGNCFWGY824ptSgbN9zM 7PV/VekFPITrklFFAFVtgysP1vH/0ph47W5R4Yc+fZ69nBV+3mfBfcUGlfCy+UWrbp rFB5MujzYS4CB/8bp3I99jojkLUylY0LxYhAkomQtl5g37rpPm8pv7IKMsq/v5AB+X 4F5zRP4er77bw== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 377314DE6 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id E5F8D3A0998 for ; Sat, 14 Sep 2024 13:10:40 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:27 +0200 Message-ID: <20240914111036.17164-3-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 02/23] compat: add a fallback implementation of C23 stdbit.h 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: CW16OtkQ+y3+ From: Rémi Denis-Courmont Header contents taken from VLC commit 7a970a33329c9836d169727ddbaf49a33240d587. Signed-off-by: Anton Khirnov --- compat/stdbit/stdbit.h | 594 +++++++++++++++++++++++++++++++++++++++++ configure | 4 + tests/ref/fate/source | 1 + 3 files changed, 599 insertions(+) create mode 100644 compat/stdbit/stdbit.h diff --git a/compat/stdbit/stdbit.h b/compat/stdbit/stdbit.h new file mode 100644 index 0000000000..b6a2c7e945 --- /dev/null +++ b/compat/stdbit/stdbit.h @@ -0,0 +1,594 @@ +/* + * Copyright (C) 2023 Rémi Denis-Courmont + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + */ + +#ifndef __STDC_VERSION_STDBIT_H__ +#define __STDC_VERSION_STDBIT_H__ 202311L + +#include +#include /* CHAR_BIT */ + +#define __STDC_ENDIAN_LITTLE__ 1234 +#define __STDC_ENDIAN_BIG__ 4321 + +#ifdef __BYTE_ORDER__ +# if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__ +# elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_BIG__ +# else +# define __STDC_ENDIAN_NATIVE__ 3412 +# endif +#else +# error Not implemented. +#endif + +#define __stdbit_generic_type_func(func, value) \ + _Generic (value, \ + unsigned long long: stdc_##func##_ull((unsigned long long)(value)), \ + unsigned long: stdc_##func##_ul((unsigned long)(value)), \ + unsigned int: stdc_##func##_ui((unsigned int)(value)), \ + unsigned short: stdc_##func##_us((unsigned short)(value)), \ + unsigned char: stdc_##func##_uc((unsigned char)(value))) + +#if defined (__GNUC__) || defined (__clang__) +static inline unsigned int stdc_leading_zeros_ull(unsigned long long value) +{ + return value ? __builtin_clzll(value) : (CHAR_BIT * sizeof (value)); +} + +static inline unsigned int stdc_leading_zeros_ul(unsigned long value) +{ + return value ? __builtin_clzl(value) : (CHAR_BIT * sizeof (value)); +} + +static inline unsigned int stdc_leading_zeros_ui(unsigned int value) +{ + return value ? __builtin_clz(value) : (CHAR_BIT * sizeof (value)); +} + +static inline unsigned int stdc_leading_zeros_us(unsigned short value) +{ + return stdc_leading_zeros_ui(value) + - CHAR_BIT * (sizeof (int) - sizeof (value)); +} + +static inline unsigned int stdc_leading_zeros_uc(unsigned char value) +{ + return stdc_leading_zeros_ui(value) - (CHAR_BIT * (sizeof (int) - 1)); +} +#else +static inline unsigned int __stdc_leading_zeros(unsigned long long value, + unsigned int size) +{ + unsigned int zeros = size * CHAR_BIT; + + while (value != 0) { + value >>= 1; + zeros--; + } + + return zeros; +} + +static inline unsigned int stdc_leading_zeros_ull(unsigned long long value) +{ + return __stdc_leading_zeros(value, sizeof (value)); +} + +static inline unsigned int stdc_leading_zeros_ul(unsigned long value) +{ + return __stdc_leading_zeros(value, sizeof (value)); +} + +static inline unsigned int stdc_leading_zeros_ui(unsigned int value) +{ + return __stdc_leading_zeros(value, sizeof (value)); +} + +static inline unsigned int stdc_leading_zeros_us(unsigned short value) +{ + return __stdc_leading_zeros(value, sizeof (value)); +} + +static inline unsigned int stdc_leading_zeros_uc(unsigned char value) +{ + return __stdc_leading_zeros(value, sizeof (value)); +} +#endif + +#define stdc_leading_zeros(value) \ + __stdbit_generic_type_func(leading_zeros, value) + +static inline unsigned int stdc_leading_ones_ull(unsigned long long value) +{ + return stdc_leading_zeros_ull(~value); +} + +static inline unsigned int stdc_leading_ones_ul(unsigned long value) +{ + return stdc_leading_zeros_ul(~value); +} + +static inline unsigned int stdc_leading_ones_ui(unsigned int value) +{ + return stdc_leading_zeros_ui(~value); +} + +static inline unsigned int stdc_leading_ones_us(unsigned short value) +{ + return stdc_leading_zeros_us(~value); +} + +static inline unsigned int stdc_leading_ones_uc(unsigned char value) +{ + return stdc_leading_zeros_uc(~value); +} + +#define stdc_leading_ones(value) \ + __stdbit_generic_type_func(leading_ones, value) + +#if defined (__GNUC__) || defined (__clang__) +static inline unsigned int stdc_trailing_zeros_ull(unsigned long long value) +{ + return value ? (unsigned int)__builtin_ctzll(value) + : (CHAR_BIT * sizeof (value)); +} + +static inline unsigned int stdc_trailing_zeros_ul(unsigned long value) +{ + return value ? (unsigned int)__builtin_ctzl(value) + : (CHAR_BIT * sizeof (value)); +} + +static inline unsigned int stdc_trailing_zeros_ui(unsigned int value) +{ + return value ? (unsigned int)__builtin_ctz(value) + : (CHAR_BIT * sizeof (value)); +} + +static inline unsigned int stdc_trailing_zeros_us(unsigned short value) +{ + return value ? (unsigned int)__builtin_ctz(value) + : (CHAR_BIT * sizeof (value)); +} + +static inline unsigned int stdc_trailing_zeros_uc(unsigned char value) +{ + return value ? (unsigned int)__builtin_ctz(value) + : (CHAR_BIT * sizeof (value)); +} +#else +static inline unsigned int __stdc_trailing_zeros(unsigned long long value, + unsigned int size) +{ + unsigned int zeros = size * CHAR_BIT; + + while (value != 0) { + value <<= 1; + zeros--; + } + + return zeros; +} + +static inline unsigned int stdc_trailing_zeros_ull(unsigned long long value) +{ + return __stdc_trailing_zeros(value, sizeof (value)); +} + +static inline unsigned int stdc_trailing_zeros_ul(unsigned long value) +{ + return __stdc_trailing_zeros(value, sizeof (value)); +} + +static inline unsigned int stdc_trailing_zeros_ui(unsigned int value) +{ + return __stdc_trailing_zeros(value, sizeof (value)); +} + +static inline unsigned int stdc_trailing_zeros_us(unsigned short value) +{ + return __stdc_trailing_zeros(value, sizeof (value)); +} + +static inline unsigned int stdc_trailing_zeros_uc(unsigned char value) +{ + return __stdc_trailing_zeros(value, sizeof (value)); +} +#endif + +#define stdc_trailing_zeros(value) \ + __stdbit_generic_type_func(trailing_zeros, value) + +static inline unsigned int stdc_trailing_ones_ull(unsigned long long value) +{ + return stdc_trailing_zeros_ull(~value); +} + +static inline unsigned int stdc_trailing_ones_ul(unsigned long value) +{ + return stdc_trailing_zeros_ul(~value); +} + +static inline unsigned int stdc_trailing_ones_ui(unsigned int value) +{ + return stdc_trailing_zeros_ui(~value); +} + +static inline unsigned int stdc_trailing_ones_us(unsigned short value) +{ + return stdc_trailing_zeros_us(~value); +} + +static inline unsigned int stdc_trailing_ones_uc(unsigned char value) +{ + return stdc_trailing_zeros_uc(~value); +} + +#define stdc_trailing_ones(value) \ + __stdbit_generic_type_func(trailing_ones, value) + +static inline unsigned int stdc_first_leading_one_ull(unsigned long long value) +{ + return value ? (stdc_leading_zeros_ull(value) + 1) : 0; +} + +static inline unsigned int stdc_first_leading_one_ul(unsigned long value) +{ + return value ? (stdc_leading_zeros_ul(value) + 1) : 0; +} + +static inline unsigned int stdc_first_leading_one_ui(unsigned int value) +{ + return value ? (stdc_leading_zeros_ui(value) + 1) : 0; +} + +static inline unsigned int stdc_first_leading_one_us(unsigned short value) +{ + return value ? (stdc_leading_zeros_us(value) + 1) : 0; +} + +static inline unsigned int stdc_first_leading_one_uc(unsigned char value) +{ + return value ? (stdc_leading_zeros_uc(value) + 1) : 0; +} + +#define stdc_first_leading_one(value) \ + __stdbit_generic_type_func(first_leading_one, value) + +static inline unsigned int stdc_first_leading_zero_ull(unsigned long long value) +{ + return stdc_leading_ones_ull(~value); +} + +static inline unsigned int stdc_first_leading_zero_ul(unsigned long value) +{ + return stdc_leading_ones_ul(~value); +} + +static inline unsigned int stdc_first_leading_zero_ui(unsigned int value) +{ + return stdc_leading_ones_ui(~value); +} + +static inline unsigned int stdc_first_leading_zero_us(unsigned short value) +{ + return stdc_leading_ones_us(~value); +} + +static inline unsigned int stdc_first_leading_zero_uc(unsigned char value) +{ + return stdc_leading_ones_uc(~value); +} + +#define stdc_first_leading_zero(value) \ + __stdbit_generic_type_func(first_leading_zero, value) + +#if defined (__GNUC__) || defined (__clang__) +static inline unsigned int stdc_first_trailing_one_ull(unsigned long long value) +{ + return __builtin_ffsll(value); +} + +static inline unsigned int stdc_first_trailing_one_ul(unsigned long value) +{ + return __builtin_ffsl(value); +} + +static inline unsigned int stdc_first_trailing_one_ui(unsigned int value) +{ + return __builtin_ffs(value); +} + +static inline unsigned int stdc_first_trailing_one_us(unsigned short value) +{ + return __builtin_ffs(value); +} + +static inline unsigned int stdc_first_trailing_one_uc(unsigned char value) +{ + return __builtin_ffs(value); +} +#else +static inline unsigned int stdc_first_trailing_one_ull(unsigned long long value) +{ + return value ? (1 + stdc_trailing_zeros_ull(value)) : 0; +} + +static inline unsigned int stdc_first_trailing_one_ul(unsigned long value) +{ + return value ? (1 + stdc_trailing_zeros_ul(value)) : 0; +} + +static inline unsigned int stdc_first_trailing_one_ui(unsigned int value) +{ + return value ? (1 + stdc_trailing_zeros_ui(value)) : 0; +} + +static inline unsigned int stdc_first_trailing_one_us(unsigned short value) +{ + return value ? (1 + stdc_trailing_zeros_us(value)) : 0; +} + +static inline unsigned int stdc_first_trailing_one_uc(unsigned char value) +{ + return value ? (1 + stdc_trailing_zeros_uc(value)) : 0; +} +#endif + +#define stdc_first_trailing_one(value) \ + __stdbit_generic_type_func(first_trailing_one, value) + +static inline unsigned int stdc_first_trailing_zero_ull(unsigned long long value) +{ + return stdc_first_trailing_one_ull(~value); +} + +static inline unsigned int stdc_first_trailing_zero_ul(unsigned long value) +{ + return stdc_first_trailing_one_ul(~value); +} + +static inline unsigned int stdc_first_trailing_zero_ui(unsigned int value) +{ + return stdc_first_trailing_one_ui(~value); +} + +static inline unsigned int stdc_first_trailing_zero_us(unsigned short value) +{ + return stdc_first_trailing_one_us(~value); +} + +static inline unsigned int stdc_first_trailing_zero_uc(unsigned char value) +{ + return stdc_first_trailing_one_uc(~value); +} + +#define stdc_first_trailing_zero(value) \ + __stdbit_generic_type_func(first_trailing_zero, value) + +#if defined (__GNUC__) || defined (__clang__) +static inline unsigned int stdc_count_ones_ull(unsigned long long value) +{ + return __builtin_popcountll(value); +} + +static inline unsigned int stdc_count_ones_ul(unsigned long value) +{ + return __builtin_popcountl(value); +} + +static inline unsigned int stdc_count_ones_ui(unsigned int value) +{ + return __builtin_popcount(value); +} + +static inline unsigned int stdc_count_ones_us(unsigned short value) +{ + return __builtin_popcount(value); +} + +static inline unsigned int stdc_count_ones_uc(unsigned char value) +{ + return __builtin_popcount(value); +} +#else +static inline unsigned int __stdc_count_ones(unsigned long long value, + unsigned int size) +{ + unsigned int ones = 0; + + for (unsigned int c = 0; c < (size * CHAR_BIT); c++) { + ones += value & 1; + value >>= 1; + } + + return ones; +} + +static inline unsigned int stdc_count_ones_ull(unsigned long long value) +{ + return __stdc_count_ones(value, sizeof (value)); +} + +static inline unsigned int stdc_count_ones_ul(unsigned long value) +{ + return __stdc_count_ones(value, sizeof (value)); +} + +static inline unsigned int stdc_count_ones_ui(unsigned int value) +{ + return __stdc_count_ones(value, sizeof (value)); +} + +static inline unsigned int stdc_count_ones_us(unsigned short value) +{ + return __stdc_count_ones(value, sizeof (value)); +} + +static inline unsigned int stdc_count_ones_uc(unsigned char value) +{ + return __stdc_count_ones(value, sizeof (value)); +} +#endif + +#define stdc_count_ones(value) \ + __stdbit_generic_type_func(count_ones, value) + +static inline unsigned int stdc_count_zeros_ull(unsigned long long value) +{ + return stdc_count_ones_ull(~value); +} + +static inline unsigned int stdc_count_zeros_ul(unsigned long value) +{ + return stdc_count_ones_ul(~value); +} + +static inline unsigned int stdc_count_zeros_ui(unsigned int value) +{ + return stdc_count_ones_ui(~value); +} + +static inline unsigned int stdc_count_zeros_us(unsigned short value) +{ + return stdc_count_ones_us(~value); +} + +static inline unsigned int stdc_count_zeros_uc(unsigned char value) +{ + return stdc_count_ones_uc(~value); +} + +#define stdc_count_zeros(value) \ + __stdbit_generic_type_func(count_zeros, value) + +static inline bool stdc_has_single_bit_ull(unsigned long long value) +{ + return value && (value & (value - 1)) == 0; +} + +static inline bool stdc_has_single_bit_ul(unsigned long value) +{ + return value && (value & (value - 1)) == 0; +} + +static inline bool stdc_has_single_bit_ui(unsigned int value) +{ + return value && (value & (value - 1)) == 0; +} + +static inline bool stdc_has_single_bit_us(unsigned short value) +{ + return value && (value & (value - 1)) == 0; +} + +static inline bool stdc_has_single_bit_uc(unsigned char value) +{ + return value && (value & (value - 1)) == 0; +} + +#define stdc_has_single_bit(value) \ + __stdbit_generic_type_func(has_single_bit, value) + +static inline unsigned int stdc_bit_width_ull(unsigned long long value) +{ + return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ull(value); +} + +static inline unsigned int stdc_bit_width_ul(unsigned long value) +{ + return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ul(value); +} + +static inline unsigned int stdc_bit_width_ui(unsigned int value) +{ + return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ui(value); +} + +static inline unsigned int stdc_bit_width_us(unsigned short value) +{ + return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_us(value); +} + +static inline unsigned int stdc_bit_width_uc(unsigned char value) +{ + return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_uc(value); +} + +#define stdc_bit_width(value) \ + __stdbit_generic_type_func(bit_width, value) + +static inline unsigned long long stdc_bit_floor_ull(unsigned long long value) +{ + return value ? (1ULL << (stdc_bit_width_ull(value) - 1)) : 0ULL; +} + +static inline unsigned long stdc_bit_floor_ul(unsigned long value) +{ + return value ? (1UL << (stdc_bit_width_ul(value) - 1)) : 0UL; +} + +static inline unsigned int stdc_bit_floor_ui(unsigned int value) +{ + return value ? (1U << (stdc_bit_width_ui(value) - 1)) : 0U; +} + +static inline unsigned short stdc_bit_floor_us(unsigned short value) +{ + return value ? (1U << (stdc_bit_width_us(value) - 1)) : 0U; +} + +static inline unsigned int stdc_bit_floor_uc(unsigned char value) +{ + return value ? (1U << (stdc_bit_width_uc(value) - 1)) : 0U; +} + +#define stdc_bit_floor(value) \ + __stdbit_generic_type_func(bit_floor, value) + +/* NOTE: Bit ceiling undefines overflow. */ +static inline unsigned long long stdc_bit_ceil_ull(unsigned long long value) +{ + return 1ULL << (value ? stdc_bit_width_ull(value - 1) : 0); +} + +static inline unsigned long stdc_bit_ceil_ul(unsigned long value) +{ + return 1UL << (value ? stdc_bit_width_ul(value - 1) : 0); +} + +static inline unsigned int stdc_bit_ceil_ui(unsigned int value) +{ + return 1U << (value ? stdc_bit_width_ui(value - 1) : 0); +} + +static inline unsigned short stdc_bit_ceil_us(unsigned short value) +{ + return 1U << (value ? stdc_bit_width_us(value - 1) : 0); +} + +static inline unsigned int stdc_bit_ceil_uc(unsigned char value) +{ + return 1U << (value ? stdc_bit_width_uc(value - 1) : 0); +} + +#define stdc_bit_ceil(value) \ + __stdbit_generic_type_func(bit_ceil, value) + +#endif /* __STDC_VERSION_STDBIT_H__ */ diff --git a/configure b/configure index 337172a6c6..83c0d02f8c 100755 --- a/configure +++ b/configure @@ -7766,6 +7766,10 @@ if disabled stdatomic; then fi fi +check_builtin stdbit "stdbit.h assert.h" \ + 'static_assert(__STDC_VERSION_STDBIT_H__ >= 202311L, "Compiler lacks stdbit.h")' || \ + add_cppflags '-I\$(SRC_PATH)/compat/stdbit' + # Check if requested libraries were found. for lib in $AUTODETECT_LIBS; do requested $lib && ! enabled $lib && die "ERROR: $lib requested but not found"; diff --git a/tests/ref/fate/source b/tests/ref/fate/source index 1703b36c02..78d3a2e0fa 100644 --- a/tests/ref/fate/source +++ b/tests/ref/fate/source @@ -24,6 +24,7 @@ Headers without standard inclusion guards: compat/djgpp/math.h compat/float/float.h compat/float/limits.h +compat/stdbit/stdbit.h libavcodec/bitstream_template.h tools/decode_simple.h Use of av_clip() where av_clip_uintp2() could be used: From patchwork Sat Sep 14 10:45:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51584 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp303464vqy; Sat, 14 Sep 2024 04:19:18 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCV9kTznN3FpAZtyf0xr1VtnV8c0U4Im9U5bqNdPsjKyvNIk5JKPO+bftaUkmn9KPR9YpY9JF7GSp/AETdaIY17k@gmail.com X-Google-Smtp-Source: AGHT+IEMW4uv2f4XIdkENaOs/UHWPs0+J5gD5j/3TxvNkvknhqZtsNZCv8LJ+VUq4KQiIYcsthvn X-Received: by 2002:a05:651c:2118:b0:2f7:528f:421e with SMTP id 38308e7fff4ca-2f79183a94emr31326201fa.0.1726312757868; Sat, 14 Sep 2024 04:19:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312757; cv=none; d=google.com; s=arc-20240605; b=hBTG++JqF5gv+FB856FzSjcteIfI5lHl3n3lOkFR7wd3aXkFbYiiCB84wzbbJM11Wc eBDguYrMw5iSUgpfef8P1yIqq/qM2Mk9TcW9QN7WhIvF2o4Uupfm4/T4C+uu3d0siRyz ciqX5riZIRRsbPmF+aMvXF6Ua6bXorbFogLBOnTDsO94v3f4nKhRa5YwLpF5XyATcmEk Krv/jcTvzb7eh9XICbAD6v4/dUGwAf8F9626tvtYO592q9sxIUdqgJ+VYiDJzebo4CA+ kUPIm6CQP163LV9LMSzbQVXQvwzCQ9UREco4AO3Oc3RoE7ouX00Z3a8oJZH6JoQNjNQY K03A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=1oK6F2ENs5tB1kwzOzbl87r1ByhovFyjAQkUJoSyD3M=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=h0zRScHNKCeixRZ0Va7O8xNsuMzE//xBQ/SGROMOVmFH6yfXZOK4mnyL60kB0YUSbL 6otwQ4nXv7U8MFfl/R/IwYi8a/7vOpTwVj88IwISJD+Lm/9JKnh0ZtIUF863A5MfkDJB yi9/4Cw3jBbL3aMi+aAPqijBPeOUQFpmacKkwMh0ChmLxin4dP2iSjPRJXzDekZAIQKv /dtsikRCnqZO8sw9+PDNNyw6u0dtJDerEabNEEqcTkVp+lqyvul1htCELAnDYZ6gEOfx ylqWb5tXuRXG/vHloAKMuBXGtAPhnukUSqxYcXr7oS/7bfouluCUW9tCqm+4A5OP6Sh6 feRQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=D4aXoHYw; 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 38308e7fff4ca-2f79d379421si3826991fa.424.2024.09.14.04.19.17; Sat, 14 Sep 2024 04:19:17 -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=@khirnov.net header.s=mail header.b=D4aXoHYw; 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 7152568DE55; Sat, 14 Sep 2024 14:11:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9B0EC68DDB7 for ; Sat, 14 Sep 2024 14:10:58 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=D4aXoHYw; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id B30964E19 for ; Sat, 14 Sep 2024 13:10:53 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id yULxOZQZHHqj for ; Sat, 14 Sep 2024 13:10:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312247; bh=B/tN+efWZV3qNoGWsDUmkU7a7Izm27QXJxCim1SyEno=; h=From:To:Subject:Date:In-Reply-To:References:From; b=D4aXoHYwsuF3+0VN1WDFY5e3iP4MuzSMaDLsuzMQo4MNbSx6TF+ih9OHIbFWmtyIK 05H4gRpLXBFxBEANS1ca1kzKCLzedecBtGz76O5eGb9NdVEvfnO/D02H2xtbSdNDlQ Ee/pK8NxUW+gfcU6V/5mE67rJrNWCD2qbsPgRX64Y5d2QVoWqs/hilZEspjhsqwSrZ JUBPPnVRZUdJMjfGCQKuw0xJ2YEYoEJ/jnqTv9m2lJ2sEYlQJM2m7z5S6upz4yZH+t 7ZDJtgefzGcaFqvD/8E2/CJF1rTClLTmlYmsK6qCwo+GkNU6G8rHCLIFAXj7qlw44E 22QeCJeBsrKgw== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id A740B4DE6 for ; Sat, 14 Sep 2024 13:10:47 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id F1D573A0F02 for ; Sat, 14 Sep 2024 13:10:40 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:28 +0200 Message-ID: <20240914111036.17164-4-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 03/23] lavu/frame: add side data storing view ID for multi-view video 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: sMAc/kjwn83r --- doc/APIchanges | 3 +++ fftools/ffprobe.c | 2 ++ libavfilter/vf_showinfo.c | 2 ++ libavutil/frame.c | 1 + libavutil/frame.h | 9 +++++++++ libavutil/version.h | 2 +- 6 files changed, 18 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 830a38cd69..189932c99c 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07 API changes, most recent first: +2024-xx-xx - xxxxxxx - lavu 59.37.100 - frame.h + Add AV_FRAME_DATA_VIEW_ID. + 2024-09-xx - xxxxxxxxxx - lavc 61.13.100 - avcodec.h Add avcodec_get_supported_config() and enum AVCodecConfig; deprecate AVCodec.pix_fmts, AVCodec.sample_fmts, AVCodec.supported_framerates, diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index bf5ebe3ce0..14b98d22a1 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -2920,6 +2920,8 @@ static void print_frame_side_data(WriterContext *w, } else if (sd->type == AV_FRAME_DATA_FILM_GRAIN_PARAMS) { AVFilmGrainParams *fgp = (AVFilmGrainParams *)sd->data; print_film_grain_params(w, fgp); + } else if (sd->type == AV_FRAME_DATA_VIEW_ID) { + print_int("view_id", *(int*)sd->data); } writer_print_section_footer(w); } diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index f81df9d1bf..77082505f5 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -857,6 +857,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) case AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT: dump_ambient_viewing_environment(ctx, sd); break; + case AV_FRAME_DATA_VIEW_ID: + av_log(ctx, AV_LOG_INFO, "view id: %d\n", *(int*)sd->data); default: if (name) av_log(ctx, AV_LOG_INFO, diff --git a/libavutil/frame.c b/libavutil/frame.c index 5cbfc6a48b..891909fc2a 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -46,6 +46,7 @@ static const AVSideDataDescriptor sd_props[] = { [AV_FRAME_DATA_DETECTION_BBOXES] = { "Bounding boxes for object detection and classification" }, [AV_FRAME_DATA_DOVI_RPU_BUFFER] = { "Dolby Vision RPU Data" }, [AV_FRAME_DATA_DOVI_METADATA] = { "Dolby Vision Metadata" }, + [AV_FRAME_DATA_VIEW_ID] = { "View ID" }, [AV_FRAME_DATA_STEREO3D] = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL }, [AV_FRAME_DATA_REPLAYGAIN] = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL }, [AV_FRAME_DATA_DISPLAYMATRIX] = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL }, diff --git a/libavutil/frame.h b/libavutil/frame.h index 60bb966f8b..cea1c68df5 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -228,6 +228,15 @@ enum AVFrameSideDataType { * encoding. */ AV_FRAME_DATA_VIDEO_HINT, + + /** + * This side data must be associated with a video frame. + * The presence of this side data indicates that the video stream is + * composed of multiple views (e.g. stereoscopic 3D content, + * cf. H.264 Annex H or H.265 Annex G). + * The data is an int storing the view ID. + */ + AV_FRAME_DATA_VIEW_ID, }; enum AVActiveFormatDescription { diff --git a/libavutil/version.h b/libavutil/version.h index 25a6f5531b..7900379c12 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 59 -#define LIBAVUTIL_VERSION_MINOR 36 +#define LIBAVUTIL_VERSION_MINOR 37 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From patchwork Sat Sep 14 10:45:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51587 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp305326vqy; Sat, 14 Sep 2024 04:24:19 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCW0l9Go5DxqbH6DEjVzdQs4mb6ATRSuYcLMbOeJS/iWS0XZORZa5fdtNjAIgf/PxQf72lXps3qVifYl66mhk57k@gmail.com X-Google-Smtp-Source: AGHT+IFGQrDH4VDsUpkL9QLXQ4AMs6akEQxYKqJCs9+tM90KzxD39rDwoLobPttEbzp5od9SAXam X-Received: by 2002:a05:6402:1f49:b0:5a2:5bd2:ca50 with SMTP id 4fb4d7f45d1cf-5c413e4a430mr7415592a12.25.1726313059356; Sat, 14 Sep 2024 04:24:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313059; cv=none; d=google.com; s=arc-20240605; b=V8c950Z0mcl0KsNqBupS0QzVxdILRtxJQLYepSd6TF5ViVTAwgdxp4Hzbh3Ufv7+vJ YiZqXgb1DCXfX9oWN6SbeAuYR3Slfpi1iRT6z51u/tqX0aoZq/lWwciFjZdAwMqw2k8p bc7iGpZi6BqdODy9Ml6q07m4d1BkGfPDgY6+DZrWgeFaDxjNhb+TuPvpzoY7G5qLfOHB ZUMuBtF553emI0zgPqoJadMoiJLGj/HEBaowD8zqyt/8A16lEsk9ZXZP5zoQbrn3HMVR 3Id8ma8l0A0K1e3ahF85uNCgAsownYzALWJlmnYc9uKVZ/6zJprlo4AXGUVaSf+bGaKM 9ydw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=9KM0df2x9DKydAiCS/6/F1zOGQsEu3AdM8LMGKMuCQ8=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=F+8aD0LVV8bjT9qqeJqLMADOGfrdb+ydMjzSyXphlDDhclD6VhYOMQPuqF2HkRcw6J yqGB3DIeGVyIwGvD0F4twvf5AWjv2YAlkY6bJ02uOo8ICJwCDZ+KT6GqpIhqRoDws8Y1 CFnTJFajrMKUBtNyIyI6m+CLXI6ALe7qm3hs1WmVkQtOp1kvWPeFWJssyeJcUvwXLCh4 4q6YiDcwKQwAhRTN4333+yPP/ABDTRpidXsCMPQQG8SK0qSl8PTXy9w3mcxKUjfWdWbS 1E9LiiDOXMLmGDLm1zdigBBB5WYZ3kIHitxlgBJkc0FOPSvpGgxobTs2IAqNijGUzkWO pn7A==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=rH+YIBeY; 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 4fb4d7f45d1cf-5c42bcad6cbsi894019a12.590.2024.09.14.04.24.19; Sat, 14 Sep 2024 04:24:19 -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=@khirnov.net header.s=mail header.b=rH+YIBeY; 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 12DAF68DEBC; Sat, 14 Sep 2024 14:11:19 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 594C568DDB8 for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=rH+YIBeY; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 723934E18 for ; Sat, 14 Sep 2024 13:10:53 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id wBm-eDz8cq7r for ; Sat, 14 Sep 2024 13:10:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312247; bh=7K/ZePx6g8YsvW3xlAQjL4Ml731S26xthAl/ld0zQgI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=rH+YIBeYG285j/bBPNLLTlQ5+gKinP2CdzPm+hPWwtdEoHoeyaFwUiUjmCk5bXmpC /AsEUmEcRsNJWZrbmnkau2JsGHf81SqTdF9gyJVlgBf4O8y7Jh35vPKv1A/GFlmlg6 lA8pDN4K95KQRAj/3uIAK6j/HTn0fqheHmAqakEIyCgGZq+rfQUhlb2Df+C9zfmXL3 PGvvTt0WgaoI7HhYTnjBdw+ANqYzMkl41kw8HeyrIumpijSnKjsuJHpQBha0z/GGV4 01R5CnDFp94G2jQgSbJ/CiAdWHYLSiand7QwTvx3UbsFvW8zvbN//sh7gIOIzN6jNp dZs+jydpgkF0Q== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id AA7FC4E2B for ; Sat, 14 Sep 2024 13:10:47 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 0914F3A0F41 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:29 +0200 Message-ID: <20240914111036.17164-5-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 04/23] lavfi/f_select: allow selection based on view ID 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: /2vEf1cZzNFa Can be used together with the split filter to decompose multiview video into individual views. --- doc/filters.texi | 3 +++ libavfilter/f_select.c | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index db2f4b7ea7..428986a1e9 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -31111,6 +31111,9 @@ Represents the width of the input video frame. @item ih @emph{(video only)} Represents the height of the input video frame. +@item view @emph{(video only)} +View ID for multi-view video. + @end table The default value of the select expression is "1". diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c index 6ba96bd7c5..ba0ae31f1b 100644 --- a/libavfilter/f_select.c +++ b/libavfilter/f_select.c @@ -93,6 +93,8 @@ static const char *const var_names[] = { "ih", ///< ih: Represents the height of the input video frame. "iw", ///< iw: Represents the width of the input video frame. + "view", + NULL }; @@ -150,6 +152,8 @@ enum var_name { VAR_IH, VAR_IW, + VAR_VIEW, + VAR_VARS_NB }; @@ -343,6 +347,7 @@ static void select_frame(AVFilterContext *ctx, AVFrame *frame) SelectContext *select = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; FilterLink *inl = ff_filter_link(inlink); + const AVFrameSideData *sd; double res; if (isnan(select->var_values[VAR_START_PTS])) @@ -381,6 +386,10 @@ FF_ENABLE_DEPRECATION_WARNINGS snprintf(buf, sizeof(buf), "%f", select->var_values[VAR_SCENE]); av_dict_set(&frame->metadata, "lavfi.scene_score", buf, 0); } + + sd = av_frame_side_data_get(frame->side_data, frame->nb_side_data, + AV_FRAME_DATA_VIEW_ID); + select->var_values[VAR_VIEW] = sd ? *(int*)sd->data : NAN; break; } From patchwork Sat Sep 14 10:45:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51582 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp300465vqy; Sat, 14 Sep 2024 04:11:37 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX9YMUUtQXP9qWlvvI2TePcLH78W5KFvAsbNPCHkvnr4HqpcT7jJzoC2tKuj+IasiPMRXQJZn2UpThwlOuJqAGu@gmail.com X-Google-Smtp-Source: AGHT+IEtQXTBy985D24hho/alo6Fbt8b8ZvONFriHNfRmX+tnCuIa6lrOTVpXiZGdThlpBQa6X/0 X-Received: by 2002:a05:6402:1f0e:b0:5be:fa43:8017 with SMTP id 4fb4d7f45d1cf-5c413e1eecbmr7523943a12.16.1726312296869; Sat, 14 Sep 2024 04:11:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312296; cv=none; d=google.com; s=arc-20240605; b=imjRzvrMLjSv5gAFUzR5Ze4DkkPZdJ6o8S5ZqTv2R657GUFuhqkCLK6gY/9kVY21c7 Pbq4FpLv9UyWyYV5w849efw70vff4+DZYu/BRfbQUlC5RXyDo0KnMgu8THFmCrEgHWdu uuBJ3td/8Jgol8LsEkvQdoLcHgv+6XtP6SXx/xhxrPI6rkrcpqJ+UUL0tPS5V0GaxPWO GfK8RBIL4faXd1uNjGJK7LIy5dWNNovacCYQS7G3iPH8//riaW9BpeqqE7UUHhPLr47+ g45DyiLncGHvuPpEE2yM35cg9tGZe0BWN4WEUG7OFhRBnJaJVTXddad7Cf+rKsfC8gzr tK4g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=EnEMeHKgqbE+5BncJOMAwRWS4xs8qZ7nPTJFwbYRk80=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=Q3v4brwd7q7+XYCiZ/Pnr93M88nODp/6m8sTeSdfalt9ZjQqpCvwxttDK591hRxV9C He9aLvJZbZditAT1MRvxifsvOWx2fIUjqJIIXWPIT+4FAN/xdwRQnY9mewrDxFufLj5e 0Ercae+uRQToxCgkB3WyvdE8AHlmGe+g9QtHV32Yf9izytYuYlk976vY2SZ5lTMQwoNy E7MsMMLanGbhVn1sNkXmOkN0QOrPGyqsGeP5Ax1IXUe3DN9dcSTE5oyZyk5lYGM8sOAE pviEAObfPmlbedHZxPL9s9Tv2RdOOKuePHWp+BopEYzp9Hjfr9NvuIZ+gn9BUP527OVy gXIA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=dW5Q64wd; 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 4fb4d7f45d1cf-5c42bb4e462si877853a12.118.2024.09.14.04.11.36; Sat, 14 Sep 2024 04:11:36 -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=@khirnov.net header.s=mail header.b=dW5Q64wd; 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 B780368DC74; Sat, 14 Sep 2024 14:10:57 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9F27068DA8C for ; Sat, 14 Sep 2024 14:10:48 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=dW5Q64wd; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 46BDA4E05 for ; Sat, 14 Sep 2024 13:10:48 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id pfoPs8ZkA7St for ; Sat, 14 Sep 2024 13:10:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=6f436dYgo2JIPWb15eOwwHI16m3E0danxEWK0Vj+ZUw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=dW5Q64wdEeZaL8oH/GOr90uOUqs+9xo5+4uI5G7f8v6xpWpC3RJgX0HVkeL81NoCT b762BCGrIPfUCZcVHWzYl2Wem9fHr7sjIf/yz45ZtoQMd+UUitDowMESCmhzSIeeyc n7dXVPrUwDdNLsVcsFL8Tl+LorlIxvS/6UcUq0uPVH5azqfKEZ8bjNq1fgs8dO3Vz9 J5ifSRrhsU/8BQxG5QFb2KKhapPHd2lfkaa0F55z6955aKQH9+STIRl4k0OkfiLLCV CkTgyVZ5tPvo/XZq+06RfiZ94xf/obOJNeVA+sMXKXEKnKQbnYoj/5EWDtxBV1HutG pKC6JKkEAj2bQ== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 57AFA4DEE for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 142BA3A0F6F for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:30 +0200 Message-ID: <20240914111036.17164-6-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 05/23] avcodec/hevc/sei: add support for 3D Reference Displays Information SEI 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: o0XXqZu2l85a From: James Almer Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavcodec/hevc/sei.c | 55 +++++++++++++++++++++++++++++++++++++++++++ libavcodec/hevc/sei.h | 17 +++++++++++++ 2 files changed, 72 insertions(+) diff --git a/libavcodec/hevc/sei.c b/libavcodec/hevc/sei.c index b55ba71a8d..e11a33773c 100644 --- a/libavcodec/hevc/sei.c +++ b/libavcodec/hevc/sei.c @@ -150,6 +150,59 @@ static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb) return 0; } +static int decode_nal_sei_3d_reference_displays_info(HEVCSEITDRDI *s, GetBitContext *gb) +{ + s->prec_ref_display_width = get_ue_golomb(gb); + if (s->prec_ref_display_width > 31) + return AVERROR_INVALIDDATA; + s->ref_viewing_distance_flag = get_bits1(gb); + if (s->ref_viewing_distance_flag) { + s->prec_ref_viewing_dist = get_ue_golomb(gb); + if (s->prec_ref_viewing_dist > 31) + return AVERROR_INVALIDDATA; + } + s->num_ref_displays = get_ue_golomb(gb); + if (s->num_ref_displays > 31) + return AVERROR_INVALIDDATA; + s->num_ref_displays += 1; + + for (int i = 0; i < s->num_ref_displays; i++) { + int length; + s->left_view_id[i] = get_ue_golomb(gb); + s->right_view_id[i] = get_ue_golomb(gb); + s->exponent_ref_display_width[i] = get_bits(gb, 6); + if (s->exponent_ref_display_width[i] > 62) + return AVERROR_INVALIDDATA; + else if (!s->exponent_ref_display_width[i]) + length = FFMAX(0, (int)s->prec_ref_display_width - 30); + else + length = FFMAX(0, (int)s->exponent_ref_display_width[i] + + (int)s->prec_ref_display_width - 31); + s->mantissa_ref_display_width[i] = get_bits_long(gb, length); + if (s->ref_viewing_distance_flag) { + s->exponent_ref_viewing_distance[i] = get_bits(gb, 6); + if (s->exponent_ref_viewing_distance[i] > 62) + return AVERROR_INVALIDDATA; + else if (!s->exponent_ref_viewing_distance[i]) + length = FFMAX(0, (int)s->prec_ref_viewing_dist - 30); + else + length = FFMAX(0, (int)s->exponent_ref_viewing_distance[i] + + (int)s->prec_ref_viewing_dist - 31); + s->mantissa_ref_viewing_distance[i] = get_bits_long(gb, length); + } + s->additional_shift_present_flag[i] = get_bits1(gb); + if (s->additional_shift_present_flag[i]) { + s->num_sample_shift[i] = get_bits(gb, 10); + if (s->num_sample_shift[i] > 1023) + return AVERROR_INVALIDDATA; + s->num_sample_shift[i] -= 512; + } + } + s->three_dimensional_reference_displays_extension_flag = get_bits1(gb); + + return 0; +} + static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int type) @@ -163,6 +216,8 @@ static int decode_nal_sei_prefix(GetBitContext *gb, GetByteContext *gbyte, return decode_nal_sei_active_parameter_sets(s, gb, logctx); case SEI_TYPE_TIME_CODE: return decode_nal_sei_timecode(&s->timecode, gb); + case SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO: + return decode_nal_sei_3d_reference_displays_info(&s->tdrdi, gb); default: { int ret = ff_h2645_sei_message_decode(&s->common, type, AV_CODEC_ID_HEVC, gb, gbyte, logctx); diff --git a/libavcodec/hevc/sei.h b/libavcodec/hevc/sei.h index c97d22d423..a9d6a52080 100644 --- a/libavcodec/hevc/sei.h +++ b/libavcodec/hevc/sei.h @@ -79,12 +79,29 @@ typedef struct HEVCSEITimeCode { int32_t time_offset_value[3]; } HEVCSEITimeCode; +typedef struct HEVCSEITDRDI { + uint8_t prec_ref_display_width; + uint8_t ref_viewing_distance_flag; + uint8_t prec_ref_viewing_dist; + uint8_t num_ref_displays; + uint16_t left_view_id[31]; + uint16_t right_view_id[31]; + uint8_t exponent_ref_display_width[31]; + uint8_t mantissa_ref_display_width[31]; + uint8_t exponent_ref_viewing_distance[31]; + uint8_t mantissa_ref_viewing_distance[31]; + uint8_t additional_shift_present_flag[31]; + int16_t num_sample_shift[31]; + uint8_t three_dimensional_reference_displays_extension_flag; +} HEVCSEITDRDI; + typedef struct HEVCSEI { H2645SEI common; HEVCSEIPictureHash picture_hash; HEVCSEIPictureTiming picture_timing; int active_seq_parameter_set_id; HEVCSEITimeCode timecode; + HEVCSEITDRDI tdrdi; } HEVCSEI; struct HEVCParamSets; From patchwork Sat Sep 14 10:45:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51597 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp314343vqy; Sat, 14 Sep 2024 04:49:11 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWQpbfW/SVDCqBj/x7UcBGGvUSBPFbIeQDe8EVkpMub8DnghcCM8Xta3d0rp6XkcbKhbU247lQIqTziyFpwvGFK@gmail.com X-Google-Smtp-Source: AGHT+IEMT7QsCASqY2IGYSyIVMF7X5t7he5URe5TX4DAPykBt2xVe5l/w5jKs4RJAyiXRbx0Zo9F X-Received: by 2002:a05:6512:2812:b0:536:561c:a0cb with SMTP id 2adb3069b0e04-53678fb6d6amr5352958e87.18.1726314551053; Sat, 14 Sep 2024 04:49:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726314551; cv=none; d=google.com; s=arc-20240605; b=Ue/jETM5NMVLt/StVBKyYBb5sERj7s7QVJbv6b7akBB+0sCYLJ+nfWICuecwQc5plX qYi48LCgUUR++MXf1VDTiVe6NZXy5MzP9ajKqVIkCV/51J2mbh2qfPt7DkAr5UKd8UOg kAUztu6F8/JZK2VGK/UUxRcQCpp2aORR+9s3B+BY3WtAOLbDrnTUGxvWTZlF7AVsI1gE cgHdCwb0DbNwB2jUnkWLOd82L3EYbWzDz1k2y8j+RkepRYogPNYk181Za4Y3pbgZ95qK G4uV6C9KRe0n43i+jdgPzKC58hngDIOO9nGAFBSTqj2py6dE0BdiQ4RhEormkrugsHu0 3JsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=U7gQ1NFnH1yp5IAp1w8kS/b9pL3l+mcHmT7iInaiDOc=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=HpshlV13EVG3d8D8se32QIVamTH5FFWzpXliilycLtXEEXRmGsSk5u7KMRbIZTSvSe j7ZPdLYLph951jNZyZSDMgvqSsUOWibX2K+wJimml3CiuTab6L67xUtdvLz6kvs0GlFA E+8pM06HbMSFrU536ylvUzIrRKNZiTMqLaCnf7YUOchrygCdRoEqVVirlTUOWHDJ2bsN QZncgRwSG7Tnj/IlofYK/UbkPrOzViXlugFUFmYjaxAchkCu4XhLY2bwvI13KFoBv742 Vqhb14sL9TRKulp2lII/IsOBU+tlPh/UGt+dLaXUfOZqRrxhJD/Ndmn43TbSSGF/xXYx johQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=MOSTg3Uh; 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 2adb3069b0e04-53687048fd9si419601e87.140.2024.09.14.04.49.10; Sat, 14 Sep 2024 04:49:10 -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=@khirnov.net header.s=mail header.b=MOSTg3Uh; 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 9A34B68DE3E; Sat, 14 Sep 2024 14:11:05 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6268D68DC92 for ; Sat, 14 Sep 2024 14:10:53 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=MOSTg3Uh; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 13A484E0A for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id 86F1z6F3B88B for ; Sat, 14 Sep 2024 13:10:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=PJb6qu3lnTtU922ZwFxhb8LQe0fXZVsT/CmQop5eQQg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=MOSTg3UhZifYOIpNN6EOPfBHx+WBDw35EznfStrAED60smCQZmAtXC3ezUz+o0O7s 8XdGMKzE0ZyPxWOaEbsSukPN0HNxGHVRPTAqZPYftROePq/HPaLd+FvPjShgvUeax1 hFEmz5jUNcba1lpJnRXnUk7hjicR/3z4Jb+5peAsrn7sZPA2vTVRYE0niGhspMCFRJ 3Z7Mx4oGJzEh3SwlYH8voqNIVjZKB9YSFppQoHqAVOAsf8l1hTtZ4HelRGUkCgYsMk UkTtRFOfhwkt00mwxSYReyOX4y2dKCdTZMT+Btr2hEI+zR1tYBCQMF2875idSBiOrE e6Sp2Z0U2mvuQ== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 60A624E07 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 1FCEB3A164C for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:31 +0200 Message-ID: <20240914111036.17164-7-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 06/23] lavc/hevc_ps: parse VPS extension 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: j4UeYi3W8Pfl From: Niklas Haas Only implementing what's needed for MV-HEVC with two views. Signed-off-by: Anton Khirnov --- libavcodec/hevc/hevc.h | 9 +- libavcodec/hevc/ps.c | 307 +++++++++++++++++++++++++++++++++++++++-- libavcodec/hevc/ps.h | 62 +++++++++ 3 files changed, 364 insertions(+), 14 deletions(-) diff --git a/libavcodec/hevc/hevc.h b/libavcodec/hevc/hevc.h index 9fdbc0a224..8bd59142db 100644 --- a/libavcodec/hevc/hevc.h +++ b/libavcodec/hevc/hevc.h @@ -100,11 +100,14 @@ enum HEVCSliceType { enum { // 7.4.3.1: vps_max_layers_minus1 is in [0, 62]. - HEVC_MAX_LAYERS = 63, + HEVC_MAX_LAYERS = 63, // 7.4.3.1: vps_max_sub_layers_minus1 is in [0, 6]. - HEVC_MAX_SUB_LAYERS = 7, + HEVC_MAX_SUB_LAYERS = 7, // 7.4.3.1: vps_num_layer_sets_minus1 is in [0, 1023]. - HEVC_MAX_LAYER_SETS = 1024, + HEVC_MAX_LAYER_SETS = 1024, + // 7.4.3.1: vps_max_layer_id is in [0, 63]. + HEVC_MAX_LAYER_ID = 63, + HEVC_MAX_NUH_LAYER_ID = 62, // 7.4.2.1: vps_video_parameter_set_id is u(4). HEVC_MAX_VPS_COUNT = 16, diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index 2c3b335966..35de26644c 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -311,11 +311,17 @@ static int decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx, } static int parse_ptl(GetBitContext *gb, AVCodecContext *avctx, - PTL *ptl, int max_num_sub_layers) + int profile_present, PTL *ptl, int max_num_sub_layers) { - int i; - if (decode_profile_tier_level(gb, avctx, &ptl->general_ptl) < 0 || - get_bits_left(gb) < 8 + (8*2 * (max_num_sub_layers - 1 > 0))) { + int i, status = 0; + + if (profile_present) { + status = decode_profile_tier_level(gb, avctx, &ptl->general_ptl); + } else { + memset(&ptl->general_ptl, 0, sizeof(ptl->general_ptl)); + } + + if (status < 0 || get_bits_left(gb) < 8 + (8*2 * (max_num_sub_layers - 1 > 0))) { av_log(avctx, AV_LOG_ERROR, "PTL information too short\n"); return -1; } @@ -444,13 +450,273 @@ static void hevc_vps_free(FFRefStructOpaque opaque, void *obj) av_freep(&vps->data); } +enum ScalabilityMask { + HEVC_SCALABILITY_DEPTH = 0, + HEVC_SCALABILITY_MULTIVIEW = 1, + HEVC_SCALABILITY_SPATIAL = 2, + HEVC_SCALABILITY_AUXILIARY = 3, + HEVC_SCALABILITY_MASK_MAX = 15, +}; + +enum DependencyType { + HEVC_DEP_TYPE_SAMPLE = 0, + HEVC_DEP_TYPE_MV = 1, + HEVC_DEP_TYPE_BOTH = 2, +}; + +static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps, + uint64_t layer1_id_included) +{ + PTL ptl_dummy; + uint8_t max_sub_layers[HEVC_MAX_LAYERS]; + + int splitting_flag, dimension_id_len, view_id_len, num_add_olss, + default_output_layer_idc, direct_dep_type_len, direct_dep_type, + sub_layers_max_present, sub_layer_flag_info_present_flag, nb_ptl; + unsigned non_vui_extension_length; + + if (vps->vps_max_layers == 1 || vps->vps_num_layer_sets == 1) { + av_log(avctx, AV_LOG_VERBOSE, "Ignoring VPS extensions with a single layer\n"); + return 0; + } + + if (vps->vps_max_layers > 2) { + av_log(avctx, AV_LOG_ERROR, + "VPS has %d layers, only 2 layers are supported\n", + vps->vps_max_layers); + return AVERROR_PATCHWELCOME; + } + if (vps->vps_num_layer_sets > 2) { + av_log(avctx, AV_LOG_ERROR, + "VPS has %d layer sets, only 2 layer sets are supported\n", + vps->vps_num_layer_sets); + return AVERROR_PATCHWELCOME; + } + + align_get_bits(gb); + + /** + * For stereoscopic MV-HEVC, the following simplifying assumptions are made: + * + * - vps_max_layers = 2 (one base layer, one multiview layer) + * - vps_num_layer_sets = 2 (one output layer set for each view) + * - NumScalabilityTypes = 1 (only HEVC_SCALABILITY_MULTIVIEW) + * - direct_dependency_flag[1][0] = 1 (second layer depends on first) + * - num_add_olss = 0 (no extra output layer sets) + * - default_output_layer_idc = 0 (1:1 mapping between OLSs and layers) + * - layer_id_included_flag[1] = {1, 1} (consequence of layer dependencies) + * - vps_num_rep_formats_minus1 = 0 (all layers have the same size) + * + * Which results in the following derived variables: + * - ViewOrderIdx = {0, 1} + * - NumViews = 2 + * - DependencyFlag[1][0] = 1 + * - NumDirectRefLayers = {0, 1} + * - NumRefLayers = {0, 1} + * - NumPredictedLayers = {1, 0} + * - NumIndependentLayers = 1 + * - NumLayersInTreePartition = {2} + * - NumLayerSets = 2 + * - NumOutputLayerSets = 2 + * - OlsIdxToLsIdx = {0, 1} + * - LayerIdxInVps = {0, 1} + * - NumLayersInIdList = {1, 2} + * - NumNecessaryLayers = {1, 2} + * - NecessaryLayerFlag = {{1, 0}, {1, 1}} + * - NumOutputLayersInOutputLayerSet = {1, 2} + * - OutputLayerFlag = {{1, 0}, {1, 1}} + */ + vps->nb_layers = 2; + + if (parse_ptl(gb, avctx, 0, &ptl_dummy, vps->vps_max_sub_layers) < 0) + return AVERROR_INVALIDDATA; + + splitting_flag = get_bits1(gb); + for (int i = 0; i <= HEVC_SCALABILITY_MASK_MAX; i++) { + int scalability_mask_flag = get_bits1(gb); + if (scalability_mask_flag != (i == HEVC_SCALABILITY_MULTIVIEW)) { + av_log(avctx, AV_LOG_ERROR, "Scalability type %d not supported\n", i); + return AVERROR_PATCHWELCOME; + } + } + + if (!splitting_flag) + dimension_id_len = get_bits(gb, 3) + 1; + + if (get_bits1(gb)) { /* vps_nuh_layer_id_present_flag */ + int layer_id_in_nuh = get_bits(gb, 6); + if (layer_id_in_nuh >= FF_ARRAY_ELEMS(vps->layer_idx)) { + av_log(avctx, AV_LOG_ERROR, "Invalid layer_id_in_nuh[1]: %d\n", + layer_id_in_nuh); + return AVERROR_INVALIDDATA; + } + vps->layer_idx[layer_id_in_nuh] = 1; + vps->layer_id_in_nuh[1] = layer_id_in_nuh; + } else { + vps->layer_idx[1] = 1; + vps->layer_id_in_nuh[1] = 1; + } + + if (!splitting_flag) { + int view_idx = get_bits(gb, dimension_id_len); + if (view_idx != 1) { + av_log(avctx, AV_LOG_ERROR, "Unexpected ViewOrderIdx: %d\n", view_idx); + return AVERROR_PATCHWELCOME; + } + } + + view_id_len = get_bits(gb, 4); + if (view_id_len) + for (int i = 0; i < 2 /* NumViews */; i++) + vps->view_id[i] = get_bits(gb, view_id_len); + + if (!get_bits1(gb) /* direct_dependency_flag */) { + av_log(avctx, AV_LOG_WARNING, "Independent output layers not supported\n"); + return AVERROR_PATCHWELCOME; + } + vps->num_direct_ref_layers[1] = 1; + + sub_layers_max_present = get_bits1(gb); // vps_sub_layers_max_minus1_present_flag + for (int i = 0; i < vps->vps_max_layers; i++) + max_sub_layers[i] = sub_layers_max_present ? get_bits(gb, 3) + 1 : + vps->vps_max_sub_layers; + + if (get_bits1(gb) /* max_tid_ref_present_flag */) + skip_bits(gb, 3); // max_tid_il_ref_pics_plus1 + + vps->default_ref_layers_active = get_bits1(gb); + + nb_ptl = get_ue_golomb(gb) + 1; + /* idx [0] is signalled in base VPS, idx [1] is signalled at the + * start of VPS extension, indices 2+ are signalled here; + * we ignore all but the first one anyway */ + for (int i = 2; i < nb_ptl; i++) { + int profile_present = get_bits1(gb); + if (parse_ptl(gb, avctx, profile_present, &ptl_dummy, vps->vps_max_sub_layers) < 0) + return AVERROR_INVALIDDATA; + } + + num_add_olss = get_ue_golomb(gb); + if (num_add_olss != 0) { + /* Since we don't implement support for independent output layer sets + * and auxiliary layers, this should never nonzero */ + av_log(avctx, AV_LOG_ERROR, "Unexpected num_add_olss: %d\n", num_add_olss); + return AVERROR_PATCHWELCOME; + } + + default_output_layer_idc = get_bits(gb, 2); + if (default_output_layer_idc != 0) { + av_log(avctx, AV_LOG_WARNING, "Unsupported default_output_layer_idc: %d\n", + default_output_layer_idc); + return AVERROR_PATCHWELCOME; + } + + /* Consequence of established layer dependencies */ + if (layer1_id_included != ((1 << vps->layer_id_in_nuh[0]) | + (1 << vps->layer_id_in_nuh[1]))) { + av_log(avctx, AV_LOG_ERROR, "Dependent layer not included in layer ID?\n"); + return AVERROR_PATCHWELCOME; + } + + vps->num_output_layer_sets = 2; + vps->ols[1] = 3; + + for (int j = 0; j < av_popcount64(vps->ols[1]); j++) { + int ptl_idx = get_bits(gb, av_ceil_log2(nb_ptl)); + if (ptl_idx < 1 || ptl_idx >= nb_ptl) { + av_log(avctx, AV_LOG_ERROR, "Invalid PTL index: %d\n", ptl_idx); + return AVERROR_INVALIDDATA; + } + } + + if (get_ue_golomb_31(gb) != 0 /* vps_num_rep_formats_minus1 */) { + av_log(avctx, AV_LOG_ERROR, "Unexpected extra rep formats\n"); + return AVERROR_INVALIDDATA; + } + + vps->rep_format.pic_width_in_luma_samples = get_bits(gb, 16); + vps->rep_format.pic_height_in_luma_samples = get_bits(gb, 16); + + if (!get_bits1(gb) /* chroma_and_bit_depth_vps_present_flag */) { + av_log(avctx, AV_LOG_ERROR, + "chroma_and_bit_depth_vps_present_flag=0 in first rep_format\n"); + return AVERROR_INVALIDDATA; + } + vps->rep_format.chroma_format_idc = get_bits(gb, 2); + if (vps->rep_format.chroma_format_idc == 3) + vps->rep_format.separate_colour_plane_flag = get_bits1(gb); + vps->rep_format.bit_depth_luma = get_bits(gb, 4) + 8; + vps->rep_format.bit_depth_chroma = get_bits(gb, 4) + 8; + if (vps->rep_format.bit_depth_luma > 16 || + vps->rep_format.bit_depth_chroma > 16 || + vps->rep_format.bit_depth_luma != vps->rep_format.bit_depth_chroma) { + av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %"PRIu8" %"PRIu8"\n", + vps->rep_format.bit_depth_luma, vps->rep_format.bit_depth_chroma); + return AVERROR_PATCHWELCOME; + } + + if (get_bits1(gb) /* conformance_window_vps_flag */) { + int vert_mult = hevc_sub_height_c[vps->rep_format.chroma_format_idc]; + int horiz_mult = hevc_sub_width_c[vps->rep_format.chroma_format_idc]; + vps->rep_format.conf_win_left_offset = get_ue_golomb(gb) * horiz_mult; + vps->rep_format.conf_win_right_offset = get_ue_golomb(gb) * horiz_mult; + vps->rep_format.conf_win_top_offset = get_ue_golomb(gb) * vert_mult; + vps->rep_format.conf_win_bottom_offset = get_ue_golomb(gb) * vert_mult; + } + + vps->max_one_active_ref_layer = get_bits1(gb); + vps->poc_lsb_aligned = get_bits1(gb); + + sub_layer_flag_info_present_flag = get_bits1(gb); + for (int j = 0; j < FFMAX(max_sub_layers[0], max_sub_layers[1]); j++) { + int sub_layer_dpb_info_present_flag = 1; + if (j > 0 && sub_layer_flag_info_present_flag) + sub_layer_dpb_info_present_flag = get_bits1(gb); + if (sub_layer_dpb_info_present_flag) { + for (int k = 0; k < av_popcount64(vps->ols[1]); k++) + vps->dpb_size.max_dec_pic_buffering = get_ue_golomb_long(gb) + 1; + vps->dpb_size.max_num_reorder_pics = get_ue_golomb_long(gb); + vps->dpb_size.max_latency_increase = get_ue_golomb_long(gb) - 1; + } + } + + direct_dep_type_len = get_ue_golomb_31(gb) + 2; + if (direct_dep_type_len > 32) { + av_log(avctx, AV_LOG_ERROR, "Invalid direct_dep_type_len: %d\n", + direct_dep_type_len); + return AVERROR_INVALIDDATA; + } + + skip_bits1(gb); /* direct_depenency_all_layers_flag */ + direct_dep_type = get_bits_long(gb, direct_dep_type_len); + if (direct_dep_type > HEVC_DEP_TYPE_BOTH) { + av_log(avctx, AV_LOG_WARNING, "Unsupported direct_dep_type: %d\n", + direct_dep_type); + return AVERROR_PATCHWELCOME; + } + + non_vui_extension_length = get_ue_golomb(gb); + if (non_vui_extension_length > 4096) { + av_log(avctx, AV_LOG_ERROR, "vps_non_vui_extension_length too large: %u\n", + non_vui_extension_length); + return AVERROR_INVALIDDATA; + } + skip_bits_long(gb, non_vui_extension_length * 8); + + if (get_bits1(gb)) // vps_vui_present_flag + av_log(avctx, AV_LOG_WARNING, "VPS VUI not supported\n"); + + return 0; +} + int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, HEVCParamSets *ps) { - int i,j; + int i; int vps_id = get_bits(gb, 4); ptrdiff_t nal_size = gb->buffer_end - gb->buffer; int ret = AVERROR_INVALIDDATA; + uint64_t layer1_id_included = 0; HEVCVPS *vps; if (ps->vps_list[vps_id]) { @@ -494,7 +760,7 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, goto err; } - if (parse_ptl(gb, avctx, &vps->ptl, vps->vps_max_sub_layers) < 0) + if (parse_ptl(gb, avctx, 1, &vps->ptl, vps->vps_max_sub_layers) < 0) goto err; vps->vps_sub_layer_ordering_info_present_flag = get_bits1(gb); @@ -526,9 +792,14 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, goto err; } - for (i = 1; i < vps->vps_num_layer_sets; i++) - for (j = 0; j <= vps->vps_max_layer_id; j++) - skip_bits(gb, 1); // layer_id_included_flag[i][j] + vps->num_output_layer_sets = 1; + vps->ols[0] = 1; + + // we support at most 2 layers, so ignore the others + if (vps->vps_num_layer_sets > 1) + layer1_id_included = get_bits64(gb, vps->vps_max_layer_id + 1); // layer_id_included_flag + if (vps->vps_num_layer_sets > 2) + skip_bits_long(gb, (vps->vps_num_layer_sets - 2) * (vps->vps_max_layer_id + 1)); vps->vps_timing_info_present_flag = get_bits1(gb); if (vps->vps_timing_info_present_flag) { @@ -560,7 +831,21 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, vps->vps_max_sub_layers); } } - get_bits1(gb); /* vps_extension_flag */ + + vps->nb_layers = 1; + vps->layer_idx[0] = 0; + for (int i = 1; i < FF_ARRAY_ELEMS(vps->layer_idx); i++) + vps->layer_idx[i] = -1; + + if (vps->vps_max_layers > 1 && get_bits1(gb)) { /* vps_extension_flag */ + int ret = decode_vps_ext(gb, avctx, vps, layer1_id_included); + if (ret == AVERROR_PATCHWELCOME) { + vps->nb_layers = 1; + av_log(avctx, AV_LOG_WARNING, "Ignoring unsupported VPS extension\n"); + ret = 0; + } else if (ret < 0) + goto err; + } if (get_bits_left(gb) < 0) { av_log(avctx, AV_LOG_ERROR, @@ -893,7 +1178,7 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->temporal_id_nesting = get_bits(gb, 1); - if ((ret = parse_ptl(gb, avctx, &sps->ptl, sps->max_sub_layers)) < 0) + if ((ret = parse_ptl(gb, avctx, 1, &sps->ptl, sps->max_sub_layers)) < 0) return ret; *sps_id = get_ue_golomb_long(gb); diff --git a/libavcodec/hevc/ps.h b/libavcodec/hevc/ps.h index 331d163476..bd1acf12e6 100644 --- a/libavcodec/hevc/ps.h +++ b/libavcodec/hevc/ps.h @@ -32,6 +32,8 @@ #include "hevc.h" +#define HEVC_VPS_MAX_LAYERS 2 + typedef struct HEVCSublayerHdrParams { uint32_t bit_rate_value_minus1[HEVC_MAX_CPB_CNT]; uint32_t cpb_size_value_minus1[HEVC_MAX_CPB_CNT]; @@ -153,6 +155,19 @@ typedef struct PTL { uint8_t sub_layer_level_present_flag[HEVC_MAX_SUB_LAYERS]; } PTL; +typedef struct RepFormat { + uint16_t pic_width_in_luma_samples; + uint16_t pic_height_in_luma_samples; + uint8_t chroma_format_idc; + uint8_t separate_colour_plane_flag; + uint8_t bit_depth_luma; ///< bit_depth_vps_luma_minus8 + 8 + uint8_t bit_depth_chroma; ///< bit_depth_vps_chroma_minus8 + 8 + uint16_t conf_win_left_offset; + uint16_t conf_win_right_offset; + uint16_t conf_win_top_offset; + uint16_t conf_win_bottom_offset; +} RepFormat; + typedef struct HEVCVPS { unsigned int vps_id; @@ -176,6 +191,53 @@ typedef struct HEVCVPS { HEVCHdrParams *hdr; + /* VPS extension */ + + /* Number of layers this VPS was parsed for, between 1 and + * min(HEVC_VPS_MAX_LAYERS, vps_max_layers). + * + * Note that vps_max_layers contains the layer count declared in the + * bitstream, while nb_layers contains the number of layers exported to + * users of this API (which may be smaller as we only support a subset of + * multilayer extensions). + * + * Arrays below documented as [layer_idx] have nb_layers valid entries. + */ + int nb_layers; + + // LayerIdxInVps[nuh_layer_id], i.e. a mapping of nuh_layer_id to VPS layer + // indices. Valid values are between 0 and HEVC_VPS_MAX_LAYERS. Entries for + // unmapped values of nuh_layer_id are set to -1. + int8_t layer_idx[HEVC_MAX_NUH_LAYER_ID + 1]; + + uint8_t layer_id_in_nuh[HEVC_VPS_MAX_LAYERS]; + + uint8_t default_ref_layers_active; + uint8_t max_one_active_ref_layer; + uint8_t poc_lsb_aligned; + // bitmask of poc_lsb_not_present[layer_idx] + uint8_t poc_lsb_not_present; + + struct { + unsigned max_dec_pic_buffering; // max_vps_dec_pic_buffering_minus1 + 1 + unsigned max_num_reorder_pics; // max_vps_num_reorder_pics + unsigned max_latency_increase; // max_vps_latency_increase_plus1 - 1 + } dpb_size; + + // ViewId[layer_idx] + uint16_t view_id[HEVC_VPS_MAX_LAYERS]; + + // NumOutputLayerSets + uint8_t num_output_layer_sets; + // Bitmasks specifying output layer sets. i-th bit set means layer with VPS + // index i is present in the layer set. + uint64_t ols[HEVC_VPS_MAX_LAYERS]; + + // NumDirectRefLayers[layer_idx] + uint8_t num_direct_ref_layers[HEVC_VPS_MAX_LAYERS]; + + RepFormat rep_format; + uint8_t *data; int data_size; } HEVCVPS; From patchwork Sat Sep 14 10:45:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51581 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp300391vqy; Sat, 14 Sep 2024 04:11:28 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWzQj9lCaWhGWOsv1X8LKK59vFp//lGCRQu/z9jid35rWu47AYcno0RBBJ36f179h6Lxxy6PP/+Zo/+PRWMKvLg@gmail.com X-Google-Smtp-Source: AGHT+IHrWwybLzd5W1n1PDdgIUaJxc8eYGTFwPF3aYUL6l2PmEBFFWUgUu18v7t90kKjCBSJaPq1 X-Received: by 2002:a2e:be28:0:b0:2f4:402:2a77 with SMTP id 38308e7fff4ca-2f787f4f40amr45437041fa.45.1726312287738; Sat, 14 Sep 2024 04:11:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312287; cv=none; d=google.com; s=arc-20240605; b=lzXqN97H0EMj+qeVZ/jRc73CMTgZM9LPCoS/Jaeb/cnkt6jSTnciQk570XUpM84fej 5h8BrUp1MlcmQ6HgFZ1OJlG10Z5kuFxkbe5WGtfdtVjo/fo7UZ2EYCfpeDvykIStTcoQ IaVeFWa0aFwC1xoEEQL7CG1CmHU098RCve9hY6wWnYZ20xBWByS6DIUYmx3P17ycgoUn UUSuNeauPlS+ozk89Ad3h2jZ22tP4UK5qQGG2bsC2BtjlxqJKHUZ9IIPqoOoZsr1zgzq nF6dWPYgLAEI3y9zrnq2dsDtVQtqbBcsJvkfJl0pa0bIzRmB75BuZuIF7gcTQXqKE2rr M+xw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=a/t3bU7E3c/p+XCpBY1uourYQ1ECE4kNeE39Jv/w9zk=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=d01MK8j/CMy2b3ex9rpTSZMCxL9EoFaPfA4wEtkrYUS8ZCjsjLSq3ms/7xzVE5GzhB SlI6QlmcJY5owX/pR1IUkelAQUvEy5sGo9DfB/uOlXlyrPvo0zD+7DSFrfLarEdZaEOk L1X5RYowfHJEs5cUSF1WRYRCfjy0x8fTRzrvsRkd7RSsVjE9TZSIo3+Wzk8sN8rlKVuY g7JApMi+7vcYQtIbzdZXLc3oDjroJVIuAk2L3qzKJgQKSybl1IrOj0ygXKoBcA5YCNLy Vi8UdHW+j+XAoN9MXN9/Y+MYWLOAkK1wKjhpFU/Fjr7JLogLE2kC8Dj+xucQ40qlc2Ng 1myg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=ovSUWEsi; 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 38308e7fff4ca-2f79d488a00si3816631fa.599.2024.09.14.04.11.27; Sat, 14 Sep 2024 04:11:27 -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=@khirnov.net header.s=mail header.b=ovSUWEsi; 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 B19E868DC70; Sat, 14 Sep 2024 14:10:56 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2080C68DADD for ; Sat, 14 Sep 2024 14:10:48 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=ovSUWEsi; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id A85354E2A for ; Sat, 14 Sep 2024 13:10:47 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id Iru2UOjNHWiu for ; Sat, 14 Sep 2024 13:10:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=ylBCrUOPdHY+5nrr6mYhw5NRhY8j1J1ILujlFD85TWg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ovSUWEsiqVj7V/imAkHr+AafZ6xjvNfj+R7a5VLXMpgcNJxE+QnXnaeJvXZXJrNiY hPJNnyyk40EXaXlfYmurNaiGG2QmQO2yEmDOGQUDlOMZP+abCYNTik+608F/YIID6P bWcizWtDzPvNHV5MeMqNWMVF3XvB9Tjlkxf3Ps6+kv4IRnd/OlJfYY2VGw6+ausXbr Sy+E67oFpXtBw3xMgTmdEga4mJdLgbNYn1nUzQ5Pt72IBMR5fiMOZdlrM4BZfiLIFM dpZTqX6i693ml5bORyOZ7TxypoZDPuaJMOxnZhYwGLp7dYnjztS7maOYeI8+OQWVfW MTPaQah+kO+gw== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 5EC5A4E05 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 2B9F33A17BA for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:32 +0200 Message-ID: <20240914111036.17164-8-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 07/23] lavc/hevc/ps: drop a warning for sps_multilayer_extension_flag 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: PCUnALknCOd8 SPS multilayer extension contains a single flag that we are free to ignore, no reason to print a warning. --- libavcodec/hevc/ps.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index 35de26644c..81b3f9cd09 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -1425,8 +1425,6 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, if (sps->multilayer_extension) { skip_bits1(gb); // inter_view_mv_vert_constraint_flag - av_log(avctx, AV_LOG_WARNING, - "sps_multilayer_extension_flag not yet implemented\n"); } if (sps->sps_3d_extension) { From patchwork Sat Sep 14 10:45:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51585 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp303501vqy; Sat, 14 Sep 2024 04:19:24 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUODdUETpcoRBnMr22rj0Sa0H4WVJsHTDSToXNebFtR24D7SD7fJsB48/oQEcpEqVM34Nf/g787qd7+DhINCpxL@gmail.com X-Google-Smtp-Source: AGHT+IG1QwF/3rxuVXUpNKa5ZaVc8Jt0cHmr/TQC+F6QkzN1iz8ihXaSFanQj3WJaI5rWW2FsEH9 X-Received: by 2002:a17:907:3f17:b0:a72:7a71:7f4f with SMTP id a640c23a62f3a-a902a3d2e92mr1024978166b.7.1726312763426; Sat, 14 Sep 2024 04:19:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312763; cv=none; d=google.com; s=arc-20240605; b=lXyLnHeN9uDwK9Drr/+v11sArGGIjiKMkB1zEmkj/WcTOgh1LRdh7JrnW5abuLziQJ HD40+h3/aZX7iyKlNoeZg21M2XOzumM2li38tyNLJHkIQr3Nscp6Asl1bNyeNOFg30qz udFWXTmfw15ljViIeief6nchfOrb2WnAqlHJk3aAgemMxxONpIYYMx0G9Pcsqx/Ynj+v EkowtevS0pEWQenblwpgRrq7+jh8Z9K48vK3LdEJ4Rx5DnBZl/DuRFo9dseCJIxmgOv/ JSrshI1jOxk9qclqGAJEoz7Zywt7Q8K0XBceVK+iRo60vJGDLxl0TLL2DfvHWuFgfNKF 4//g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=dRCp8vflKJ/y57ho6+86QF4wFPyDq+8sF6pRqyJghlg=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=CE0It1PqKXnvpJGu2pKaIOT2CuWth7vPNNGVhZ9WhVGePsBJRFDfMU/JqpBQzxcxba Sy0j4huM+nFuDFb6OSQmma0tQhpZOuoKxUMvLw0uQmQoRJUeAPpCIFXcweU2W1C1SRNi 0H0jor7bqfkyAmxZQjeaconM8Y4YUIc7n7FD5+XK2T7tPAFioi24qKj3+fsG1ZON/R7H sZfFh0H7zIKSCdeIe5EKIPrNPXlNB9getaSyT0wqBLsSoNwLsZHXuNWafxNd+CGGzoQM 6SELSBOIeeHyBSnta3r7vuF+dqFuI13fND5OKtUe7dblu89PJTJBjRsGWhibEmTgJQC4 0V3A==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=IyfTO1ok; 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 a640c23a62f3a-a906135931csi86933266b.948.2024.09.14.04.19.23; Sat, 14 Sep 2024 04:19:23 -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=@khirnov.net header.s=mail header.b=IyfTO1ok; 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 ADDDA68DE34; Sat, 14 Sep 2024 14:11:04 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5FB4A68DC90 for ; Sat, 14 Sep 2024 14:10:53 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=IyfTO1ok; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id C7D754DDE for ; Sat, 14 Sep 2024 13:10:48 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id GIOiVe9p70ge for ; Sat, 14 Sep 2024 13:10:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=d4UmMs0eIWdvSP2Za1D4+cNA+2KYlrlRHb9d4DQ4Lb4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=IyfTO1ok5yuNG8YakVIGVIf8e/wKgFTBws9XOpEOkVz1XTsaUBDt97+LSXV+S1j5u 4Tq8/if8tOEmPm1hCkWqmP1T/+N6ot0OIAYQ04zv9lvMaM5CChbnG442c3GXOF5b2k tA1e+WQ3PGz03QAMRSJg96yqVYnQqKI3r1Hw+Vxw34yO8Jagv5THgS3pjEFvK30XID +bPuKNbGEqYTSWxuYLP9SDkHYPYjNK2KqGsiRKdT+4Av5GoX7YBXi76O0FkPB4AX2h Lov8xgxNeKY+e2lcnHXTf/3dB+38kMF3sFyKd5LEqbF3GWnFgkILTPK2FvIRnEvJ8l oujMcJuqkanQA== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 5ED784E06 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 376673A19A6 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:33 +0200 Message-ID: <20240914111036.17164-9-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 08/23] lavc/hevc/ps: implement SPS parsing for nuh_layer_id>0 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: pMBZwqzhDohv Cf. F.7.3.2.2 "Sequence parameter set RBSP syntax", which extends normal SPS parsing with special clauses depending on MultiLayerExtSpsFlag. --- libavcodec/hevc/hevcdec.c | 2 +- libavcodec/hevc/parse.c | 3 +- libavcodec/hevc/parser.c | 2 +- libavcodec/hevc/ps.c | 65 +++++++++++++++++++++++++++++++++++---- libavcodec/hevc/ps.h | 7 +++-- libavcodec/qsvenc_hevc.c | 2 +- 6 files changed, 68 insertions(+), 13 deletions(-) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index d915d74d22..ebe2f5ad11 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -3260,7 +3260,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) break; case HEVC_NAL_SPS: ret = ff_hevc_decode_nal_sps(&gb, s->avctx, &s->ps, - s->apply_defdispwin); + nal->nuh_layer_id, s->apply_defdispwin); if (ret < 0) goto fail; break; diff --git a/libavcodec/hevc/parse.c b/libavcodec/hevc/parse.c index ec8d1aeacf..ad84b7b152 100644 --- a/libavcodec/hevc/parse.c +++ b/libavcodec/hevc/parse.c @@ -49,7 +49,8 @@ static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets goto done; break; case HEVC_NAL_SPS: - ret = ff_hevc_decode_nal_sps(&nal->gb, logctx, ps, apply_defdispwin); + ret = ff_hevc_decode_nal_sps(&nal->gb, logctx, ps, + nal->nuh_layer_id, apply_defdispwin); if (ret < 0) goto done; break; diff --git a/libavcodec/hevc/parser.c b/libavcodec/hevc/parser.c index 2d14b4fae2..8c7444a162 100644 --- a/libavcodec/hevc/parser.c +++ b/libavcodec/hevc/parser.c @@ -209,7 +209,7 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, ff_hevc_decode_nal_vps(gb, avctx, ps); break; case HEVC_NAL_SPS: - ff_hevc_decode_nal_sps(gb, avctx, ps, 1); + ff_hevc_decode_nal_sps(gb, avctx, ps, nal->nuh_layer_id, 1); break; case HEVC_NAL_PPS: ff_hevc_decode_nal_pps(gb, avctx, ps); diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index 81b3f9cd09..2d09500278 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -1148,12 +1148,12 @@ static int map_pixel_format(AVCodecContext *avctx, HEVCSPS *sps) } int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, - int apply_defdispwin, const HEVCVPS * const *vps_list, - AVCodecContext *avctx) + unsigned nuh_layer_id, int apply_defdispwin, + const HEVCVPS * const *vps_list, AVCodecContext *avctx) { HEVCWindow *ow; int ret = 0; - int bit_depth_chroma, start, num_comps; + int bit_depth_chroma, num_comps, multi_layer_ext; int i; // Coded parameters @@ -1170,16 +1170,29 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, } sps->max_sub_layers = get_bits(gb, 3) + 1; + multi_layer_ext = nuh_layer_id > 0 && + sps->max_sub_layers == HEVC_MAX_SUB_LAYERS + 1; + if (multi_layer_ext) { + if (!sps->vps) + return AVERROR(EINVAL); + + sps->max_sub_layers = sps->vps->vps_max_sub_layers; + } if (sps->max_sub_layers > HEVC_MAX_SUB_LAYERS) { av_log(avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n", sps->max_sub_layers); return AVERROR_INVALIDDATA; } + if (!multi_layer_ext) { sps->temporal_id_nesting = get_bits(gb, 1); if ((ret = parse_ptl(gb, avctx, 1, &sps->ptl, sps->max_sub_layers)) < 0) return ret; + } else { + sps->temporal_id_nesting = sps->max_sub_layers > 1 ? + sps->vps->vps_max_sub_layers : 1; + } *sps_id = get_ue_golomb_long(gb); if (*sps_id >= HEVC_MAX_SPS_COUNT) { @@ -1187,6 +1200,28 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, return AVERROR_INVALIDDATA; } + if (multi_layer_ext) { + const RepFormat *rf = &sps->vps->rep_format; + + if (get_bits1(gb) && // update_rep_format_flag + get_bits(gb, 8)) { // sps_rep_format_idx + av_log(avctx, AV_LOG_ERROR, "sps_rep_format_idx!=0\n"); + return AVERROR_PATCHWELCOME; + } + + sps->separate_colour_plane = rf->separate_colour_plane_flag; + sps->chroma_format_idc = sps->separate_colour_plane ? 0 : + rf->chroma_format_idc; + sps->bit_depth = rf->bit_depth_luma; + sps->width = rf->pic_width_in_luma_samples; + sps->height = rf->pic_height_in_luma_samples; + + sps->pic_conf_win.left_offset = rf->conf_win_left_offset; + sps->pic_conf_win.right_offset = rf->conf_win_right_offset; + sps->pic_conf_win.top_offset = rf->conf_win_top_offset; + sps->pic_conf_win.bottom_offset = rf->conf_win_bottom_offset; + + } else { sps->chroma_format_idc = get_ue_golomb_long(gb); if (sps->chroma_format_idc > 3U) { av_log(avctx, AV_LOG_ERROR, "chroma_format_idc %d is invalid\n", sps->chroma_format_idc); @@ -1228,7 +1263,6 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->pic_conf_win.top_offset = sps->pic_conf_win.bottom_offset = 0; } - sps->output_window = sps->pic_conf_win; } sps->bit_depth = get_ue_golomb_31(gb) + 8; @@ -1251,6 +1285,9 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, return AVERROR_INVALIDDATA; } sps->bit_depth_chroma = bit_depth_chroma; + } + + sps->output_window = sps->pic_conf_win; ret = map_pixel_format(avctx, sps); if (ret < 0) @@ -1263,6 +1300,9 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, return AVERROR_INVALIDDATA; } + if (!multi_layer_ext) { + int start; + sps->sublayer_ordering_info = get_bits1(gb); start = sps->sublayer_ordering_info ? 0 : sps->max_sub_layers - 1; for (i = start; i < sps->max_sub_layers; i++) { @@ -1292,6 +1332,13 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->temporal_layer[i].max_latency_increase = sps->temporal_layer[start].max_latency_increase; } } + } else { + for (int i = 0; i < sps->max_sub_layers; i++) { + sps->temporal_layer[i].max_dec_pic_buffering = sps->vps->dpb_size.max_dec_pic_buffering; + sps->temporal_layer[i].num_reorder_pics = sps->vps->dpb_size.max_num_reorder_pics; + sps->temporal_layer[i].max_latency_increase = sps->vps->dpb_size.max_latency_increase; + } + } sps->log2_min_cb_size = get_ue_golomb_long(gb) + 3; sps->log2_diff_max_min_coding_block_size = get_ue_golomb_long(gb); @@ -1328,6 +1375,11 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, if (sps->scaling_list_enabled) { set_default_scaling_list_data(&sps->scaling_list); + if (multi_layer_ext && get_bits1(gb)) { // sps_infer_scaling_list_flag + av_log(avctx, AV_LOG_ERROR, "sps_infer_scaling_list_flag=1 not supported\n"); + return AVERROR_PATCHWELCOME; + } + if (get_bits1(gb)) { ret = scaling_list_data(gb, avctx, &sps->scaling_list, sps); if (ret < 0) @@ -1582,7 +1634,8 @@ static int compare_sps(const HEVCSPS *sps1, const HEVCSPS *sps2) } int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, - HEVCParamSets *ps, int apply_defdispwin) + HEVCParamSets *ps, unsigned nuh_layer_id, + int apply_defdispwin) { HEVCSPS *sps = ff_refstruct_alloc_ext(sizeof(*sps), 0, NULL, hevc_sps_free); unsigned int sps_id; @@ -1601,7 +1654,7 @@ int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, } ret = ff_hevc_parse_sps(sps, gb, &sps_id, - apply_defdispwin, + nuh_layer_id, apply_defdispwin, ps->vps_list, avctx); if (ret < 0) goto err; diff --git a/libavcodec/hevc/ps.h b/libavcodec/hevc/ps.h index bd1acf12e6..6f5b1f8755 100644 --- a/libavcodec/hevc/ps.h +++ b/libavcodec/hevc/ps.h @@ -521,13 +521,14 @@ typedef struct HEVCParamSets { * to an existing VPS */ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, - int apply_defdispwin, const HEVCVPS * const *vps_list, - AVCodecContext *avctx); + unsigned nuh_layer_id, int apply_defdispwin, + const HEVCVPS * const *vps_list, AVCodecContext *avctx); int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, HEVCParamSets *ps); int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, - HEVCParamSets *ps, int apply_defdispwin); + HEVCParamSets *ps, unsigned nuh_layer_id, + int apply_defdispwin); int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, HEVCParamSets *ps); diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index 2a397a2919..80fdf782a7 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -99,7 +99,7 @@ static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx) } get_bits(&gb, 9); - ret = ff_hevc_parse_sps(&sps, &gb, &sps_id, 0, NULL, avctx); + ret = ff_hevc_parse_sps(&sps, &gb, &sps_id, 0, 0, NULL, avctx); av_freep(&sps_rbsp.rbsp_buffer); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error parsing the SPS\n"); From patchwork Sat Sep 14 10:45:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51591 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp307048vqy; Sat, 14 Sep 2024 04:29:20 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXeJDOmWhCiKEIFWqmDC8exZDJp3oZYYNJ43hH4o0rFaSZG0xK6mI4Krc+77bmo64fNpOoiyZLouS3x+OBD7Aj8@gmail.com X-Google-Smtp-Source: AGHT+IFn8o/2qV5AKxvs6IUaQ3JHRIBhh9L22imDvW8ZYwOj/Z1KwUtLfuWfabmjiMsgQPHKjsPH X-Received: by 2002:a17:906:f857:b0:a90:3497:e138 with SMTP id a640c23a62f3a-a903497eb0amr271677966b.13.1726313360136; Sat, 14 Sep 2024 04:29:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313360; cv=none; d=google.com; s=arc-20240605; b=DvyItGIEt7QmCqwpL9xhi7d57732SPkfX71a4M4PuLsI2+IQTq5RJHFTdYnFmdxhaD fWOfO12JTNhDO7OX9VW1mxRqENROui+4Ldyu8XlYP5vByPtVrQ4lvkfDdQYlq1tzAWsR ENJv/XIaCzoNCCGpU9ktNY8MET5MnSXReWMjTjbssL4uQYhRTwozdr4pxERYDCUOZmsR nyPF8AgYcXJcKJIlSoUyhahd+Y4gM8Y4UX6zhfLd+yo21hzVzdhdJYFmOWJ9+azcqWm3 FcdL+mBAToRYtlMUhgGnUfL9Kv2JiKV1oqQu9ZPV7f4IxiKRYiJvhNfaC8R5yMiusxwg uybw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=8xyaeP1gwH9k+UqWue6txd5XXicbT4+XCMcuouPbA80=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=i6MkH6hcYy0yWAAoLmIf+g7xxCGfAi3l/ToHOZMWcx+rBVqJt7MSMcycC/TIBFZIQH QdLpRnar4DhDFMljpv+m23gPBE+k/8QNzA0+8QurfelZCybL1JIiFQ61VuqnfED4lUFF TqLAREJYo9yJHFbVxh7VWpkxL1kqfpVX6e+dgn+JHsB1h/oIoudiGmvdoCUDYcNmTyoF oCS7ORJZNBMnqvKJLhfNbpsRB8CXjrkIWnKEysQvdCeLQtEHre078nJv5C4lYw1l1v7p kDQci9YgQV2knEBMB/nCwxJSbw0l9kufGOWCVHmiO17vuov8wDMxcvlQAM+SxfdYgQdC +KHA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=aNXRbrX5; 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 a640c23a62f3a-a9061339979si87133066b.788.2024.09.14.04.29.19; Sat, 14 Sep 2024 04:29:20 -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=@khirnov.net header.s=mail header.b=aNXRbrX5; 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 89E5068DDF4; Sat, 14 Sep 2024 14:11:06 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6EC4B68DC9E for ; Sat, 14 Sep 2024 14:10:53 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=aNXRbrX5; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 5EB224DE4 for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id s3eoV2Xfi1b5 for ; Sat, 14 Sep 2024 13:10:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=Xe176Xyrjz+cSkeG3SsXMC40g4jKSQJiYxS5Ea3IY/Y=; h=From:To:Subject:Date:In-Reply-To:References:From; b=aNXRbrX56/XKYAZRsmQ+0LYvjhQd577u1ZUso2SjqkV/lmIzeEffZnRPu31fgfjE9 ZNt5lDsqfgWKhArrS7KWRo9Wjwb9ENe/SDnsRtb+aWtTtjohGhivJCbZxuIeAs8RLl UpwcFv9PDv2eBzJrKwQQzyMiJpMaXTLGDavz2QrZIXJ2qThS6ygRmL1mSTIDgE5ozo PnFJRwLp8xFpiEui0YZK/dLnLfoYG998J4igP7Kuq2zod5kyjKnajcHUfHa9Eh8vvW JKbhPoOt1WTE2gl+2mXN9YR6O06Jz4Ml1xPSlwYzgaBdwVnLPwkw3b6QOTG9D3eW95 QGyHk3n+0xpNQ== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 69A5E4E09 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 4318D3A19EA for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:34 +0200 Message-ID: <20240914111036.17164-10-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 09/23] lavc/hevc/ps: reindent 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: pV7MA/6EMTL4 --- libavcodec/hevc/ps.c | 178 +++++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 89 deletions(-) diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index 2d09500278..f18b88489b 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -1185,10 +1185,10 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, } if (!multi_layer_ext) { - sps->temporal_id_nesting = get_bits(gb, 1); + sps->temporal_id_nesting = get_bits(gb, 1); - if ((ret = parse_ptl(gb, avctx, 1, &sps->ptl, sps->max_sub_layers)) < 0) - return ret; + if ((ret = parse_ptl(gb, avctx, 1, &sps->ptl, sps->max_sub_layers)) < 0) + return ret; } else { sps->temporal_id_nesting = sps->max_sub_layers > 1 ? sps->vps->vps_max_sub_layers : 1; @@ -1222,69 +1222,69 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->pic_conf_win.bottom_offset = rf->conf_win_bottom_offset; } else { - sps->chroma_format_idc = get_ue_golomb_long(gb); - if (sps->chroma_format_idc > 3U) { - av_log(avctx, AV_LOG_ERROR, "chroma_format_idc %d is invalid\n", sps->chroma_format_idc); - return AVERROR_INVALIDDATA; - } - - if (sps->chroma_format_idc == 3) - sps->separate_colour_plane = get_bits1(gb); - - if (sps->separate_colour_plane) - sps->chroma_format_idc = 0; - - sps->width = get_ue_golomb_long(gb); - sps->height = get_ue_golomb_long(gb); - if ((ret = av_image_check_size(sps->width, - sps->height, 0, avctx)) < 0) - return ret; - - sps->conformance_window = get_bits1(gb); - if (sps->conformance_window) { - int vert_mult = hevc_sub_height_c[sps->chroma_format_idc]; - int horiz_mult = hevc_sub_width_c[sps->chroma_format_idc]; - sps->pic_conf_win.left_offset = get_ue_golomb_long(gb) * horiz_mult; - sps->pic_conf_win.right_offset = get_ue_golomb_long(gb) * horiz_mult; - sps->pic_conf_win.top_offset = get_ue_golomb_long(gb) * vert_mult; - sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * vert_mult; - - if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) { - av_log(avctx, AV_LOG_DEBUG, - "discarding sps conformance window, " - "original values are l:%u r:%u t:%u b:%u\n", - sps->pic_conf_win.left_offset, - sps->pic_conf_win.right_offset, - sps->pic_conf_win.top_offset, - sps->pic_conf_win.bottom_offset); - - sps->pic_conf_win.left_offset = - sps->pic_conf_win.right_offset = - sps->pic_conf_win.top_offset = - sps->pic_conf_win.bottom_offset = 0; + sps->chroma_format_idc = get_ue_golomb_long(gb); + if (sps->chroma_format_idc > 3U) { + av_log(avctx, AV_LOG_ERROR, "chroma_format_idc %d is invalid\n", sps->chroma_format_idc); + return AVERROR_INVALIDDATA; } - } - sps->bit_depth = get_ue_golomb_31(gb) + 8; - if (sps->bit_depth > 16) { - av_log(avctx, AV_LOG_ERROR, "Luma bit depth (%d) is out of range\n", - sps->bit_depth); - return AVERROR_INVALIDDATA; - } - bit_depth_chroma = get_ue_golomb_31(gb) + 8; - if (bit_depth_chroma > 16) { - av_log(avctx, AV_LOG_ERROR, "Chroma bit depth (%d) is out of range\n", - bit_depth_chroma); - return AVERROR_INVALIDDATA; - } - if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth) { - av_log(avctx, AV_LOG_ERROR, - "Luma bit depth (%d) is different from chroma bit depth (%d), " - "this is unsupported.\n", - sps->bit_depth, bit_depth_chroma); - return AVERROR_INVALIDDATA; - } - sps->bit_depth_chroma = bit_depth_chroma; + if (sps->chroma_format_idc == 3) + sps->separate_colour_plane = get_bits1(gb); + + if (sps->separate_colour_plane) + sps->chroma_format_idc = 0; + + sps->width = get_ue_golomb_long(gb); + sps->height = get_ue_golomb_long(gb); + if ((ret = av_image_check_size(sps->width, + sps->height, 0, avctx)) < 0) + return ret; + + sps->conformance_window = get_bits1(gb); + if (sps->conformance_window) { + int vert_mult = hevc_sub_height_c[sps->chroma_format_idc]; + int horiz_mult = hevc_sub_width_c[sps->chroma_format_idc]; + sps->pic_conf_win.left_offset = get_ue_golomb_long(gb) * horiz_mult; + sps->pic_conf_win.right_offset = get_ue_golomb_long(gb) * horiz_mult; + sps->pic_conf_win.top_offset = get_ue_golomb_long(gb) * vert_mult; + sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * vert_mult; + + if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) { + av_log(avctx, AV_LOG_DEBUG, + "discarding sps conformance window, " + "original values are l:%u r:%u t:%u b:%u\n", + sps->pic_conf_win.left_offset, + sps->pic_conf_win.right_offset, + sps->pic_conf_win.top_offset, + sps->pic_conf_win.bottom_offset); + + sps->pic_conf_win.left_offset = + sps->pic_conf_win.right_offset = + sps->pic_conf_win.top_offset = + sps->pic_conf_win.bottom_offset = 0; + } + } + + sps->bit_depth = get_ue_golomb_31(gb) + 8; + if (sps->bit_depth > 16) { + av_log(avctx, AV_LOG_ERROR, "Luma bit depth (%d) is out of range\n", + sps->bit_depth); + return AVERROR_INVALIDDATA; + } + bit_depth_chroma = get_ue_golomb_31(gb) + 8; + if (bit_depth_chroma > 16) { + av_log(avctx, AV_LOG_ERROR, "Chroma bit depth (%d) is out of range\n", + bit_depth_chroma); + return AVERROR_INVALIDDATA; + } + if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth) { + av_log(avctx, AV_LOG_ERROR, + "Luma bit depth (%d) is different from chroma bit depth (%d), " + "this is unsupported.\n", + sps->bit_depth, bit_depth_chroma); + return AVERROR_INVALIDDATA; + } + sps->bit_depth_chroma = bit_depth_chroma; } sps->output_window = sps->pic_conf_win; @@ -1301,37 +1301,37 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, } if (!multi_layer_ext) { - int start; + int start; - sps->sublayer_ordering_info = get_bits1(gb); - start = sps->sublayer_ordering_info ? 0 : sps->max_sub_layers - 1; - for (i = start; i < sps->max_sub_layers; i++) { - sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1; - sps->temporal_layer[i].num_reorder_pics = get_ue_golomb_long(gb); - sps->temporal_layer[i].max_latency_increase = get_ue_golomb_long(gb) - 1; - if (sps->temporal_layer[i].max_dec_pic_buffering > (unsigned)HEVC_MAX_DPB_SIZE) { - av_log(avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n", - sps->temporal_layer[i].max_dec_pic_buffering - 1U); - return AVERROR_INVALIDDATA; - } - if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) { - av_log(avctx, AV_LOG_WARNING, "sps_max_num_reorder_pics out of range: %d\n", - sps->temporal_layer[i].num_reorder_pics); - if (avctx->err_recognition & AV_EF_EXPLODE || - sps->temporal_layer[i].num_reorder_pics > HEVC_MAX_DPB_SIZE - 1) { + sps->sublayer_ordering_info = get_bits1(gb); + start = sps->sublayer_ordering_info ? 0 : sps->max_sub_layers - 1; + for (i = start; i < sps->max_sub_layers; i++) { + sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1; + sps->temporal_layer[i].num_reorder_pics = get_ue_golomb_long(gb); + sps->temporal_layer[i].max_latency_increase = get_ue_golomb_long(gb) - 1; + if (sps->temporal_layer[i].max_dec_pic_buffering > (unsigned)HEVC_MAX_DPB_SIZE) { + av_log(avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n", + sps->temporal_layer[i].max_dec_pic_buffering - 1U); return AVERROR_INVALIDDATA; } - sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[i].num_reorder_pics + 1; + if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) { + av_log(avctx, AV_LOG_WARNING, "sps_max_num_reorder_pics out of range: %d\n", + sps->temporal_layer[i].num_reorder_pics); + if (avctx->err_recognition & AV_EF_EXPLODE || + sps->temporal_layer[i].num_reorder_pics > HEVC_MAX_DPB_SIZE - 1) { + return AVERROR_INVALIDDATA; + } + sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[i].num_reorder_pics + 1; + } } - } - if (!sps->sublayer_ordering_info) { - for (i = 0; i < start; i++) { - sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering; - sps->temporal_layer[i].num_reorder_pics = sps->temporal_layer[start].num_reorder_pics; - sps->temporal_layer[i].max_latency_increase = sps->temporal_layer[start].max_latency_increase; + if (!sps->sublayer_ordering_info) { + for (i = 0; i < start; i++) { + sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering; + sps->temporal_layer[i].num_reorder_pics = sps->temporal_layer[start].num_reorder_pics; + sps->temporal_layer[i].max_latency_increase = sps->temporal_layer[start].max_latency_increase; + } } - } } else { for (int i = 0; i < sps->max_sub_layers; i++) { sps->temporal_layer[i].max_dec_pic_buffering = sps->vps->dpb_size.max_dec_pic_buffering; From patchwork Sat Sep 14 10:45:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51583 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp300599vqy; Sat, 14 Sep 2024 04:11:58 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVluC7UdllBducHv6gfxxp4e+xzXIfSY7HYtuWZ4adXNvXqm4XzeJU8nsrfoZ+sKociDonUxtbyuoQOguO2BLBh@gmail.com X-Google-Smtp-Source: AGHT+IEbYmSHHM79XT0OwzzGKfYcHhTxu9SoaKdN//FmghO5qKhNJPf8tdvqaTBz6Y/P3UQ+w1t+ X-Received: by 2002:a05:6402:3209:b0:5c2:53a1:c209 with SMTP id 4fb4d7f45d1cf-5c413e4c638mr7989363a12.25.1726312318017; Sat, 14 Sep 2024 04:11:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312317; cv=none; d=google.com; s=arc-20240605; b=iRQqPFZiBUlF5eHBpFWR0/f4LtthNHDz2XngWZxWUugtMr9owulY1Jt0tvhVwmVedf KoPDImkhVZm4+nfk91/juaCOf9e/nmSUzQhbfdgRhKuGCg/77r4zm2rI7cWiQwIURzSJ b/RlfQcbYdUXlaREdmovRyiN4NpeLQqB/JI+2B/YZhj5SpM+IjhJEJhiAfsKQjCoaWZ1 sazf294Dp9wSaKepkaRe0sgUkgvugr53XHHu84DbYIu4rSaE9ypf9hTc7QTuCHDRb53L 6pnMrWjar5AqZ0l9qvqlZLJQQl6aM5kHB6J4Ag/6DGlnUUIQRR/8tGgb8ZlI0Nx0acXD LhOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=Rjq4kJQl2LMad/fkJVkxJRvG5MMOi8USNpKTVj0ueEM=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=Uds+icIjO3UaUitvlZ2wQR/g59rAwZI+bQQW1XZgH416CoM9WO4EFj+meMBytdcJto p8+SgeAQifyt5Tu9XtOGz9LHELLfeNBRChn9oPxJVUEjT2PfswPWfcRcQtgdT11JH0YG KQ4hLmJFFnL8p4hMIDu51g49p7G+fXejU7a1rAjJ5kjscBTYn/1yzoe398tWMJuhKzLA KuDD9N0L9SQnlwiS1DWwN2P0JIiTSJ99DKbEUBJTWbrOyMwOx3sJypOZwYUfDFIOI4zt vjAaP9yUgljvhlP45Vrl7nFCCiOGIs8AHu+Gk5lOtZdJVrHH4pba8j0RbA2eIblAa4z2 bYrw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=cRiXwJnZ; 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 4fb4d7f45d1cf-5c42bc90969si826707a12.447.2024.09.14.04.11.57; Sat, 14 Sep 2024 04:11:57 -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=@khirnov.net header.s=mail header.b=cRiXwJnZ; 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 056B868DDB8; Sat, 14 Sep 2024 14:11:00 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B83EB68DB42 for ; Sat, 14 Sep 2024 14:10:53 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=cRiXwJnZ; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id AAE674E06 for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id FstMJ2Sk5NFS for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=t+nqy3HKz4gaXiXjCSR++H8WcniNXaBA/05sXYV2Kj4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cRiXwJnZ9dmcqdrK4JuUGkj8LaJTFwkRT3ChKL4gl9a6Zkoophp2PkcKDs4Mlw0Oe zUDGAY3KAYQEehG9O2mUlqTBuuN8iIRU1GeQNiKf+bgmF/WsYFPxRyqgeHXfr2sRwx ZWz/kEwUhEoxs/aVdSUCv0kHcxVfHQJyqPFqvnHhymSO+WRyYgttvJrLL2x8s5PICX rTXheEAKzywg8+dj4LTjbV4mkH8H0sjzzpo0H+nHT4aMzufrmtP/YZycWveiY9u66a cH03CQN8HtrSuVF5UD7cGw8TosL0xO2bmdNvE7mzK03+b05r5w2G3X10jF7qfrQydY jbwVQSrx8hW+w== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 6CBDA4E0C for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 4EB6B3A1A1B for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:35 +0200 Message-ID: <20240914111036.17164-11-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 10/23] lavc/hevcdec/parse: process NALUs with nuh_layer_id>0 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: o4ritKc+kEAQ Otherwise parameter sets from extradata with nuh_layer_id>0 would be ignored. Needed for upcoming MV-HEVC support. --- libavcodec/hevc/parse.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavcodec/hevc/parse.c b/libavcodec/hevc/parse.c index ad84b7b152..29f21a5966 100644 --- a/libavcodec/hevc/parse.c +++ b/libavcodec/hevc/parse.c @@ -38,9 +38,6 @@ static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets for (i = 0; i < pkt.nb_nals; i++) { H2645NAL *nal = &pkt.nals[i]; - if (nal->nuh_layer_id > 0) - continue; - /* ignore everything except parameter sets and VCL NALUs */ switch (nal->type) { case HEVC_NAL_VPS: From patchwork Sat Sep 14 10:45:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51600 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp331666vqy; Sat, 14 Sep 2024 05:29:12 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVTC9dGD2nfKNEovQDZwmwZZ5OoJsLMbH4yTIOxdjqkgiZzLzK7VGK+ww7rtjNQ8+wEIMI5MsjS/xnRJ6sG+1ud@gmail.com X-Google-Smtp-Source: AGHT+IFAhFqlk4DbInE4bS9hgpgrz3S63CZJO2LIlGVB3mkTvJjldUoOt15hDO1JZZfqZW5179Wa X-Received: by 2002:a5d:58d4:0:b0:374:c7a5:d610 with SMTP id ffacd0b85a97d-378d6236b9cmr5002074f8f.43.1726316952532; Sat, 14 Sep 2024 05:29:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726316952; cv=none; d=google.com; s=arc-20240605; b=B2fkOhqfxNjam/NNShK/LvksTA3ygAfscFWbPq1f1oNnWGBSKH+CqHrcaFk3ZjqbF3 oQSLSK73HycmTqgyecLKIgpQy6mIGeO4nP5PvLfvdai8QtPmjCMUqb6z+97fIxKuRaQz yzv+5Z0KVC6IBhBVdDt1Dc3PtDni9/Z0z7us9pclzm6BO6x+3oRN9AS+tYaVRQCEKV3g IuxsDPdjUWCSAYrjt6d3OCmE7Iy9HB+m6v7mz3oLPgr+QaOEBsSDmuIB9bKJfkv5dpPI wjFwo39h0fTlzEtspfkb3hpX9rkW9p9WPrhh6nNcG+nisBoJoE1eDNfncIfoDTMfYWeW 6jcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=MIMIYzaO0QAhngZfzjsb/yBVkDhlFBQGDdIlDUwK2pc=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=Eefknjv4BTrAzcIPzslb0VlUWnCd8Is64WYYqb5MK2dSUe3m3Lq2jopdEdF1qSKyvx 0+QpLM1Nm99TR4Dj7vCIAWaTb8QGHkYFwPvAyfjoS1l/pCBBRnpKzVvMMn2aaN/jyo5i GWnKZeTblu88Ug+vS+ya1s/c/M97B+wkOL+S7Xu2G1o3pPdz9XfKhVuQ6lHUTwXdYEs8 mwQu9U3RJNimroKvcfrcgaW4jcpnoL67knBwfHYZAmJ7R76ywYvN3mTzLRUAF1yyUKlD Zffh72wbCA5E9TVzYJb+vjm8FGsuBAQbDpiFJBBbbcf1DZJOrflvFfdmtNoxam2mYOdA vLBQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=kH+KiQz9; 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 a640c23a62f3a-a90612b9b18si92460666b.331.2024.09.14.05.29.12; Sat, 14 Sep 2024 05:29:12 -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=@khirnov.net header.s=mail header.b=kH+KiQz9; 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 8877068DE49; Sat, 14 Sep 2024 14:11:07 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6AFB068DC94 for ; Sat, 14 Sep 2024 14:10:53 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=kH+KiQz9; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 5BCF54DEE for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id CsYfI97km49C for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=km+mq1gtm4WOVAFt8t7hfh/b/meF5LaVs86scBONolg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=kH+KiQz9Jnz05sla5Cuob3o7d2B0ASoFCGkDYIsIEcVU34kfGYMqEmQVR3KwBywbt 0uh92IreVZMwRMMPsLP5htiuq3KAw/piidCORhPfBSloQsWDkjyHIcA+2IP1I2Khy1 AOx074/tjNOPurcCAAwY140S4mfSzFq7pkJjj8nLrsJoatvP+9TCO1P0R+9uho8aXg Fu8LUvRIoqZPznCR/h2XNuoEcgGMv4gWWeiiI3PEXKkd69Szy1gGaQ/G/48oII6Dwd jSJZsPvqAX/vggXSK+maTKBXJYSQQ6Ah84jwIIwpXrjd8Wr++RLcqNfuWjdJKPS9Jj 6CElO/rcEbyAA== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 6F7234E11 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 5A7233A1A81 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:36 +0200 Message-ID: <20240914111036.17164-12-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 11/23] lavc/hevc/parser: only split packets on NALUs with nuh_layer_id=0 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: fC6eUwyQ/Rcz A packet should contain a full access unit, which for multilayer video should contain all the layers. --- libavcodec/hevc/parser.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/hevc/parser.c b/libavcodec/hevc/parser.c index 8c7444a162..16b40e2b10 100644 --- a/libavcodec/hevc/parser.c +++ b/libavcodec/hevc/parser.c @@ -262,7 +262,7 @@ static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, int i; for (i = 0; i < buf_size; i++) { - int nut; + int nut, layer_id; pc->state64 = (pc->state64 << 8) | buf[i]; @@ -270,6 +270,11 @@ static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, continue; nut = (pc->state64 >> 2 * 8 + 1) & 0x3F; + + layer_id = (pc->state64 >> 11) & 0x3F; + if (layer_id > 0) + continue; + // Beginning of access unit if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_EOB_NUT) || nut == HEVC_NAL_SEI_PREFIX || (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) { From patchwork Sat Sep 14 10:45:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51590 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp307035vqy; Sat, 14 Sep 2024 04:29:17 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCV8kL6lumHgQhLzKB3G0IR0MmpystZVLahIYAR/NwfK6DU7IgGdHPuT8anUBhNUz39oqP1lvcWw1W6R8vtr82eU@gmail.com X-Google-Smtp-Source: AGHT+IEDfv0TxI3YdG+BpxI2m04F3bC/LDNiqhr1cTLkmc0kcfzzFp0Q4jlCJxe94MxMErwwbjci X-Received: by 2002:a17:907:d3c5:b0:a8d:64af:dc2a with SMTP id a640c23a62f3a-a902947b903mr900817366b.25.1726313356960; Sat, 14 Sep 2024 04:29:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313356; cv=none; d=google.com; s=arc-20240605; b=NjCjI6+AUHw7/i9XVc8n9zdKn5d02usl80cCqZX4G/DJpQrxfQgq99UzmcCvUTrJcH LQlTe09Y2wGl6d5pMhN41ORvlgCCT66Wr5WvXzyMfplPmfXeQzj+J/gIoZZuy+WovBCt BkLPZ43i0jTTMbNw2u8kKl8lW1PUHUUw0VT7WAXePw4f4zdzTRFDlnl+rqYUgUalI75c pubPE78KQD5/19Ih1GmNZnT2V4u/BVQ0mOEsevSdq7QTxjxK+aIgVoME/WYrQegc1DfF UYaUebVCHDyh5spGTJr/xLPuon/jzYWLp9zIGTBB2OlbdHbj2zjWKmn/n4ujZKUhUE4V BYrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=SihbBhRGoFEexzQUyorNWwizfgyCOGVVJcyqe6d6sE4=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=iubU9wadtxJ8gmmOnA6BFbTMY+5jTAExGMy8QAkGVaPqsvJnxSfiSi3TlThFSqRWIm hr7LcsTj6K85MFsessKRj4AXiZCZmlthtgvwkDekHmgmyEJOMDpVLq9AKhVHGy+xvyfF T5+MZpNFZdMzwUvvkC3QycmiJBhyaKTE1iQsoL+JeZJRxiD4b+jmmxfrJVRCKlI1zyqQ QY1B3SowZkQNXlHB4xTBpEwtFjiyS8eTwz6ihdg9oOkA0/sq4FzG+N/ZgQz/To8mXW8t nmT6GiTgO3HI3zmpdMM7V+HtZ/D0qTt9clx7mfG0+uKhT+njxe6yfoQxdWCI+7Auk6aH oy0g==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=oa7m8Eqc; 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 a640c23a62f3a-a906109a18dsi87235766b.121.2024.09.14.04.29.16; Sat, 14 Sep 2024 04:29:16 -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=@khirnov.net header.s=mail header.b=oa7m8Eqc; 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 06A9568DE61; Sat, 14 Sep 2024 14:11:10 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0C86168DDC8 for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=oa7m8Eqc; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 0BD324E07 for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id PHu-fRNF0iSr for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=QPf9PMiO1Bs/9HCjYtPvI5c/ORcxha5cw44GDm7NqUI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oa7m8Eqc/fBSpxASLXzR89byf0BLEVHyqtErLoybTkHby3tvJugsuC5wfc4bHvuMi q2utZuWS4tod+HRQ4yNlDKtbRG1k3sjC+opveu7NXLeCNcPjXBcjDuxfspwEnt67GD PClG8KpmrQ1vSd2EBWaz1wq/rDNFdYx+H6m7NmpXewNd+Xqgz94UKqgXhFlzilKDiu w9amsvZwYbsfunzK6wS1kEr0nFV2PomlXODMn9Wt5guN6YFtybMKc6lwUMxAbIrenC LhdFwTgwOLUjChbVt3zr7KWkZY87ifx1LFlnKSuy9k54892ycA5NF+6peCvoHtTMZy dIPKnHmuJvCQQ== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 769E94E12 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 664F33A1B33 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:37 +0200 Message-ID: <20240914111036.17164-13-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 12/23] lavc/hevcdec: implement slice header parsing for nuh_layer_id>0 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: vqwQJKnyFKMm Cf. F.7.3.6.1 "General slice segment header syntax" --- libavcodec/hevc/hevcdec.c | 36 ++++++++++++++++++++++++++++++++---- libavcodec/hevc/hevcdec.h | 1 + 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index ebe2f5ad11..d3a47b65f4 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -584,7 +584,8 @@ static int hls_slice_header(SliceHeader *sh, const HEVCContext *s, GetBitContext { const HEVCPPS *pps; const HEVCSPS *sps; - unsigned pps_id; + const HEVCVPS *vps; + unsigned pps_id, layer_idx; int i, ret; // Coded parameters @@ -607,6 +608,8 @@ static int hls_slice_header(SliceHeader *sh, const HEVCContext *s, GetBitContext pps = s->ps.pps_list[pps_id]; sps = pps->sps; + vps = sps->vps; + layer_idx = vps->layer_idx[s->nuh_layer_id]; if (s->nal_unit_type == HEVC_NAL_CRA_NUT && s->last_eos == 1) sh->no_output_of_prior_pics_flag = 1; @@ -652,7 +655,8 @@ static int hls_slice_header(SliceHeader *sh, const HEVCContext *s, GetBitContext return AVERROR_INVALIDDATA; } if (IS_IRAP(s) && sh->slice_type != HEVC_SLICE_I && - !pps->pps_curr_pic_ref_enabled_flag) { + !pps->pps_curr_pic_ref_enabled_flag && + s->nuh_layer_id == 0) { av_log(s->avctx, AV_LOG_ERROR, "Inter slices in an IRAP frame.\n"); return AVERROR_INVALIDDATA; } @@ -665,8 +669,10 @@ static int hls_slice_header(SliceHeader *sh, const HEVCContext *s, GetBitContext if (sps->separate_colour_plane) sh->colour_plane_id = get_bits(gb, 2); - if (!IS_IDR(s)) { - int poc, pos; + if (!IS_IDR(s) || + (s->nuh_layer_id > 0 && + !(vps->poc_lsb_not_present & (1 << layer_idx)))) { + int poc; sh->pic_order_cnt_lsb = get_bits(gb, sps->log2_max_poc_lsb); poc = ff_hevc_compute_poc(sps, s->poc_tid0, sh->pic_order_cnt_lsb, s->nal_unit_type); @@ -678,6 +684,10 @@ static int hls_slice_header(SliceHeader *sh, const HEVCContext *s, GetBitContext poc = sh->poc; } sh->poc = poc; + } + + if (!IS_IDR(s)) { + int pos; sh->short_term_ref_pic_set_sps_flag = get_bits1(gb); pos = get_bits_left(gb); @@ -724,6 +734,23 @@ static int hls_slice_header(SliceHeader *sh, const HEVCContext *s, GetBitContext sh->slice_temporal_mvp_enabled_flag = 0; } + sh->inter_layer_pred = 0; + if (s->nuh_layer_id > 0) { + int num_direct_ref_layers = vps->num_direct_ref_layers[layer_idx]; + + if (vps->default_ref_layers_active) + sh->inter_layer_pred = !!num_direct_ref_layers; + else if (num_direct_ref_layers) { + sh->inter_layer_pred = get_bits1(gb); + + if (sh->inter_layer_pred && num_direct_ref_layers > 1) { + av_log(s->avctx, AV_LOG_ERROR, + "NumDirectRefLayers>1 not supported\n"); + return AVERROR_PATCHWELCOME; + } + } + } + if (sps->sao_enabled) { sh->slice_sample_adaptive_offset_flag[0] = get_bits1(gb); if (sps->chroma_format_idc) { @@ -3238,6 +3265,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) int ret; s->nal_unit_type = nal->type; + s->nuh_layer_id = nal->nuh_layer_id; s->temporal_id = nal->temporal_id; if (FF_HW_HAS_CB(s->avctx, decode_params) && diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h index e3194fd87e..16b1d1ce92 100644 --- a/libavcodec/hevc/hevcdec.h +++ b/libavcodec/hevc/hevcdec.h @@ -215,6 +215,7 @@ typedef struct SliceHeader { uint8_t dependent_slice_segment_flag; uint8_t pic_output_flag; uint8_t colour_plane_id; + uint8_t inter_layer_pred; ///< RPS coded in the slice header itself is stored here int short_term_ref_pic_set_sps_flag; From patchwork Sat Sep 14 10:45:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51595 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp311031vqy; Sat, 14 Sep 2024 04:39:18 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUyxKCXiHdzS7jcEbf89oytUeaJumLMX35G+T6ckNd67VCAypGsuhuErzt5X64MGl25TDBQQa+5VtB5bijDWJT3@gmail.com X-Google-Smtp-Source: AGHT+IF4helqDvJmJasYiUXi7KX5IIAvextXGvAv4NmBCuZLInFy14fkb1dhFg6l2s9JgB5pSmnN X-Received: by 2002:a05:6000:184f:b0:374:c8eb:9b18 with SMTP id ffacd0b85a97d-378d61e2ad1mr5661211f8f.24.1726313957862; Sat, 14 Sep 2024 04:39:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313957; cv=none; d=google.com; s=arc-20240605; b=VTXm588iVrlYNLqWWF+YWzgCboAIOPrM0er84y1VR61YlcD7g94SqrjPd9BSxUiEx+ /1y/1Hdbrgm1CeZbsPHPAft5nPceSNiJINTTxZ+TdfB9aSnuDa9aIAQDSaUZn7U8eZMQ FZai0kgHORzO82qxdp7GS+Yig69sqYPOtHJ1YheYcnU24mRjVWNrfokDu4cBYBvtTvch 31/G9oKuONXR1mOKTUBjGl0SWCkwia1hXTqiBU81xCMJKfX6L24znAjx2WYsGju6n5CH fzm1LYG6WWwdXv/KSxTqs67cjErtpsEYaEgu4qcmphCpJqQbZHmx/K9ADbZIhFkiiBrM woxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=PbU9PCFkI8xnZZg4o4f/6ADAlB7f2ZwN9LTCJmBs2Ls=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=Z3kk65b++K7NwnmLZ7WG6rKI4Z9AHX5jfNOFjFQkOlhHAKJ9N10QGybDLoAnZv1GLI DOEYLLrKdpRRB4gZZAiG1jnsGvUcb3UeKG+jUWZ9EzcaFsNtVupdFF0KPoOq+or2S9AU xz2DmvvnSHfzsYzrUyIreRpyQoBCGVPyoY58Wa2w59e2uJFTInEURw/8YmTmnpaI03B/ 9i8TFcvsCTN9jvkuBQFKf2rEfV22Y4/7rKwf0EDkMXA5C15w5B3nxpOZPXshagyx2aZy E5Aw/Wc6niOIqHzRZhd8/+GtWtXcY2ebqCkzF2a4EL9w3sEsiz3uDFtPRt5zyD49FZai SYtA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=TirwhKk+; 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 a640c23a62f3a-a90612e7c7dsi81999466b.503.2024.09.14.04.39.17; Sat, 14 Sep 2024 04:39:17 -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=@khirnov.net header.s=mail header.b=TirwhKk+; 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 EB3E168DE6B; Sat, 14 Sep 2024 14:11:10 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1277F68DDB8 for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=TirwhKk+; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 369BE4E09 for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id JmAJRErJxiJ2 for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=EgUsRMu0U8QpLjDWUUvAmjPeMhlsWKR3mOqU0Pjk61w=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TirwhKk+siHAjuoWeIUk47REdthjLG5uZb/q/BySzY5LGc4NnjxEuYUno/EMUwyGa EErduNpjdQa1YOWhXrZqtde/V6+ea+F8BWY/NGv2ViEBr87YXJt4eUyRchaaaaRFny 0+TeReazm1hJ8lQsRPCgMPxhanhFYa5jCDvJFUsbj2uUt7PLwSAP59/cC70KuhvkoW PL6vehAfz8nXrw+7EZai71jUV3ugYrLwKov4fPCAfdCpD7w58MjjJLXuwXeM5n72HR +4kS9sGm/TAf3DFtTwXrdS9eYMvpQVOrrFFXZtQQ9ZPjp2ZXBO/bR5SoMD8GU/bk7t KCYPYutSL+61w== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 7D9FD4E13 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 720FA3A1DFD for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:38 +0200 Message-ID: <20240914111036.17164-14-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 13/23] lavc/hevc/hevcdec: implement MV-HEVC inter-layer prediction 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: AaEu15A8RhXR The per-frame reference picture set contains two more lists - INTER_LAYER[01]. Assuming at most two layers, INTER_LAYER1 is always empty, but is added anyway for completeness. When inter-layer prediction is enabled, INTER_LAYER0 for the second-layer frame will contain the base-layer frame from the same access unit, if it exists. The new lists are then used in per-slice reference picture set construction as per F.8.3.4 "Decoding process for reference picture lists construction". --- libavcodec/hevc/hevcdec.c | 7 ++++- libavcodec/hevc/hevcdec.h | 8 ++++-- libavcodec/hevc/refs.c | 58 ++++++++++++++++++++++++++++++--------- libavcodec/nvdec_hevc.c | 2 +- libavcodec/vdpau_hevc.c | 2 +- 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index d3a47b65f4..cbf763b8be 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -784,7 +784,7 @@ static int hls_slice_header(SliceHeader *sh, const HEVCContext *s, GetBitContext sh->rpl_modification_flag[0] = 0; sh->rpl_modification_flag[1] = 0; - nb_refs = ff_hevc_frame_nb_refs(sh, pps); + nb_refs = ff_hevc_frame_nb_refs(sh, pps, layer_idx); if (!nb_refs) { av_log(s->avctx, AV_LOG_ERROR, "Zero refs for a frame with P or B slices.\n"); return AVERROR_INVALIDDATA; @@ -3356,6 +3356,11 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) s->eos = 0; s->slice_initialized = 0; + for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) { + HEVCLayerContext *l = &s->layers[i]; + l->cur_frame = NULL; + } + /* split the input packet into NAL units, so we know the upper bound on the * number of slices in the frame */ ret = ff_h2645_packet_split(&s->pkt, buf, length, s->avctx, diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h index 16b1d1ce92..57bf5aa599 100644 --- a/libavcodec/hevc/hevcdec.h +++ b/libavcodec/hevc/hevcdec.h @@ -84,6 +84,8 @@ enum RPSType { ST_FOLL, LT_CURR, LT_FOLL, + INTER_LAYER0, + INTER_LAYER1, NB_RPS_TYPE, }; @@ -442,6 +444,7 @@ typedef struct HEVCLocalContext { typedef struct HEVCLayerContext { HEVCFrame DPB[32]; + HEVCFrame *cur_frame; const HEVCSPS *sps; // RefStruct reference @@ -498,7 +501,7 @@ typedef struct HEVCContext { struct AVMD5 *md5_ctx; ///< candidate references for the current frame - RefPicList rps[5]; + RefPicList rps[NB_RPS_TYPE]; const HEVCVPS *vps; ///< RefStruct reference const HEVCPPS *pps; ///< RefStruct reference @@ -615,7 +618,8 @@ int ff_hevc_res_scale_sign_flag(HEVCLocalContext *lc, int idx); /** * Get the number of candidate references for the current frame. */ -int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps); +int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps, + unsigned layer_idx); int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc); diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index 20fdbb5794..625ac68aaa 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -149,6 +149,7 @@ int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) return AVERROR(ENOMEM); s->cur_frame = ref; + l->cur_frame = ref; s->collocated_ref = NULL; if (s->sh.pic_output_flag) @@ -248,7 +249,9 @@ int ff_hevc_slice_rpl(HEVCContext *s) return ret; if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs + - s->rps[LT_CURR].nb_refs) && !s->pps->pps_curr_pic_ref_enabled_flag) { + s->rps[LT_CURR].nb_refs + + s->rps[INTER_LAYER0].nb_refs + s->rps[INTER_LAYER1].nb_refs) && + !s->pps->pps_curr_pic_ref_enabled_flag) { av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n"); return AVERROR_INVALIDDATA; } @@ -258,11 +261,14 @@ int ff_hevc_slice_rpl(HEVCContext *s) RefPicList *rpl = &s->cur_frame->refPicList[list_idx]; /* The order of the elements is - * ST_CURR_BEF - ST_CURR_AFT - LT_CURR for the L0 and - * ST_CURR_AFT - ST_CURR_BEF - LT_CURR for the L1 */ - int cand_lists[3] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF, - list_idx ? ST_CURR_BEF : ST_CURR_AFT, - LT_CURR }; + * ST_CURR_BEF - INTER_LAYER0 - ST_CURR_AFT - LT_CURR - INTER_LAYER1 for the L0 and + * ST_CURR_AFT - INTER_LAYER1 - ST_CURR_BEF - LT_CURR - INTER_LAYER0 for the L1 */ + int cand_lists[] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF, + list_idx ? INTER_LAYER1 : INTER_LAYER0, + list_idx ? ST_CURR_BEF : ST_CURR_AFT, + LT_CURR, + list_idx ? INTER_LAYER0 : INTER_LAYER1 + }; /* concatenate the candidate lists for the current frame */ while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) { @@ -271,7 +277,11 @@ int ff_hevc_slice_rpl(HEVCContext *s) for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < HEVC_MAX_REFS; j++) { rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j]; rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j]; - rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = i == 2; + // multiview inter-layer refs are treated as long-term here, + // cf. G.8.1.3 + rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = cand_lists[i] == LT_CURR || + cand_lists[i] == INTER_LAYER0 || + cand_lists[i] == INTER_LAYER1; rpl_tmp.nb_refs++; } } @@ -410,11 +420,6 @@ int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l) RefPicList *rps = s->rps; int i, ret = 0; - if (!short_rps) { - rps[0].nb_refs = rps[1].nb_refs = 0; - return 0; - } - unref_missing_refs(l); /* clear the reference flags on all frames except the current one */ @@ -430,6 +435,9 @@ int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l) for (i = 0; i < NB_RPS_TYPE; i++) rps[i].nb_refs = 0; + if (!short_rps) + goto inter_layer; + /* add the short refs */ for (i = 0; i < short_rps->num_delta_pocs; i++) { int poc = s->poc + short_rps->delta_poc[i]; @@ -459,6 +467,24 @@ int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l) goto fail; } +inter_layer: + /* add inter-layer refs */ + if (s->sh.inter_layer_pred) { + HEVCLayerContext *l0 = &s->layers[0]; + + av_assert0(l != l0); + + /* Given the assumption of at most two layers, refPicSet0Flag is + * always 1, so only RefPicSetInterLayer0 can ever contain a frame. */ + if (l0->cur_frame) { + // inter-layer refs are treated as short-term here, cf. F.8.1.6 + ret = add_candidate_ref(s, l0, &rps[INTER_LAYER0], l0->cur_frame->poc, + HEVC_FRAME_FLAG_SHORT_REF, 1); + if (ret < 0) + goto fail; + } + } + fail: /* release any frames that are now unused */ for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) @@ -467,7 +493,8 @@ fail: return ret; } -int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps) +int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps, + unsigned layer_idx) { int ret = 0; int i; @@ -486,6 +513,11 @@ int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps) ret += !!long_rps->used[i]; } + if (sh->inter_layer_pred) { + av_assert0(pps->sps->vps->num_direct_ref_layers[layer_idx] < 2); + ret++; + } + if (pps->pps_curr_pic_ref_enabled_flag) ret++; diff --git a/libavcodec/nvdec_hevc.c b/libavcodec/nvdec_hevc.c index 6888507535..e01ce4c782 100644 --- a/libavcodec/nvdec_hevc.c +++ b/libavcodec/nvdec_hevc.c @@ -188,7 +188,7 @@ static int nvdec_hevc_start_frame(AVCodecContext *avctx, .NumBitsForShortTermRPSInSlice = s->sh.short_term_rps ? s->sh.short_term_ref_pic_set_size : 0, .NumDeltaPocsOfRefRpsIdx = s->sh.short_term_rps ? s->sh.short_term_rps->rps_idx_num_delta_pocs : 0, - .NumPocTotalCurr = ff_hevc_frame_nb_refs(&s->sh, pps), + .NumPocTotalCurr = ff_hevc_frame_nb_refs(&s->sh, pps, s->cur_layer), .NumPocStCurrBefore = s->rps[ST_CURR_BEF].nb_refs, .NumPocStCurrAfter = s->rps[ST_CURR_AFT].nb_refs, .NumPocLtCurr = s->rps[LT_CURR].nb_refs, diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index affb7e7f5a..0ddcafd897 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -206,7 +206,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx, } } /* See section 7.4.7.2 of the specification. */ - info->NumPocTotalCurr = ff_hevc_frame_nb_refs(&h->sh, pps); + info->NumPocTotalCurr = ff_hevc_frame_nb_refs(&h->sh, pps, h->cur_layer); if (sh->short_term_ref_pic_set_sps_flag == 0 && sh->short_term_rps) { /* Corresponds to specification field, NumDeltaPocs[RefRpsIdx]. Only applicable when short_term_ref_pic_set_sps_flag == 0. From patchwork Sat Sep 14 10:45:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51586 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp303514vqy; Sat, 14 Sep 2024 04:19:24 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVpt9A+OdxkNknQczz12fMKh3+IHVjWiXfn9eZUdAgsg4L5Cnybo8n8nj88sZj8D59h/wF6kIeAfoxC3tfhHIGC@gmail.com X-Google-Smtp-Source: AGHT+IG/9iUKKJPqe0Mz1EQnrI7DV1+7T4PAxheVZigaQG9Zng698TA7UoDdeoVrK9F20K7VDO5C X-Received: by 2002:a17:907:f75a:b0:a86:a90f:3025 with SMTP id a640c23a62f3a-a90480ce2a2mr536865366b.59.1726312764378; Sat, 14 Sep 2024 04:19:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312764; cv=none; d=google.com; s=arc-20240605; b=fI7dEmBTZXqrw9WKODUR+zRbEgMLuYkLIVunSI4pRI/FB4JLqWCsH2CIivRlIQcPbQ urQ/APst9RmRWoDQbpJ3bD+8cQIsYbg57xSAAh3g5jZDmBvvivgy9MQ7H/FAvVh4W016 ffYyf73NJEr01Ids/3z2/XJFN2vZQmZGDduBDhEm5Zd3QNSX0k2tH0fdJeBTWWiItzFt VOkqiHHH72klrlDAh+rEhP9zgRBOY8jM8daSAnL+DjIctxeXUagQoik3YKCS5FrsYv87 3UZf6neu2Z6LbRzcW0m2rFNoogmUmooMAy2UU3Xx0ELvUnfod+tezwU+eiDmaZjRAJ6N gXvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=Y+8oL9hrgcQanRpjbBjiIm8TRbrIt6uuq/1aOTmrWyk=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=KbuR5OZDJg+/kPBwpqdCDNanZwRfF12O2zuRQH+nsPp0GmqIVSuNnAwIxLEUJITwCX JbHZoGIoNi6Rcm2llJ5Fe+cx+LXZ5fOSDC4h7aqWdomDSxZyMfbviPtnPpAnd3lZrkwd 9OMlutu9ZX3pm9wtMyInNLSSQN+rhVIBUMelEzH7bgyivHTJRQ/7z5dqmku4Cidryg1Z UQyQhxj0Hjd9r2Yt7oM2WTnmKjuEzN/7bHHXOOZFTwSuJno6mLJCuWNQed8OrCedk3Ca V0RsZaaan5whm4mqAG0ICqmcZ9sN+c6GB+693nWTdB0JGV2P//ZjX0jm0WvZDjDLfMI+ yuag==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=XBB9Sj5v; 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 a640c23a62f3a-a906133aa9dsi85705866b.862.2024.09.14.04.19.24; Sat, 14 Sep 2024 04:19: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; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=XBB9Sj5v; 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 6091168DDFF; Sat, 14 Sep 2024 14:11:01 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BE99568DBA3 for ; Sat, 14 Sep 2024 14:10:53 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=XBB9Sj5v; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id AB5534E11 for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id AocUpMwCAm9E for ; Sat, 14 Sep 2024 13:10:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=eF4yBVIFT6kfIUwdv7m7k/98WRLnrlrV3yxU3Uqm56M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XBB9Sj5vjQXsouAOGRCXZeEpsqnRPykPWInKqPmXoEYNmQ0Wl+K9DBctqzpJ1Dq/X ++38bdDhN6/E7aoHBChhOLZm9qsAwvOeh2NH+FM/GfcCBz1/ITqPSnsL5i0h/M7lfh GxsRRzY5fmuWZwzz1sfPNR6B00OpsU/I13Qw7qLJGX8DcXdKXO3GXr8Z+8BzGBAmkv /TvGNSvBomevHx85gfkWA99toCQ0fKpgKLXeFTkdVwj6YNay80v85fC7PbxCmBRZfn vBAL612JiiwBrpU+Y8GVehDNpkmmC1uA4zKHqYIn+8AkADEy/e309626G5w94ETrbk YkhMsucMR7ssQ== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 7E2C64E14 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 7D9393A1E08 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:39 +0200 Message-ID: <20240914111036.17164-15-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 14/23] avcodec/decode: split ProgressFrame allocator into two functions 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: E6hAz96cEX/E From: James Almer Signed-off-by: James Almer Signed-off-by: Anton Khirnov --- libavcodec/decode.c | 11 +++++++---- libavcodec/progressframe.h | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 27dba8a1f3..5f6646ea4d 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1724,7 +1724,7 @@ static void check_progress_consistency(const ProgressFrame *f) av_assert1(!f->progress || f->progress->f == f->f); } -static int progress_frame_get(AVCodecContext *avctx, ProgressFrame *f) +int ff_progress_frame_alloc(AVCodecContext *avctx, ProgressFrame *f) { FFRefStructPool *pool = avctx->internal->progress_frame_pool; @@ -1742,9 +1742,12 @@ int ff_progress_frame_get_buffer(AVCodecContext *avctx, ProgressFrame *f, int fl { int ret; - ret = progress_frame_get(avctx, f); - if (ret < 0) - return ret; + check_progress_consistency(f); + if (!f->f) { + ret = ff_progress_frame_alloc(avctx, f); + if (ret < 0) + return ret; + } ret = ff_thread_get_buffer(avctx, f->progress->f, flags); if (ret < 0) { diff --git a/libavcodec/progressframe.h b/libavcodec/progressframe.h index 428a461659..32a345beec 100644 --- a/libavcodec/progressframe.h +++ b/libavcodec/progressframe.h @@ -102,12 +102,24 @@ void ff_progress_frame_report(ProgressFrame *f, int progress); void ff_progress_frame_await(const ProgressFrame *f, int progress); /** - * This function sets up the ProgressFrame, i.e. gets ProgressFrame.f - * and also calls ff_thread_get_buffer() on the frame. + * This function allocates ProgressFrame.f + * May be called before ff_progress_frame_get_buffer() in the cases where the + * AVFrame needs to be accessed before the ff_thread_get_buffer() call in + * ff_progress_frame_alloc(). * * @note: This must only be called by codecs with the * FF_CODEC_CAP_USES_PROGRESSFRAMES internal cap. */ +int ff_progress_frame_alloc(struct AVCodecContext *avctx, ProgressFrame *f); + +/** + * This function sets up the ProgressFrame, i.e. allocates ProgressFrame.f + * if needed, and also calls ff_thread_get_buffer() on the frame. + * + * @note: This must only be called by codecs with the + * FF_CODEC_CAP_USES_PROGRESSFRAMES internal cap. + * @see ff_progress_frame_alloc + */ int ff_progress_frame_get_buffer(struct AVCodecContext *avctx, ProgressFrame *f, int flags); From patchwork Sat Sep 14 10:45:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51589 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp307007vqy; Sat, 14 Sep 2024 04:29:14 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCU+EWi6YYQoIfD+zFc2JKaZqEdVqAqTVOwWaW+ggTywHfUPBEr4o9o3UdwlSQR2vgIGOD6FYL452UVxLDq5OYKv@gmail.com X-Google-Smtp-Source: AGHT+IFFUo/njsZ1uQ8vM2aiuClR4ZcTwoIEoitA2H2ywOlQ7B50LAZEe8ttSBn74lGRCfVISLvO X-Received: by 2002:a05:6512:3e08:b0:52f:c438:883c with SMTP id 2adb3069b0e04-53678fab60amr1632166e87.1.1726313354438; Sat, 14 Sep 2024 04:29:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313354; cv=none; d=google.com; s=arc-20240605; b=kE1K9CPpmmEtS0KZyMQQGSfuyPP8sww6rBqYj0hB0u6Xi/gpxQLYhsh4d5kKgKYz1z KHJg/LyGXyIb0ieqYf3Fi0KKYthLuJZOmEi8RhNJoJDql4rmm3pzd1Nd1ID63mhiVzru UOjoOF3LEYFyS+1K9R9J+dWTQx6tmqktNr0Cc/rOILnr3qn2UvmhSK9/nAomw/TwNwk4 I0ATHc7uEztbT9PHb24bUG9FMWe6poxphCj3U3vGOHlvwe/zucXpORxxQPHfcth6t3DX Dy6d/wFwZz489GIe06+AiiKNTy3UvA1v674SZyVTlTynYObor1AIx5d4bhqxiHmsoBbx eRQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=AkXQnldXNGaLVjeSROkptYopeuMezGFAZfZ7uPGUpE4=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=PTf2aLSOb+NV4CX7qkeihHmDLF8unLDqR+PW4zj6FxVmuHXOQaRKRl2dezY/U0zs7W Vh6gATLDDCrLGAmMaTixeQgK6mlr7Mm7dYzEMf3gA8XcV1rjv9hu+G3ALvrKv8bEVIO4 p1LEHsmF06jiwqc0vYvUJ7uGbxWyiFK9a9G5tHU2MZ0iQPDOKDL5IC3RsaNoLbQnwO4n wJgor5IM3z5DoYWKuQfAnH/yeO918x5O0aZTeTYNLEqlYkhAXRMpBnahwM42Z3sZUufH 48nijby1d//+PoWtgjaXCsZuwfu3+doRf+EmWiQvNGAgmJBNZvyvaahbKsuIRrYAGxsT 87XA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=mdQ5aukC; 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 2adb3069b0e04-536870a0a12si402092e87.375.2024.09.14.04.29.14; Sat, 14 Sep 2024 04:29:14 -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=@khirnov.net header.s=mail header.b=mdQ5aukC; 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 3F39E68DE5C; Sat, 14 Sep 2024 14:11:09 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0B32D68DC90 for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=mdQ5aukC; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id BED364E1E for ; Sat, 14 Sep 2024 13:10:52 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id Xb5VR6j-y5BO for ; Sat, 14 Sep 2024 13:10:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=YKafEcQwvPohXVc+WhQZ2p9G3XhI7CUgetPvCQSFUQM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=mdQ5aukCKxMwM8Ld+9b8NkwwhgBvfRHceJ24N0ooH8jFD6e7N6dc+L56v8kTIfp4v orSMk1LAMpmh+c2qXEiHFi6nT2RGp51FU88dmJ9tT0xHxf62Ip9XtEV5hCTTGqG5Dl hLYWalb1tf2ZMi+EOneTTKTTlyENy3UPy/jqBVpBvuwAZCO+dfTyg32ucX3mwtZBC9 bmtFJq8XRmSzdCspJQzpHgKxUdezVjW+FUu3VIu+zAV1jgzGZrUc0zFeRroLwQLgmO ufNGSoSblicwXqSXbrbKl9A6RCQ/yrQVbmzWojFqZwNvOP0Kfw/45KzS0s6uYcslMz hEu7ujnJhOoOw== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 88F9B4E16 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 89B9F3A1E2B for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:40 +0200 Message-ID: <20240914111036.17164-16-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 15/23] lavc/hevcdec: implement decoding MV-HEVC 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: xCFk1Vnk/TBL At most two layers are supported. Aspects of this work were sponsored by Vimeo and Meta. --- Changelog | 1 + doc/decoders.texi | 45 ++++++ libavcodec/hevc/hevcdec.c | 332 ++++++++++++++++++++++++++++++++++---- libavcodec/hevc/hevcdec.h | 34 +++- libavcodec/hevc/refs.c | 67 ++++++-- 5 files changed, 423 insertions(+), 56 deletions(-) diff --git a/Changelog b/Changelog index b6f91d7c8c..ff5d1b1bc8 100644 --- a/Changelog +++ b/Changelog @@ -21,6 +21,7 @@ version : - MediaCodec AAC/AMR-NB/AMR-WB/MP3 decoding - YUV colorspace negotiation for codecs and filters, obsoleting the YUVJ pixel format +- MV-HEVC decoding version 7.0: diff --git a/doc/decoders.texi b/doc/decoders.texi index 2fcc761d2f..17bb361ffa 100644 --- a/doc/decoders.texi +++ b/doc/decoders.texi @@ -38,6 +38,51 @@ Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0. @end table +@section hevc +HEVC (AKA ITU-T H.265 or ISO/IEC 23008-2) decoder. + +The decoder supports MV-HEVC multiview streams with at most two views. Views to +be output are selected by supplying a list of view IDs to the decoder (the +@option{view_ids} option). This option may be set either statically before +decoder init, or from the @code{get_format()} callback - useful for the case +when the view count or IDs change dynamically during decoding. + +Only the base layer is decoded by default. + +Note that if you are using the @code{ffmpeg} CLI tool, you should be using view +specifiers as documented in its manual, rather than the options documented here. + +@subsection Options + +@table @option + +@item view_ids (MV-HEVC) +Specify a list of view IDs that should be output. This option can also be set to +a single '-1', which will cause all views defined in the VPS to be decoded and +output. + +@item view_ids_available (MV-HEVC) +This option may be read by the caller to retrieve an array of view IDs available +in the active VPS. The array is empty for single-layer video. + +The value of this option is guaranteed to be accurate when read from the +@code{get_format()} callback. It may also be set at other times (e.g. after +opening the decoder), but the value is informational only and may be incorrect +(e.g. when the stream contains multiple distinct VPS NALUs). + +@item view_pos_available (MV-HEVC) +This option may be read by the caller to retrieve an array of view positions +(left, right, or unspecified) available in the active VPS, as +@code{AVStereo3DView} values. When the array is available, its elements apply to +the corresponding elements of @option{view_ids_available}, i.e. +@code{view_pos_available[i]} contains the position of view with ID +@code{view_ids_available[i]}. + +Same validity restrictions as for @option{view_ids_available} apply to +this option. + +@end table + @section rawvideo Raw video decoder. diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index cbf763b8be..692f19e97e 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -34,6 +34,7 @@ #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" +#include "libavutil/stereo3d.h" #include "libavutil/timecode.h" #include "aom_film_grain.h" @@ -417,6 +418,109 @@ static int export_stream_params_from_sei(HEVCContext *s) return 0; } +static int export_multilayer(HEVCContext *s, const HEVCVPS *vps) +{ + const HEVCSEITDRDI *tdrdi = &s->sei.tdrdi; + + av_freep(&s->view_ids_available); + s->nb_view_ids_available = 0; + av_freep(&s->view_pos_available); + s->nb_view_pos_available = 0; + + // don't export anything in the trivial case (1 layer, view id=0) + if (vps->nb_layers < 2 && !vps->view_id[0]) + return 0; + + s->view_ids_available = av_calloc(vps->nb_layers, sizeof(*s->view_ids_available)); + if (!s->view_ids_available) + return AVERROR(ENOMEM); + + if (tdrdi->num_ref_displays) { + s->view_pos_available = av_calloc(vps->nb_layers, sizeof(*s->view_pos_available)); + if (!s->view_pos_available) + return AVERROR(ENOMEM); + } + + for (int i = 0; i < vps->nb_layers; i++) { + s->view_ids_available[i] = vps->view_id[i]; + + if (s->view_pos_available) { + s->view_pos_available[i] = vps->view_id[i] == tdrdi->left_view_id[0] ? + AV_STEREO3D_VIEW_LEFT : + vps->view_id[i] == tdrdi->right_view_id[0] ? + AV_STEREO3D_VIEW_RIGHT : AV_STEREO3D_VIEW_UNSPEC; + } + } + s->nb_view_ids_available = vps->nb_layers; + s->nb_view_pos_available = s->view_pos_available ? vps->nb_layers : 0; + + return 0; +} + +static int setup_multilayer(HEVCContext *s, const HEVCVPS *vps) +{ + unsigned layers_active_output = 0, highest_layer; + + s->layers_active_output = 1; + s->layers_active_decode = 1; + + // nothing requested - decode base layer only + if (!s->nb_view_ids) + return 0; + + if (s->nb_view_ids == 1 && s->view_ids[0] == -1) { + layers_active_output = (1 << vps->nb_layers) - 1; + } else { + for (int i = 0; i < s->nb_view_ids; i++) { + int view_id = s->view_ids[i]; + int layer_idx = -1; + + if (view_id < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid view ID requested: %d\n", view_id); + return AVERROR(EINVAL); + } + + for (int j = 0; j < vps->nb_layers; j++) { + if (vps->view_id[j] == view_id) { + layer_idx = j; + break; + } + } + if (layer_idx < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "View ID %d not present in VPS\n", view_id); + return AVERROR(EINVAL); + } + layers_active_output |= 1 << layer_idx; + } + } + + if (!layers_active_output) { + av_log(s->avctx, AV_LOG_ERROR, "No layers selected\n"); + return AVERROR_BUG; + } + + highest_layer = ff_log2(layers_active_output); + if (highest_layer >= FF_ARRAY_ELEMS(s->layers)) { + av_log(s->avctx, AV_LOG_ERROR, + "Too many layers requested: %u\n", layers_active_output); + return AVERROR(EINVAL); + } + + /* Assume a higher layer depends on all the lower ones. + * This is enforced in VPS parsing currently, this logic will need + * to be changed if we want to support more complex dependency structures. + */ + s->layers_active_decode = (1 << (highest_layer + 1)) - 1; + s->layers_active_output = layers_active_output; + + av_log(s->avctx, AV_LOG_DEBUG, "decode/output layers: %x/%x\n", + s->layers_active_decode, s->layers_active_output); + + return 0; +} + static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) { #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + \ @@ -428,6 +532,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) CONFIG_HEVC_VDPAU_HWACCEL + \ CONFIG_HEVC_VULKAN_HWACCEL) enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; + int ret; switch (sps->pix_fmt) { case AV_PIX_FMT_YUV420P: @@ -547,7 +652,23 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) *fmt++ = sps->pix_fmt; *fmt = AV_PIX_FMT_NONE; - return ff_get_format(s->avctx, pix_fmts); + // export multilayer information from active VPS to the caller, + // so it is available in get_format() + ret = export_multilayer(s, sps->vps); + if (ret < 0) + return ret; + + ret = ff_get_format(s->avctx, pix_fmts); + if (ret < 0) + return ret; + s->avctx->pix_fmt = ret; + + // set up multilayer decoding, if requested by caller + ret = setup_multilayer(s, sps->vps); + if (ret < 0) + return ret; + + return 0; } static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps) @@ -2948,13 +3069,59 @@ static int set_side_data(HEVCContext *s) return 0; } -static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l) +static int find_finish_setup_nal(const HEVCContext *s) +{ + int nal_idx = 0; + + for (int i = nal_idx; i < s->pkt.nb_nals; i++) { + const H2645NAL *nal = &s->pkt.nals[i]; + const int layer_id = nal->nuh_layer_id; + GetBitContext gb = nal->gb; + + if (layer_id > HEVC_MAX_NUH_LAYER_ID || s->vps->layer_idx[layer_id] < 0 || + !(s->layers_active_decode & (1 << s->vps->layer_idx[layer_id]))) + continue; + + switch (nal->type) { + case HEVC_NAL_TRAIL_R: + case HEVC_NAL_TRAIL_N: + case HEVC_NAL_TSA_N: + case HEVC_NAL_TSA_R: + case HEVC_NAL_STSA_N: + case HEVC_NAL_STSA_R: + case HEVC_NAL_BLA_W_LP: + case HEVC_NAL_BLA_W_RADL: + case HEVC_NAL_BLA_N_LP: + case HEVC_NAL_IDR_W_RADL: + case HEVC_NAL_IDR_N_LP: + case HEVC_NAL_CRA_NUT: + case HEVC_NAL_RADL_N: + case HEVC_NAL_RADL_R: + case HEVC_NAL_RASL_N: + case HEVC_NAL_RASL_R: + if (!get_bits1(&gb)) // first_slice_segment_in_pic_flag + continue; + case HEVC_NAL_VPS: + case HEVC_NAL_SPS: + case HEVC_NAL_PPS: + nal_idx = i; + break; + } + } + + return nal_idx; +} + +static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l, + unsigned nal_idx) { const HEVCPPS *const pps = s->ps.pps_list[s->sh.pps_id]; const HEVCSPS *const sps = pps->sps; int pic_size_in_ctb = ((sps->width >> sps->log2_min_cb_size) + 1) * ((sps->height >> sps->log2_min_cb_size) + 1); - int new_sequence = IS_IDR(s) || IS_BLA(s) || s->last_eos; + int new_sequence = (l == &s->layers[0]) && + (IS_IDR(s) || IS_BLA(s) || s->last_eos); + int prev_layers_active = s->layers_active_decode; int ret; if (sps->vps != s->vps && l != &s->layers[0]) { @@ -2965,7 +3132,32 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l) ff_refstruct_replace(&s->pps, pps); if (l->sps != sps) { - enum AVPixelFormat pix_fmt; + const HEVCSPS *sps_base = s->layers[0].sps; + enum AVPixelFormat pix_fmt = sps->pix_fmt; + + if (l != &s->layers[0]) { + if (!sps_base) { + av_log(s->avctx, AV_LOG_ERROR, + "Access unit starts with a non-base layer frame\n"); + return AVERROR_INVALIDDATA; + } + + // Files produced by Vision Pro lack VPS extension VUI, + // so the secondary layer has no range information. + // This check avoids failing in such a case. + if (sps_base->pix_fmt == AV_PIX_FMT_YUVJ420P && + sps->pix_fmt == AV_PIX_FMT_YUV420P && + !sps->vui.common.video_signal_type_present_flag) + pix_fmt = sps_base->pix_fmt; + + if (pix_fmt != sps_base->pix_fmt || + sps->width != sps_base->width || + sps->height != sps_base->height) { + av_log(s->avctx, AV_LOG_ERROR, + "Base/non-base layer SPS have unsupported parameter combination\n"); + return AVERROR(ENOSYS); + } + } ff_hevc_clear_refs(l); @@ -2973,14 +3165,17 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l) if (ret < 0) return ret; - export_stream_params(s, sps); + if (l == &s->layers[0]) { + export_stream_params(s, sps); - pix_fmt = get_format(s, sps); - if (pix_fmt < 0) - return pix_fmt; - s->avctx->pix_fmt = pix_fmt; + ret = get_format(s, sps); + if (ret < 0) { + set_sps(s, l, NULL); + return ret; + } - new_sequence = 1; + new_sequence = 1; + } } memset(l->horizontal_bs, 0, l->bs_width * l->bs_height); @@ -3015,7 +3210,8 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l) s->local_ctx[0].end_of_tiles_x = pps->column_width[0] << sps->log2_ctb_size; if (new_sequence) { - ret = ff_hevc_output_frames(s, l, 0, 0, s->sh.no_output_of_prior_pics_flag); + ret = ff_hevc_output_frames(s, prev_layers_active, + 0, 0, s->sh.no_output_of_prior_pics_flag); if (ret < 0) return ret; } @@ -3072,7 +3268,8 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l) s->cur_frame->f->pict_type = 3 - s->sh.slice_type; - ret = ff_hevc_output_frames(s, l, sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics, + ret = ff_hevc_output_frames(s, s->layers_active_decode, + sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering, 0); if (ret < 0) goto fail; @@ -3083,13 +3280,21 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l) goto fail; } - ff_thread_finish_setup(s->avctx); + // after starting the base-layer frame we know which layers will be decoded, + // so we can now figure out which NALUs to wait for before we can call + // ff_thread_finish_setup() + if (l == &s->layers[0]) + s->finish_setup_nal_idx = find_finish_setup_nal(s); + + if (nal_idx >= s->finish_setup_nal_idx) + ff_thread_finish_setup(s->avctx); return 0; fail: - if (s->cur_frame) - ff_hevc_unref_frame(s->cur_frame, ~0); + if (l->cur_frame) + ff_hevc_unref_frame(l->cur_frame, ~0); + l->cur_frame = NULL; s->cur_frame = s->collocated_ref = NULL; s->slice_initialized = 0; return ret; @@ -3164,9 +3369,9 @@ static int verify_md5(HEVCContext *s, AVFrame *frame) return err; } -static int hevc_frame_end(HEVCContext *s) +static int hevc_frame_end(HEVCContext *s, HEVCLayerContext *l) { - HEVCFrame *out = s->cur_frame; + HEVCFrame *out = l->cur_frame; const AVFilmGrainParams *fgp; av_unused int ret; @@ -3198,23 +3403,32 @@ static int hevc_frame_end(HEVCContext *s) } else { if (s->avctx->err_recognition & AV_EF_CRCCHECK && s->sei.picture_hash.is_md5) { - ret = verify_md5(s, s->cur_frame->f); + ret = verify_md5(s, out->f); if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE) return ret; } } s->sei.picture_hash.is_md5 = 0; - av_log(s->avctx, AV_LOG_DEBUG, "Decoded frame with POC %d.\n", s->poc); + av_log(s->avctx, AV_LOG_DEBUG, "Decoded frame with POC %zu/%d.\n", + l - s->layers, s->poc); return 0; } -static int decode_slice(HEVCContext *s, HEVCLayerContext *l, - const H2645NAL *nal, GetBitContext *gb) +static int decode_slice(HEVCContext *s, unsigned nal_idx, GetBitContext *gb) { + const int layer_idx = s->vps ? s->vps->layer_idx[s->nuh_layer_id] : 0; + HEVCLayerContext *l; int ret; + // skip layers not requested to be decoded + // layers_active_decode can only change while decoding a base-layer frame, + // so we can check it for non-base layers + if (layer_idx < 0 || + (s->nuh_layer_id > 0 && !(s->layers_active_decode & (1 << layer_idx)))) + return 0; + ret = hls_slice_header(&s->sh, s, gb); if (ret < 0) { // hls_slice_header() does not cleanup on failure thus the state now is inconsistant so we cannot use it on depandant slices @@ -3230,16 +3444,25 @@ static int decode_slice(HEVCContext *s, HEVCLayerContext *l, return 0; } + // switching to a new layer, mark previous layer's frame (if any) as done + if (s->cur_layer != layer_idx && + s->layers[s->cur_layer].cur_frame && + s->avctx->active_thread_type == FF_THREAD_FRAME) + ff_progress_frame_report(&s->layers[s->cur_layer].cur_frame->tf, INT_MAX); + + s->cur_layer = layer_idx; + l = &s->layers[s->cur_layer]; + if (s->sh.first_slice_in_pic_flag) { - if (s->cur_frame) { + if (l->cur_frame) { av_log(s->avctx, AV_LOG_ERROR, "Two slices reporting being the first in the same frame.\n"); return AVERROR_INVALIDDATA; } - ret = hevc_frame_start(s, l); + ret = hevc_frame_start(s, l, nal_idx); if (ret < 0) return ret; - } else if (!s->cur_frame) { + } else if (!l->cur_frame) { av_log(s->avctx, AV_LOG_ERROR, "First slice in a frame missing.\n"); return AVERROR_INVALIDDATA; } @@ -3251,16 +3474,16 @@ static int decode_slice(HEVCContext *s, HEVCLayerContext *l, return AVERROR_INVALIDDATA; } - ret = decode_slice_data(s, l, nal, gb); + ret = decode_slice_data(s, l, &s->pkt.nals[nal_idx], gb); if (ret < 0) return ret; return 0; } -static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) +static int decode_nal_unit(HEVCContext *s, unsigned nal_idx) { - HEVCLayerContext *l = &s->layers[0]; + H2645NAL *nal = &s->pkt.nals[nal_idx]; GetBitContext gb = nal->gb; int ret; @@ -3319,7 +3542,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) case HEVC_NAL_RADL_R: case HEVC_NAL_RASL_N: case HEVC_NAL_RASL_R: - ret = decode_slice(s, l, nal, &gb); + ret = decode_slice(s, nal_idx, &gb); if (ret < 0) goto fail; break; @@ -3420,11 +3643,10 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) H2645NAL *nal = &s->pkt.nals[i]; if (s->avctx->skip_frame >= AVDISCARD_ALL || - (s->avctx->skip_frame >= AVDISCARD_NONREF - && ff_hevc_nal_is_nonref(nal->type)) || nal->nuh_layer_id > 0) + (s->avctx->skip_frame >= AVDISCARD_NONREF && ff_hevc_nal_is_nonref(nal->type))) continue; - ret = decode_nal_unit(s, nal); + ret = decode_nal_unit(s, i); if (ret < 0) { av_log(s->avctx, AV_LOG_WARNING, "Error parsing NAL unit #%d.\n", i); @@ -3433,12 +3655,17 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) } fail: - if (s->cur_frame) { + for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) { + HEVCLayerContext *l = &s->layers[i]; + + if (!l->cur_frame) + continue; + if (ret >= 0) - ret = hevc_frame_end(s); + ret = hevc_frame_end(s, l); if (s->avctx->active_thread_type == FF_THREAD_FRAME) - ff_progress_frame_report(&s->cur_frame->tf, INT_MAX); + ff_progress_frame_report(&l->cur_frame->tf, INT_MAX); } return ret; @@ -3459,6 +3686,11 @@ static int hevc_decode_extradata(HEVCContext *s, uint8_t *buf, int length, int f if (first && s->ps.sps_list[i]) { const HEVCSPS *sps = s->ps.sps_list[i]; export_stream_params(s, sps); + + ret = export_multilayer(s, sps->vps); + if (ret < 0) + return ret; + break; } } @@ -3489,7 +3721,7 @@ static int hevc_receive_frame(AVCodecContext *avctx, AVFrame *frame) av_packet_unref(avpkt); ret = ff_decode_get_packet(avctx, avpkt); if (ret == AVERROR_EOF) { - ret = ff_hevc_output_frames(s, &s->layers[0], 0, 0, 0); + ret = ff_hevc_output_frames(s, s->layers_active_decode, 0, 0, 0); if (ret < 0) return ret; goto do_output; @@ -3555,6 +3787,8 @@ static int hevc_ref_frame(HEVCFrame *dst, const HEVCFrame *src) dst->ctb_count = src->ctb_count; dst->flags = src->flags; + dst->base_layer_frame = src->base_layer_frame; + ff_refstruct_replace(&dst->hwaccel_picture_private, src->hwaccel_picture_private); @@ -3690,9 +3924,24 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->is_nalff = s0->is_nalff; s->nal_length_size = s0->nal_length_size; + s->layers_active_decode = s0->layers_active_decode; + s->layers_active_output = s0->layers_active_output; s->film_grain_warning_shown = s0->film_grain_warning_shown; + if (s->nb_view_ids != s0->nb_view_ids || + memcmp(s->view_ids, s0->view_ids, sizeof(*s->view_ids) * s->nb_view_ids)) { + av_freep(&s->view_ids); + s->nb_view_ids = 0; + + if (s0->nb_view_ids) { + s->view_ids = av_memdup(s0->view_ids, s0->nb_view_ids * sizeof(*s0->view_ids)); + if (!s->view_ids) + return AVERROR(ENOMEM); + s->nb_view_ids = s0->nb_view_ids; + } + } + ret = ff_h2645_sei_ctx_replace(&s->sei.common, &s0->sei.common); if (ret < 0) return ret; @@ -3787,6 +4036,19 @@ static const AVOption options[] = { AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR }, { "strict-displaywin", "stricly apply default display window size", OFFSET(apply_defdispwin), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR }, + { "view_ids", "Array of view IDs that should be decoded and output; a single -1 to decode all views", + .offset = OFFSET(view_ids), .type = AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, + .min = -1, .max = INT_MAX, .flags = PAR }, + { "view_ids_available", "Array of available view IDs is exported here", + .offset = OFFSET(view_ids_available), .type = AV_OPT_TYPE_UINT | AV_OPT_TYPE_FLAG_ARRAY, + .flags = PAR | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY }, + { "view_pos_available", "Array of view positions for view_ids_available is exported here, as AVStereo3DView", + .offset = OFFSET(view_pos_available), .type = AV_OPT_TYPE_UINT | AV_OPT_TYPE_FLAG_ARRAY, + .flags = PAR | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY, .unit = "view_pos" }, + { "unspecified", .type = AV_OPT_TYPE_CONST, .default_val = { .i64 = AV_STEREO3D_VIEW_UNSPEC }, .unit = "view_pos" }, + { "left", .type = AV_OPT_TYPE_CONST, .default_val = { .i64 = AV_STEREO3D_VIEW_LEFT }, .unit = "view_pos" }, + { "right", .type = AV_OPT_TYPE_CONST, .default_val = { .i64 = AV_STEREO3D_VIEW_RIGHT }, .unit = "view_pos" }, + { NULL }, }; diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h index 57bf5aa599..9a6c829958 100644 --- a/libavcodec/hevc/hevcdec.h +++ b/libavcodec/hevc/hevcdec.h @@ -375,6 +375,10 @@ typedef struct HEVCFrame { void *hwaccel_picture_private; ///< RefStruct reference + // for secondary-layer frames, this is the DPB index of the base-layer frame + // from the same AU, if it exists, otherwise -1 + int base_layer_frame; + /** * A combination of HEVC_FRAME_FLAG_* */ @@ -487,9 +491,13 @@ typedef struct HEVCContext { HEVCLocalContext *local_ctx; unsigned nb_local_ctx; - HEVCLayerContext layers[1]; - // index in layers of the layer currently being decoded + // per-layer decoding state, addressed by VPS layer indices + HEVCLayerContext layers[HEVC_VPS_MAX_LAYERS]; + // VPS index of the layer currently being decoded unsigned cur_layer; + // bitmask of layer indices that are active for decoding/output + unsigned layers_active_decode; + unsigned layers_active_output; /** 1 if the independent slice segment header was successfully parsed */ uint8_t slice_initialized; @@ -539,11 +547,24 @@ typedef struct HEVCContext { H2645Packet pkt; // type of the first VCL NAL of the current frame enum HEVCNALUnitType first_nal_type; + // index in pkt.nals of the NAL unit after which we can call + // ff_thread_finish_setup() + unsigned finish_setup_nal_idx; int is_nalff; ///< this flag is != 0 if bitstream is encapsulated ///< as a format defined in 14496-15 int apply_defdispwin; + // multi-layer AVOptions + int *view_ids; + unsigned nb_view_ids; + + unsigned *view_ids_available; + unsigned nb_view_ids_available; + + unsigned *view_pos_available; + unsigned nb_view_pos_available; + int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4) int nuh_layer_id; @@ -644,12 +665,13 @@ static av_always_inline int ff_hevc_nal_is_nonref(enum HEVCNALUnitType type) * Find frames in the DPB that are ready for output and either write them to the * output FIFO or drop their output flag, depending on the value of discard. * - * @param max_output maximum number of output-pending frames that can be - * present in the DPB before output is triggered + * @param max_output maximum number of AUs with an output-pending frame in at + * least one layer that can be present in the DPB before output + * is triggered * @param max_dpb maximum number of any frames that can be present in the DPB - * before output is triggered + * for any layer before output is triggered */ -int ff_hevc_output_frames(HEVCContext *s, HEVCLayerContext *l, +int ff_hevc_output_frames(HEVCContext *s, unsigned layers_active, unsigned max_output, unsigned max_dpb, int discard); void ff_hevc_unref_frame(HEVCFrame *frame, int flags); diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index 625ac68aaa..b9b08ca416 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -80,12 +80,32 @@ void ff_hevc_flush_dpb(HEVCContext *s) static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) { + const HEVCVPS *vps = l->sps->vps; + const int view_id = vps->view_id[s->cur_layer]; int i, j, ret; for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { HEVCFrame *frame = &l->DPB[i]; if (frame->f) continue; + ret = ff_progress_frame_alloc(s->avctx, &frame->tf); + if (ret < 0) + return NULL; + + // add view ID side data if it's nontrivial + if (vps->nb_layers > 1 || view_id) { + AVFrameSideData *sd = av_frame_side_data_new(&frame->f->side_data, + &frame->f->nb_side_data, + AV_FRAME_DATA_VIEW_ID, + sizeof(int), 0); + if (!sd) + goto fail; + *(int*)sd->data = view_id; + } + + if (!(s->layers_active_output & (1 << s->cur_layer))) + frame->f->flags |= AV_FRAME_FLAG_DISCARD; + ret = ff_progress_frame_get_buffer(s->avctx, &frame->tf, AV_GET_BUFFER_FLAG_REF); if (ret < 0) @@ -152,6 +172,9 @@ int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) l->cur_frame = ref; s->collocated_ref = NULL; + ref->base_layer_frame = (l != &s->layers[0] && s->layers[0].cur_frame) ? + s->layers[0].cur_frame - s->layers[0].DPB : -1; + if (s->sh.pic_output_flag) ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; else @@ -176,30 +199,44 @@ static void unref_missing_refs(HEVCLayerContext *l) } } -int ff_hevc_output_frames(HEVCContext *s, HEVCLayerContext *l, +int ff_hevc_output_frames(HEVCContext *s, unsigned layers_active, unsigned max_output, unsigned max_dpb, int discard) { while (1) { - int nb_dpb = 0; + int nb_dpb[HEVC_VPS_MAX_LAYERS] = { 0 }; int nb_output = 0; int min_poc = INT_MAX; - int i, min_idx, ret = 0; + int min_layer = -1; + int min_idx, ret = 0; - for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { - HEVCFrame *frame = &l->DPB[i]; - if (frame->flags & HEVC_FRAME_FLAG_OUTPUT) { - nb_output++; - if (frame->poc < min_poc || nb_output == 1) { - min_poc = frame->poc; - min_idx = i; + for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { + HEVCLayerContext *l = &s->layers[layer]; + + if (!(layers_active & (1 << layer))) + continue; + + for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { + HEVCFrame *frame = &l->DPB[i]; + if (frame->flags & HEVC_FRAME_FLAG_OUTPUT) { + // nb_output counts AUs with an output-pending frame + // in at least one layer + if (!(frame->base_layer_frame >= 0 && + (s->layers[0].DPB[frame->base_layer_frame].flags & HEVC_FRAME_FLAG_OUTPUT))) + nb_output++; + if (min_layer < 0 || frame->poc < min_poc) { + min_poc = frame->poc; + min_idx = i; + min_layer = layer; + } } + nb_dpb[layer] += !!frame->flags; } - nb_dpb += !!frame->flags; } if (nb_output > max_output || - (nb_output && nb_dpb > max_dpb)) { - HEVCFrame *frame = &l->DPB[min_idx]; + (nb_output && + (nb_dpb[0] > max_dpb || nb_dpb[1] > max_dpb))) { + HEVCFrame *frame = &s->layers[min_layer].DPB[min_idx]; AVFrame *f = frame->needs_fg ? frame->frame_grain : frame->f; if (!discard) { @@ -210,8 +247,8 @@ int ff_hevc_output_frames(HEVCContext *s, HEVCLayerContext *l, if (ret < 0) return ret; - av_log(s->avctx, AV_LOG_DEBUG, "%s frame with POC %d.\n", - discard ? "Discarded" : "Output", frame->poc); + av_log(s->avctx, AV_LOG_DEBUG, "%s frame with POC %d/%d.\n", + discard ? "Discarded" : "Output", min_layer, frame->poc); continue; } return 0; From patchwork Sat Sep 14 10:45:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51588 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp303520vqy; Sat, 14 Sep 2024 04:19:25 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWDi8msJWBDUEDjmnBP6yLSpo9vTzKgqbIirrINlqx/70xZ8z9C6d6uPYTdcY7cHk8OLC3MStEQeFSb9meyo9RE@gmail.com X-Google-Smtp-Source: AGHT+IHjfuBmwzdGH/i6RD27zvWPphUu/kLDBLfydMvmya8HPHZFIxsvu+WPPCD56imy/EnoXUL4 X-Received: by 2002:a17:907:6d1f:b0:a86:4649:28e6 with SMTP id a640c23a62f3a-a9029690562mr964620166b.57.1726312765634; Sat, 14 Sep 2024 04:19:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726312765; cv=none; d=google.com; s=arc-20240605; b=ZtvMmCCrGkD1o1yntIsSFOLK5plCwybzY1UkfaHpJyefaXBLRiYCEp5hJi/q5URXxS ApoqnH9/VfGkwlgXtn2aO6fkOHtcNFKB0g9nK+pvv97kYeFKuKecXrbjmfthsjly7qoa 2vC31gwqXrixClmjggeCZ9PFpKxoCuq7DQ0YFTxQEMGHuqIVsOmJcLbPQSiZhKEikOP/ 2vS471HsxdQCRyn5K2e+efjX/VTB4IM4VpKgW64ROuWkd9ZBBMj2iHT1+lcBSjHEALi1 niGjtcLEd7s9LMn3f+WhIefB2FtYGY6x829GVbUbp1dbTcv7/+7hJ/jE4BwMqh17imml w4tA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=I7NyOv8cByvFqxd7Edjr8FxcXnimFI7q+H+EW32C/RQ=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=VJ6vdr852JNpSNYSkrT0mPHWo1EmDIxyuNXVo6++QazKNo/DfXvtRst/zXTxPu6weI MWA4I+3KqOZjs+LHlVsIY5L0p2vVxTfpOGG5NNCLeL4DUeZZKhng4jfYIKV7Act1JeZm a2S9YMdy/JYxgVktfb9MgOzpiQuhr0mRWFXtk9qQD4Z7Uy+tHYrbnblab/hSum+9ITj8 mzs1CyFLOi2rIuLFnLu+X5y0dh+uuXwqWNyvkgkowgyEL4xmnAqPiZphCleQPIItKaXM kBOklmyXAUabODhawnUxNDgn8bY1fwkxb4GYoHx5YGOH9Pxgxnl0N8X1X9KdwbfD6cCO 5rEQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b="KE/PoK5t"; 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 a640c23a62f3a-a906109a602si91714366b.61.2024.09.14.04.19.25; Sat, 14 Sep 2024 04:19:25 -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=@khirnov.net header.s=mail header.b="KE/PoK5t"; 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 6799768DDC8; Sat, 14 Sep 2024 14:11:02 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D7A3A68DA8C for ; Sat, 14 Sep 2024 14:10:53 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=KE/PoK5t; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id AF62F4E12 for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id lgSxn1UG3oYf for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=TDn//xYq4XiqHFsOxCRCMF4vqrr23J9oCwgdus3PAbQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=KE/PoK5tMYFG1mIMwV8sEDrwlC7eAjmMMOeDtRkXx240dfwX3TOVtWaN/k74rXMgW xNPAvBMncH8KKiP3DXCA+K8bgh2lBfbqcnVk6+KWF9Z45XgiRzF30x4fyn2qdap84a G6XuA2XSDyEB1Jd0rCUI2W2/VOaVS/qMtBqIXOXBFEc14DBYWgllfq9Vx4CG2kbuhD rbnx+6vFV/etTCxqDO7sQ5VJgbNB0CEvijNTofPmoQ/ZVppMjF/iA5QwJj8yP9v7yA 8FgqzSmBYfEebnGSuIZc2HJ9hJ1U4akAmjDBEltuDk3H0W2+iKAFEAHwhBSexZqtPB 6lpP2p1PVA+mg== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 8B3774E1A for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 94C553A1E95 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:41 +0200 Message-ID: <20240914111036.17164-17-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 16/23] avcodec/hevc/refs: export Stereo 3D side data 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: /ELTeXwUnI5a From: James Almer Use the 3D Reference Displays Info SEI message to link a view_id with an eye. Signed-off-by: James Almer --- libavcodec/hevc/hevcdec.c | 1 + libavcodec/hevc/refs.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index 692f19e97e..b784b10bcf 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -3968,6 +3968,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->sei.common.mastering_display = s0->sei.common.mastering_display; s->sei.common.content_light = s0->sei.common.content_light; s->sei.common.aom_film_grain = s0->sei.common.aom_film_grain; + s->sei.tdrdi = s0->sei.tdrdi; return 0; } diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index b9b08ca416..ac1b07a308 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -22,6 +22,7 @@ */ #include "libavutil/mem.h" +#include "libavutil/stereo3d.h" #include "container_fifo.h" #include "decode.h" @@ -94,6 +95,7 @@ static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) // add view ID side data if it's nontrivial if (vps->nb_layers > 1 || view_id) { + HEVCSEITDRDI *tdrdi = &s->sei.tdrdi; AVFrameSideData *sd = av_frame_side_data_new(&frame->f->side_data, &frame->f->nb_side_data, AV_FRAME_DATA_VIEW_ID, @@ -101,6 +103,23 @@ static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) if (!sd) goto fail; *(int*)sd->data = view_id; + + if (tdrdi->num_ref_displays) { + AVStereo3D *stereo_3d; + + av_frame_remove_side_data(frame->f, AV_FRAME_DATA_STEREO3D); + stereo_3d = av_stereo3d_create_side_data(frame->f); + if (!stereo_3d) + goto fail; + + stereo_3d->type = AV_STEREO3D_FRAMESEQUENCE; + if (tdrdi->left_view_id[0] == view_id) + stereo_3d->view = AV_STEREO3D_VIEW_LEFT; + else if (tdrdi->right_view_id[0] == view_id) + stereo_3d->view = AV_STEREO3D_VIEW_RIGHT; + else + stereo_3d->view = AV_STEREO3D_VIEW_UNSPEC; + } } if (!(s->layers_active_output & (1 << s->cur_layer))) From patchwork Sat Sep 14 10:45:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51599 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp322937vqy; Sat, 14 Sep 2024 05:09:15 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUy3C/iiXxnR/8GpU3xSRHcLdrgBr9TAbnEbK+7LcmnWl+TRVCxOZ9oEnLwfFEp40Dl2H+bENDzOQ9R9HZbllev@gmail.com X-Google-Smtp-Source: AGHT+IF7oRxiBIoWOAsbXEfOwkaKVKm7P7kjlzVofAjfxHBM7GudxhRdJ47+TSz84JMQZfYa+Z58 X-Received: by 2002:a17:906:c149:b0:a8d:2623:dd16 with SMTP id a640c23a62f3a-a90296133admr426630866b.11.1726315754833; Sat, 14 Sep 2024 05:09:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726315754; cv=none; d=google.com; s=arc-20240605; b=Gn44u8D/I5fN1jjKoJJA0W7NCcfftrGKQ/og8Nr9Ouk914Q2itX0OUV05NGQu/fHIp lYV/vDQXFudm3rSAE3Qf/pdwrHFOIpvoHn4YmxNRDS9uN+u5NEdQOqCr1iN6Vwt48paJ jrDuk6IfTDq1XBech/mOaWUhez9NCHo00YDNJwkCRH4i7PzwIh699kxqbuFufxPEKfwH ZZud7ht9R/3dGPAspZfOa66XxA2XT+RQES6gdS/kPOpiE2eWrzkrcmC/TzXDayNNSxvW lrWoN9nVlTFbrqG3Hw7AiXcOXRkUiIWkcKsUjeOnXJCHJ2992zA1sKV5r4DmtYzgsnjA 8Omg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=+Xh34iKrKiQ1Cv4wh2uh6kn+lITKO9lnswK5qSvCoEY=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=Vr40C6yzj1mD3WVXXgHrgIhRaXL4yAI8H2o2H78g/J4HetnZ2ePN4cDuRj9e3QZgaG iGngAHavkNWxT41PIq89sXY6yxEwUGxutqbmPX5Uv+JAhj6LwwaESp8mYcxDSHDnQp4W 8Ad2wkjS+tHyUiiORuOUsO+D7Cg9FAcOZ96G4zpzH302rTC1jGaPD9Oi4tBpIK39utJm 61XK2O271dydBfTNz4dZTwWjxvIJAqyqg4OpoEOC+jBCouERD9MBHp3QDNZh3+xHfjs3 eu6VCdbZSDiCVg50shLKtk1SPPfh5L62Slg0jsqIiHsCdUsdBuEdxl85n/6VGKkZDVYR gxtQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=daPQ0Zed; 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 a640c23a62f3a-a906137231csi91884566b.961.2024.09.14.05.09.13; Sat, 14 Sep 2024 05:09:14 -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=@khirnov.net header.s=mail header.b=daPQ0Zed; 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 C3DB068DE79; Sat, 14 Sep 2024 14:11:12 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1C4C568DC9E for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=daPQ0Zed; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 6485B4E0C for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id 34FORLpWKcV4 for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=TLPaARIyRXIpXcjGi4L3enqHGpQHRcE7O7FnKRmDcWY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=daPQ0Zed7WwVDyCjzBTVPDe10CQtx7MDd1j/+oxkVC5vLGtrAhaJNbjjI9w6mQSt/ OlwN9Y366eHY5YkkHdf1prYZIiwFPr1AoCth40+WHN5KMIc10i3FYKpID7G3pYbtq6 3OyxcNQsq4gYCv9Czk94z+nfK1I79sXQR4k+cIbKUn0KpL+eyFGUOQwt2q6qiSPk1o aq0hwLXQj3cUXtQnQNBdIhLyVXkfiFUn7NxOjPWqMuX8yW/FqUau/fFuKJCSjALd23 7KNREmtItDp5TPh7Ap4eJOyYqGJGXy23+HlkOQTDjOaISEDLiD9niBMdUH0h4PAQ8y 0BZ/T5RJTnCHA== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 8C87C4E1E for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id A0D323A20DC for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:42 +0200 Message-ID: <20240914111036.17164-18-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 17/23] fftools/cmdutils: tighten condition for media type stream specifiers 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: n8UYniDfEDht Require the character indicating media type to be followed by a non-alphanumeric character (or end of string). Needed by future syntax extensions. --- fftools/cmdutils.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index a9a7ff4194..1573106d8b 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -988,6 +988,12 @@ FILE *get_preset_file(char *filename, size_t filename_size, return f; } +static int cmdutils_isalnum(char c) +{ + return (c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z'); +} void stream_specifier_uninit(StreamSpecifier *ss) { @@ -1024,8 +1030,9 @@ int stream_specifier_parse(StreamSpecifier *ss, const char *spec, // this terminates the specifier break; - } else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || - *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */ + } else if ((*spec == 'v' || *spec == 'a' || *spec == 's' || + *spec == 'd' || *spec == 't' || *spec == 'V') && + !cmdutils_isalnum(*(spec + 1))) { /* opt:[vasdtV] */ if (ss->media_type != AVMEDIA_TYPE_UNKNOWN) { av_log(logctx, AV_LOG_ERROR, "Stream type specified multiple times\n"); ret = AVERROR(EINVAL); From patchwork Sat Sep 14 10:45:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51594 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp311015vqy; Sat, 14 Sep 2024 04:39:16 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUGIOL6jp0eMojVGFVYPYc8nN7WsvOalBHZsi9QcJ8SyuSQ5jefa623I7Kgq40WOJf4l61BscTS4kSd0bxw9iIi@gmail.com X-Google-Smtp-Source: AGHT+IG3ONY/zJKO57MbnbyjDnz0XdSCDdGawTIKU0+F5OASbxiMQG/NAtxS1NyRCykG+nMsFgzw X-Received: by 2002:a05:651c:19aa:b0:2f6:5e3a:a2e9 with SMTP id 38308e7fff4ca-2f787dc73e3mr15703531fa.5.1726313956551; Sat, 14 Sep 2024 04:39:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313956; cv=none; d=google.com; s=arc-20240605; b=OoUutOB48Xn56gnhEiNEabOKeA/E6TS6kysfSZZ2lPA3PutzqtQ73yDY91tJidQVnQ VDiA575Y9tea6VbA5feFWx+rUNSuFKd//M+MBgGotyTFrLVXYZ+A34AMqIZpLln5nBs/ ahGRsFOiwCtls0BOemhhwQKF9cgIFQzXKt5VoIaaCh9aOjbGo/wsgjhINhuzD1FhM38W rIgcLWdtzZ6lefzdAFGSxjNFZR9nws7kZAOyO5eCU2HqsN1YmCskJ5AyChFLioHSpQta OqIxdmCkRVPA2W1ZTzpTiFdhX7plcCLhW8i4oZ7d7PEozUTD/gMFr55FIJwMOyZETM+B F/vA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=pE75Ow2M84b3rbatVCWxfZOQE0jeVHCDHGdl/6/HqEk=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=cekIUmnOjIZQpnnl6jW+gfYxyV7ghgvNlY1FnGHnv3X27is/sBOacCnWWTv/EaFrEq LTgM6GMGDwPX0ORvN1+L+dh2hNlFTzfex1fJhGihHBt2m5a8gD/QXtLGesVSTdMAaRMn t+0oleN//rNgVtISxBaqqnSBhCy+uh8DHJ1RrK1EReMr3qLwLQ+FJcVZxgwjXSqnDIxs 1ckQy4bSQIZAIoYoPaT32IQst09LSCdfzHzF4VGAwiw2zjFLzViOIHGyJRybBFxwHY4E NDNNfnjXgt8kfAVeqASTDZHC+6IzDVYgQ2OD65lqQst4La3KR8nGK3ZQxwGvUWD3C5zn adJA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=nQLNsF3h; 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 2adb3069b0e04-536870afcc6si403759e87.463.2024.09.14.04.39.16; Sat, 14 Sep 2024 04:39:16 -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=@khirnov.net header.s=mail header.b=nQLNsF3h; 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 D748F68DEA7; Sat, 14 Sep 2024 14:11:17 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2FDA768DC94 for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=nQLNsF3h; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id C8FD74E14 for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id Gf7tUYKrPrhk for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=QDdvLK2azQ1+d9lwihSSObZ0BkN+Hrk09llUCJLXiWU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=nQLNsF3hWfje3men7lxnUeqVsAx9rHVwiK0Pdi3jesfqmCyo51F7SNMSW0/uRuqq5 IVwdEthCOAI07f7x6PYN0iUPo30lwrpa35RvsJ5nx62b+ZC0Pt14zdHDfJdHTjOQAA EDdaT7hTgMMRNm44ooFo5wp/whvmS+gV+49tU1tfjbb6CdN0ZPgsal6aA/HQsFILVO HAhwd27c/d9M16p2wVyiqEEMPfnK1ad8QeNd2ZMricIjT/tK1G5jpaUzygM7P4x94m Q3w7l+MGH5rsVbGNA4rOgUcrH2xl3b8snmfBg5nJXl93ieXbamrP8sycOvwR84w7MD WLcBTBAezzogQ== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 8C2D34E1B for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id ACA383A2137 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:43 +0200 Message-ID: <20240914111036.17164-19-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 18/23] fftools/ffmpeg_sched: allow decoders to have multiple outputs 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 47f5oLY4T+Hx Will be useful for multilayer video. --- fftools/ffmpeg_dec.c | 10 ++-- fftools/ffmpeg_demux.c | 2 +- fftools/ffmpeg_filter.c | 4 +- fftools/ffmpeg_mux_init.c | 2 +- fftools/ffmpeg_sched.c | 102 ++++++++++++++++++++++++++++---------- fftools/ffmpeg_sched.h | 21 ++++++-- 6 files changed, 100 insertions(+), 41 deletions(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index c2bcf784b0..54f7223f0f 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -578,7 +578,7 @@ static int process_subtitle(DecoderPriv *dp, AVFrame *frame) if (!subtitle) return 0; - ret = sch_dec_send(dp->sch, dp->sch_idx, frame); + ret = sch_dec_send(dp->sch, dp->sch_idx, 0, frame); if (ret < 0) av_frame_unref(frame); @@ -620,7 +620,7 @@ static int transcode_subtitles(DecoderPriv *dp, const AVPacket *pkt, frame->time_base = pkt->time_base; frame->opaque = (void*)(intptr_t)FRAME_OPAQUE_SUB_HEARTBEAT; - ret = sch_dec_send(dp->sch, dp->sch_idx, frame); + ret = sch_dec_send(dp->sch, dp->sch_idx, 0, frame); return ret == AVERROR_EOF ? AVERROR_EXIT : ret; } else if (pkt && (intptr_t)pkt->opaque == PKT_OPAQUE_FIX_SUB_DURATION) { return fix_sub_duration_heartbeat(dp, av_rescale_q(pkt->pts, pkt->time_base, @@ -773,7 +773,7 @@ static int packet_decode(DecoderPriv *dp, AVPacket *pkt, AVFrame *frame) dp->dec.frames_decoded++; - ret = sch_dec_send(dp->sch, dp->sch_idx, frame); + ret = sch_dec_send(dp->sch, dp->sch_idx, 0, frame); if (ret < 0) { av_frame_unref(frame); return ret == AVERROR_EOF ? AVERROR_EXIT : ret; @@ -951,7 +951,7 @@ static int decoder_thread(void *arg) dp->last_frame_pts + dp->last_frame_duration_est; dt.frame->time_base = dp->last_frame_tb; - ret = sch_dec_send(dp->sch, dp->sch_idx, dt.frame); + ret = sch_dec_send(dp->sch, dp->sch_idx, 0, dt.frame); if (ret < 0 && ret != AVERROR_EOF) { av_log(dp, AV_LOG_FATAL, "Error signalling EOF timestamp: %s\n", av_err2str(ret)); @@ -1355,7 +1355,7 @@ int dec_create(const OptionsContext *o, const char *arg, Scheduler *sch) return ret; enc_idx = ret; - ret = sch_connect(sch, SCH_ENC(enc_idx), SCH_DEC(dp->sch_idx)); + ret = sch_connect(sch, SCH_ENC(enc_idx), SCH_DEC_IN(dp->sch_idx)); if (ret < 0) return ret; diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 039ee0c785..476efff127 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -954,7 +954,7 @@ static int ist_use(InputStream *ist, int decoding_needed) ds->sch_idx_dec = ret; ret = sch_connect(d->sch, SCH_DSTREAM(d->f.index, ds->sch_idx_stream), - SCH_DEC(ds->sch_idx_dec)); + SCH_DEC_IN(ds->sch_idx_dec)); if (ret < 0) return ret; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 8b420e68ab..05f9b287fb 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -686,7 +686,7 @@ static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist) if (dec_idx < 0) return dec_idx; - ret = sch_connect(fgp->sch, SCH_DEC(dec_idx), + ret = sch_connect(fgp->sch, SCH_DEC_OUT(dec_idx, 0), SCH_FILTER_IN(fgp->sch_idx, ifp->index)); if (ret < 0) return ret; @@ -732,7 +732,7 @@ static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder *dec) if (dec_idx < 0) return dec_idx; - ret = sch_connect(fgp->sch, SCH_DEC(dec_idx), + ret = sch_connect(fgp->sch, SCH_DEC_OUT(dec_idx, 0), SCH_FILTER_IN(fgp->sch_idx, ifp->index)); if (ret < 0) return ret; diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 6d9029c9c3..771fb2ef7b 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -1514,7 +1514,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ms->sch_idx_src = sched_idx; if (ost->enc) { - ret = sch_connect(mux->sch, SCH_DEC(sched_idx), + ret = sch_connect(mux->sch, SCH_DEC_OUT(sched_idx, 0), SCH_ENC(ms->sch_idx_enc)); if (ret < 0) goto fail; diff --git a/fftools/ffmpeg_sched.c b/fftools/ffmpeg_sched.c index cff824340b..ef0b6e2897 100644 --- a/fftools/ffmpeg_sched.c +++ b/fftools/ffmpeg_sched.c @@ -71,13 +71,19 @@ typedef struct SchTask { int thread_running; } SchTask; +typedef struct SchDecOutput { + SchedulerNode *dst; + uint8_t *dst_finished; + unsigned nb_dst; +} SchDecOutput; + typedef struct SchDec { const AVClass *class; SchedulerNode src; - SchedulerNode *dst; - uint8_t *dst_finished; - unsigned nb_dst; + + SchDecOutput *outputs; + unsigned nb_outputs; SchTask task; // Queue for receiving input packets, one stream. @@ -513,8 +519,14 @@ void sch_free(Scheduler **psch) av_thread_message_queue_free(&dec->queue_end_ts); - av_freep(&dec->dst); - av_freep(&dec->dst_finished); + for (unsigned j = 0; j < dec->nb_outputs; j++) { + SchDecOutput *o = &dec->outputs[j]; + + av_freep(&o->dst); + av_freep(&o->dst_finished); + } + + av_freep(&dec->outputs); av_frame_free(&dec->send_frame); } @@ -712,14 +724,28 @@ int sch_add_demux_stream(Scheduler *sch, unsigned demux_idx) return ret < 0 ? ret : d->nb_streams - 1; } +int sch_add_dec_output(Scheduler *sch, unsigned dec_idx) +{ + SchDec *dec; + int ret; + + av_assert0(dec_idx < sch->nb_dec); + dec = &sch->dec[dec_idx]; + + ret = GROW_ARRAY(dec->outputs, dec->nb_outputs); + if (ret < 0) + return ret; + + return dec->nb_outputs - 1; +} + static const AVClass sch_dec_class = { .class_name = "SchDec", .version = LIBAVUTIL_VERSION_INT, .parent_log_context_offset = offsetof(SchDec, task.func_arg), }; -int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx, - int send_end_ts) +int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx, int send_end_ts) { const unsigned idx = sch->nb_dec; @@ -739,6 +765,10 @@ int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx, if (!dec->send_frame) return AVERROR(ENOMEM); + ret = sch_add_dec_output(sch, idx); + if (ret < 0) + return ret; + ret = queue_alloc(&dec->queue, 1, 0, QUEUE_PACKETS); if (ret < 0) return ret; @@ -943,15 +973,19 @@ int sch_connect(Scheduler *sch, SchedulerNode src, SchedulerNode dst) } case SCH_NODE_TYPE_DEC: { SchDec *dec; + SchDecOutput *o; av_assert0(src.idx < sch->nb_dec); dec = &sch->dec[src.idx]; - ret = GROW_ARRAY(dec->dst, dec->nb_dst); + av_assert0(src.idx_stream < dec->nb_outputs); + o = &dec->outputs[src.idx_stream]; + + ret = GROW_ARRAY(o->dst, o->nb_dst); if (ret < 0) return ret; - dec->dst[dec->nb_dst - 1] = dst; + o->dst[o->nb_dst - 1] = dst; // decoded frames go to filters or encoding switch (dst.type) { @@ -1417,15 +1451,20 @@ static int start_prepare(Scheduler *sch) "Decoder not connected to a source\n"); return AVERROR(EINVAL); } - if (!dec->nb_dst) { - av_log(dec, AV_LOG_ERROR, - "Decoder not connected to any sink\n"); - return AVERROR(EINVAL); - } - dec->dst_finished = av_calloc(dec->nb_dst, sizeof(*dec->dst_finished)); - if (!dec->dst_finished) - return AVERROR(ENOMEM); + for (unsigned j = 0; j < dec->nb_outputs; j++) { + SchDecOutput *o = &dec->outputs[j]; + + if (!o->nb_dst) { + av_log(dec, AV_LOG_ERROR, + "Decoder output %u not connected to any sink\n", j); + return AVERROR(EINVAL); + } + + o->dst_finished = av_calloc(o->nb_dst, sizeof(*o->dst_finished)); + if (!o->dst_finished) + return AVERROR(ENOMEM); + } } for (unsigned i = 0; i < sch->nb_enc; i++) { @@ -2171,21 +2210,26 @@ finish: return AVERROR_EOF; } -int sch_dec_send(Scheduler *sch, unsigned dec_idx, AVFrame *frame) +int sch_dec_send(Scheduler *sch, unsigned dec_idx, + unsigned out_idx, AVFrame *frame) { SchDec *dec; + SchDecOutput *o; int ret; unsigned nb_done = 0; av_assert0(dec_idx < sch->nb_dec); dec = &sch->dec[dec_idx]; - for (unsigned i = 0; i < dec->nb_dst; i++) { - uint8_t *finished = &dec->dst_finished[i]; + av_assert0(out_idx < dec->nb_outputs); + o = &dec->outputs[out_idx]; + + for (unsigned i = 0; i < o->nb_dst; i++) { + uint8_t *finished = &o->dst_finished[i]; AVFrame *to_send = frame; // sending a frame consumes it, so make a temporary reference if needed - if (i < dec->nb_dst - 1) { + if (i < o->nb_dst - 1) { to_send = dec->send_frame; // frame may sometimes contain props only, @@ -2196,7 +2240,7 @@ int sch_dec_send(Scheduler *sch, unsigned dec_idx, AVFrame *frame) return ret; } - ret = dec_send_to_dst(sch, dec->dst[i], finished, to_send); + ret = dec_send_to_dst(sch, o->dst[i], finished, to_send); if (ret < 0) { av_frame_unref(to_send); if (ret == AVERROR_EOF) { @@ -2207,7 +2251,7 @@ int sch_dec_send(Scheduler *sch, unsigned dec_idx, AVFrame *frame) } } - return (nb_done == dec->nb_dst) ? AVERROR_EOF : 0; + return (nb_done == o->nb_dst) ? AVERROR_EOF : 0; } static int dec_done(Scheduler *sch, unsigned dec_idx) @@ -2222,10 +2266,14 @@ static int dec_done(Scheduler *sch, unsigned dec_idx) if (dec->queue_end_ts) av_thread_message_queue_set_err_recv(dec->queue_end_ts, AVERROR_EOF); - for (unsigned i = 0; i < dec->nb_dst; i++) { - int err = dec_send_to_dst(sch, dec->dst[i], &dec->dst_finished[i], NULL); - if (err < 0 && err != AVERROR_EOF) - ret = err_merge(ret, err); + for (unsigned i = 0; i < dec->nb_outputs; i++) { + SchDecOutput *o = &dec->outputs[i]; + + for (unsigned j = 0; j < o->nb_dst; j++) { + int err = dec_send_to_dst(sch, o->dst[j], &o->dst_finished[j], NULL); + if (err < 0 && err != AVERROR_EOF) + ret = err_merge(ret, err); + } } return ret; diff --git a/fftools/ffmpeg_sched.h b/fftools/ffmpeg_sched.h index 7cd839016c..3062c4a6ec 100644 --- a/fftools/ffmpeg_sched.h +++ b/fftools/ffmpeg_sched.h @@ -114,9 +114,12 @@ typedef int (*SchThreadFunc)(void *arg); #define SCH_MSTREAM(file, stream) \ (SchedulerNode){ .type = SCH_NODE_TYPE_MUX, \ .idx = file, .idx_stream = stream } -#define SCH_DEC(decoder) \ +#define SCH_DEC_IN(decoder) \ (SchedulerNode){ .type = SCH_NODE_TYPE_DEC, \ - .idx = decoder } + .idx = decoder } +#define SCH_DEC_OUT(decoder, out_idx) \ + (SchedulerNode){ .type = SCH_NODE_TYPE_DEC, \ + .idx = decoder, .idx_stream = out_idx } #define SCH_ENC(encoder) \ (SchedulerNode){ .type = SCH_NODE_TYPE_ENC, \ .idx = encoder } @@ -178,8 +181,15 @@ int sch_add_demux_stream(Scheduler *sch, unsigned demux_idx); * @retval ">=0" Index of the newly-created decoder. * @retval "<0" Error code. */ -int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx, - int send_end_ts); +int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx, int send_end_ts); + +/** + * Add another output to decoder (e.g. for multiview video). + * + * @retval ">=0" Index of the newly-added decoder output. + * @retval "<0" Error code. + */ +int sch_add_dec_output(Scheduler *sch, unsigned dec_idx); /** * Add a filtergraph to the scheduler. @@ -379,7 +389,8 @@ int sch_dec_receive(Scheduler *sch, unsigned dec_idx, struct AVPacket *pkt); * @retval AVERROR_EOF all consumers are done, should terminate decoding * @retval "another negative error code" other failure */ -int sch_dec_send(Scheduler *sch, unsigned dec_idx, struct AVFrame *frame); +int sch_dec_send(Scheduler *sch, unsigned dec_idx, + unsigned out_idx, struct AVFrame *frame); /** * Called by filtergraph tasks to obtain frames for filtering. Will wait for a From patchwork Sat Sep 14 10:45:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51592 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp307045vqy; Sat, 14 Sep 2024 04:29:19 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVkc4cCWuV5FHMleX6hD3IgY4lB4Cyb0qF8kgjEkmvWX3x68m1ZsxyOteStLR/RJwo7ja7WwATepIfKOARIRzgh@gmail.com X-Google-Smtp-Source: AGHT+IGI373V2e7Kc9vTms6xbvoB3foMto7NPmlKT5hdMgDH44QpdyPoMjYTOUnPMjy4iBEdd3X2 X-Received: by 2002:a05:6402:e9e:b0:5c4:2508:aa1b with SMTP id 4fb4d7f45d1cf-5c42508ac84mr1064667a12.6.1726313359280; Sat, 14 Sep 2024 04:29:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313359; cv=none; d=google.com; s=arc-20240605; b=cQaP0+LiY+YoFsSfvoXActdnszhsIkmL8TgZnE9KWnyWGv/zfbRr08Qjqtnj9j3P/I 2kuQ9hFmg6tCbDSuc0yXCZU2317NGH6o3M2mhnJzy5FGY3tTIS+PTNVsVw8iW7+vBsK3 xQB8iG3Du0ozkv5lsmLYMYJ2svKU5imiWvVU9dHp+2T4itNLpI0DbI/+4ZB5/vK46bFm nccEwZDhs8tP6EKIRZs6dsLO7T3ywJd4DLCpNMpmVdgSwjI/sklS7bwlTKjs1CLhbRnx jgOcLo2vZjBotaX4RtBHVDsVRm7c+9nXUAlF8D2M4UETmKEEfyO5KgGFMWrBAfl44jxU W1zw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=OFr3wGQrKvxgmd0cAlLYl6eaHsUMaZpCNc+BxyFK/Hg=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=HudJRE73CPGpeHP/c2FbgkFFzg3ERqdTLAJsPEJ/7kMgYh89oVumnoKYUzwUsK0IVu B3m7JEW/7uqoTyBtceQffqsonP9T9qYf8Ro+Tha7OikYhpDh9SwehYLWGQB+rhhDNLLP /qkeg2/SITAN12bCQFeEyMwJdLNJ2knA8wQPqOK4qvsxrLjHeRuB4yWHs3Bns9KYcloK Ys32oBrLTrlvIHGkcU74PkdokBDntGo3aEyuUHxWAujbkgXBMWqyD0YPIZCro1vzdbuR qaihLTJ3tTP4ZeAg2dQOFGgdjvhusbR9Eyt9hf2fskR0nCEIJz2PfMEZK1Vvno5ZsSqZ elxA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=MdhmTD1h; 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 4fb4d7f45d1cf-5c42bcb9223si889576a12.671.2024.09.14.04.29.18; Sat, 14 Sep 2024 04:29:19 -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=@khirnov.net header.s=mail header.b=MdhmTD1h; 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 82B1068DDE3; Sat, 14 Sep 2024 14:11:03 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id DC9D968DBB8 for ; Sat, 14 Sep 2024 14:10:53 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=MdhmTD1h; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 24F2D4E1A for ; Sat, 14 Sep 2024 13:10:52 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id OAif9ufBWTXo for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=sTCSLUA7BhV0jqGv5dySskvJDq6fuboWtjciq1hs6+8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=MdhmTD1h79qZF8w7vJ8ixV0r7r0R9p9jpKm9Mbz1bAwJHvXe9UY7ZQA8Ezz1EtU7S Gr0Dgy8+bgEdQiuN+1lJG6lLbr9Q/0i51bZhFb3NTOorO7TZIsWHhAUdd2n/nUc6b+ ezuQ8Ft+sHQuhF040OKH5U/maj6YLD6qjHbUk++jrOpjVcQ5rrlQP6fF8MADLFythv rIvctDwRYqcugfA5QG6G2r3O6Uemf2OEiNDFJSXQadObD0IMsVAzjE36Yy7SejwzU8 OaeFgi8yaQGpnyEq3UW9oC8mtQ+anCtaVJ+FDY/Vf6lA/ZquC+ic7sgw4mWWVQtU81 CN733LoCxaB2Q== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 8CBEC4E20 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id B8CA13A2191 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:44 +0200 Message-ID: <20240914111036.17164-20-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 19/23] fftools/ffmpeg: add support for multiview video 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: qMUgYg3h0j98 This extends the syntax for specifying input streams in -map and complex filtergraph labels, to allow selecting a view by view ID, index, or position. The corresponding decoder is then set up to decode the appropriate view and send frames for that view to the correct filtergraph input(s). --- doc/ffmpeg.texi | 30 ++- fftools/cmdutils.c | 2 +- fftools/cmdutils.h | 2 + fftools/ffmpeg.h | 45 ++++- fftools/ffmpeg_dec.c | 387 +++++++++++++++++++++++++++++++++++++- fftools/ffmpeg_demux.c | 24 ++- fftools/ffmpeg_filter.c | 71 ++++--- fftools/ffmpeg_mux_init.c | 34 ++-- fftools/ffmpeg_opt.c | 70 ++++++- 9 files changed, 610 insertions(+), 55 deletions(-) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 842e92ad1a..34007f7ea2 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1799,7 +1799,7 @@ Set the size of the canvas used to render subtitles. @section Advanced options @table @option -@item -map [-]@var{input_file_id}[:@var{stream_specifier}][?] | @var{[linklabel]} (@emph{output}) +@item -map [-]@var{input_file_id}[:@var{stream_specifier}][:@var{view_specifier}][?] | @var{[linklabel]} (@emph{output}) Create one or more streams in the output file. This option has two forms for specifying the data source(s): the first selects one or more streams from some @@ -1814,6 +1814,26 @@ only those streams that match the specifier are used (see the A @code{-} character before the stream identifier creates a "negative" mapping. It disables matching streams from already created mappings. +An optional @var{view_specifier} may be given after the stream specifier, which +for multiview video specifies the view to be used. The view specifier may have +one of the following formats: +@table @option +@item view:@var{view_id} +select a view by its ID; @var{view_id} may be set to 'all' to use all the views +interleaved into one stream; + +@item vidx:@var{view_idx} +select a view by its index; i.e. 0 is the base view, 1 is the first non-base +view, etc. + +@item vpos:@var{position} +select a view by its display position; @var{position} may be @code{left} or +@code{right} +@end table +The default for transcoding is to only use the base view, i.e. the equivalent of +@code{vidx:0}. For streamcopy, view specifiers are not supported and all views +are always copied. + A trailing @code{?} after the stream index will allow the map to be optional: if the map matches no streams the map will be ignored instead of failing. Note the map will still fail if an invalid input file index @@ -2206,11 +2226,15 @@ distinguished by the format of the corresponding link label: @item To connect an input stream, use @code{[file_index:stream_specifier]} (i.e. the same syntax as @option{-map}). If @var{stream_specifier} matches multiple -streams, the first one will be used. +streams, the first one will be used. For multiview video, the stream specifier +may be followed by the view specifier, see documentation for the @option{-map} +option for its syntax. @item To connect a loopback decoder use [dec:@var{dec_idx}], where @var{dec_idx} is -the index of the loopback decoder to be connected to given input. +the index of the loopback decoder to be connected to given input. For multiview +video, the decoder index may be followed by the view specifier, see +documentation for the @option{-map} option for its syntax. @item To connect an output from another complex filtergraph, use its link label. E.g diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index 1573106d8b..76e5721cb1 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -988,7 +988,7 @@ FILE *get_preset_file(char *filename, size_t filename_size, return f; } -static int cmdutils_isalnum(char c) +int cmdutils_isalnum(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h index 9441d5726b..e7c8c9f86b 100644 --- a/fftools/cmdutils.h +++ b/fftools/cmdutils.h @@ -541,4 +541,6 @@ void remove_avoptions(AVDictionary **a, AVDictionary *b); /* Check if any keys exist in dictionary m */ int check_avoptions(AVDictionary *m); +int cmdutils_isalnum(char c); + #endif /* FFTOOLS_CMDUTILS_H */ diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index f4a10b2a66..733d551fa4 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -112,12 +112,32 @@ typedef struct HWDevice { AVBufferRef *device_ref; } HWDevice; +enum ViewSpecifierType { + // no specifier given + VIEW_SPECIFIER_TYPE_NONE = 0, + // val is view index + VIEW_SPECIFIER_TYPE_IDX, + // val is view ID + VIEW_SPECIFIER_TYPE_ID, + // specify view by its position, val is AV_STEREO3D_VIEW_LEFT/RIGHT + VIEW_SPECIFIER_TYPE_POS, + // use all views, val is ignored + VIEW_SPECIFIER_TYPE_ALL, +}; + +typedef struct ViewSpecifier { + enum ViewSpecifierType type; + unsigned val; +} ViewSpecifier; + /* select an input stream for an output stream */ typedef struct StreamMap { int disabled; /* 1 is this mapping is disabled by a negative map */ int file_index; int stream_index; char *linklabel; /* name of an output link, for mapping lavfi outputs */ + + ViewSpecifier vs; } StreamMap; typedef struct OptionsContext { @@ -318,6 +338,10 @@ typedef struct OutputFilterOptions { const AVRational *frame_rates; const enum AVColorSpace *color_spaces; const enum AVColorRange *color_ranges; + + // for simple filtergraphs only, view specifier passed + // along to the decoder + const ViewSpecifier *vs; } OutputFilterOptions; typedef struct InputFilter { @@ -817,7 +841,21 @@ void dec_free(Decoder **pdec); * * @param opts filtergraph input options, to be filled by this function */ -int dec_filter_add(Decoder *dec, InputFilter *ifilter, InputFilterOptions *opts); +int dec_filter_add(Decoder *dec, InputFilter *ifilter, InputFilterOptions *opts, + const ViewSpecifier *vs, SchedulerNode *src); + +/* + * For multiview video, request output of the view(s) determined by vs. + * May be called multiple times. + * + * If this function is never called, only the base view is output. If it is + * called at least once, only the views requested are output. + * + * @param src scheduler node from which the frames corresponding vs + * will originate + */ +int dec_request_view(Decoder *dec, const ViewSpecifier *vs, + SchedulerNode *src); int enc_alloc(Encoder **penc, const AVCodec *codec, Scheduler *sch, unsigned sch_idx); @@ -847,7 +885,8 @@ void ifile_close(InputFile **f); int ist_output_add(InputStream *ist, OutputStream *ost); int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple, - InputFilterOptions *opts); + const ViewSpecifier *vs, InputFilterOptions *opts, + SchedulerNode *src); /** * Find an unused input stream of given type. @@ -875,6 +914,8 @@ void opt_match_per_stream_int64(void *logctx, const SpecifierOptList *sol, void opt_match_per_stream_dbl(void *logctx, const SpecifierOptList *sol, AVFormatContext *fc, AVStream *st, double *out); +int view_specifier_parse(const char **pspec, ViewSpecifier *vs); + int muxer_thread(void *arg); int encoder_thread(void *arg); diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 54f7223f0f..2723a0312e 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/dict.h" @@ -25,6 +27,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/pixfmt.h" +#include "libavutil/stereo3d.h" #include "libavutil/time.h" #include "libavutil/timestamp.h" @@ -39,6 +42,7 @@ typedef struct DecoderPriv { AVCodecContext *dec_ctx; AVFrame *frame; + AVFrame *frame_tmp_ref; AVPacket *pkt; // override output video sample aspect ratio with this value @@ -77,6 +81,23 @@ typedef struct DecoderPriv { char log_name[32]; char *parent_name; + // user specified decoder multiview options manually + int multiview_user_config; + + struct { + ViewSpecifier vs; + unsigned out_idx; + } *views_requested; + int nb_views_requested; + + /* A map of view ID to decoder outputs. + * MUST NOT be accessed outside of get_format()/get_buffer() */ + struct { + unsigned id; + uintptr_t out_mask; + } *view_map; + int nb_view_map; + struct { AVDictionary *opts; const AVCodec *codec; @@ -106,6 +127,7 @@ void dec_free(Decoder **pdec) avcodec_free_context(&dp->dec_ctx); av_frame_free(&dp->frame); + av_frame_free(&dp->frame_tmp_ref); av_packet_free(&dp->pkt); av_dict_free(&dp->standalone_init.opts); @@ -116,6 +138,9 @@ void dec_free(Decoder **pdec) av_freep(&dp->parent_name); + av_freep(&dp->views_requested); + av_freep(&dp->view_map); + av_freep(pdec); } @@ -357,7 +382,8 @@ fail: return err; } -static int video_frame_process(DecoderPriv *dp, AVFrame *frame) +static int video_frame_process(DecoderPriv *dp, AVFrame *frame, + unsigned *outputs_mask) { #if FFMPEG_OPT_TOP if (dp->flags & DECODER_FLAG_TOP_FIELD_FIRST) { @@ -419,6 +445,9 @@ static int video_frame_process(DecoderPriv *dp, AVFrame *frame) } } + if (frame->opaque) + *outputs_mask = (uintptr_t)frame->opaque; + return 0; } @@ -715,6 +744,7 @@ static int packet_decode(DecoderPriv *dp, AVPacket *pkt, AVFrame *frame) while (1) { FrameData *fd; + unsigned outputs_mask = 1; av_frame_unref(frame); @@ -763,7 +793,7 @@ static int packet_decode(DecoderPriv *dp, AVPacket *pkt, AVFrame *frame) audio_ts_process(dp, frame); } else { - ret = video_frame_process(dp, frame); + ret = video_frame_process(dp, frame, &outputs_mask); if (ret < 0) { av_log(dp, AV_LOG_FATAL, "Error while processing the decoded data\n"); @@ -773,10 +803,28 @@ static int packet_decode(DecoderPriv *dp, AVPacket *pkt, AVFrame *frame) dp->dec.frames_decoded++; - ret = sch_dec_send(dp->sch, dp->sch_idx, 0, frame); - if (ret < 0) { - av_frame_unref(frame); - return ret == AVERROR_EOF ? AVERROR_EXIT : ret; + for (int i = 0; i < stdc_count_ones(outputs_mask); i++) { + AVFrame *to_send = frame; + int pos; + + av_assert0(outputs_mask); + pos = stdc_trailing_zeros(outputs_mask); + outputs_mask &= ~(1U << pos); + + // this is not the last output and sch_dec_send() consumes the frame + // given to it, so make a temporary reference + if (outputs_mask) { + to_send = dp->frame_tmp_ref; + ret = av_frame_ref(to_send, frame); + if (ret < 0) + return ret; + } + + ret = sch_dec_send(dp->sch, dp->sch_idx, pos, to_send); + if (ret < 0) { + av_frame_unref(to_send); + return ret == AVERROR_EOF ? AVERROR_EXIT : ret; + } } } } @@ -975,10 +1023,307 @@ finish: return ret; } +int dec_request_view(Decoder *d, const ViewSpecifier *vs, + SchedulerNode *src) +{ + DecoderPriv *dp = dp_from_dec(d); + unsigned out_idx = 0; + int ret; + + if (dp->multiview_user_config) { + if (!vs || vs->type == VIEW_SPECIFIER_TYPE_NONE) { + *src = SCH_DEC_OUT(dp->sch_idx, 0); + return 0; + } + + av_log(dp, AV_LOG_ERROR, + "Manually selecting views with -view_ids cannot be combined " + "with view selection via stream specifiers. It is strongly " + "recommended you always use stream specifiers only.\n"); + return AVERROR(EINVAL); + } + + // when multiview_user_config is not set, NONE specifier is treated + // as requesting the base view + vs = (vs && vs->type != VIEW_SPECIFIER_TYPE_NONE) ? vs : + &(ViewSpecifier){ .type = VIEW_SPECIFIER_TYPE_IDX, .val = 0 }; + + // check if the specifier matches an already-existing one + for (int i = 0; i < dp->nb_views_requested; i++) { + const ViewSpecifier *vs1 = &dp->views_requested[i].vs; + + if (vs->type == vs1->type && + (vs->type == VIEW_SPECIFIER_TYPE_ALL || vs->val == vs1->val)) { + *src = SCH_DEC_OUT(dp->sch_idx, dp->views_requested[i].out_idx); + return 0; + } + } + + // we use a bitmask to map view IDs to decoder outputs, which + // limits the number of outputs allowed + if (dp->nb_views_requested >= sizeof(dp->view_map[0].out_mask) * 8) { + av_log(dp, AV_LOG_ERROR, "Too many view specifiers\n"); + return AVERROR(ENOSYS); + } + + ret = GROW_ARRAY(dp->views_requested, dp->nb_views_requested); + if (ret < 0) + return ret; + + if (dp->nb_views_requested > 1) { + ret = sch_add_dec_output(dp->sch, dp->sch_idx); + if (ret < 0) + return ret; + out_idx = ret; + } + + dp->views_requested[dp->nb_views_requested - 1].out_idx = out_idx; + dp->views_requested[dp->nb_views_requested - 1].vs = *vs; + + *src = SCH_DEC_OUT(dp->sch_idx, + dp->views_requested[dp->nb_views_requested - 1].out_idx); + + return 0; +} + +static int multiview_setup(DecoderPriv *dp, AVCodecContext *dec_ctx) +{ + unsigned views_wanted = 0; + + unsigned nb_view_ids_av, nb_view_ids; + unsigned *view_ids_av = NULL, *view_pos_av = NULL; + int *view_ids = NULL; + int ret; + + // no views/only base view were requested - do nothing + if (!dp->nb_views_requested || + (dp->nb_views_requested == 1 && + dp->views_requested[0].vs.type == VIEW_SPECIFIER_TYPE_IDX && + dp->views_requested[0].vs.val == 0)) + return 0; + + av_freep(&dp->view_map); + dp->nb_view_map = 0; + + // retrieve views available in current CVS + ret = av_opt_get_array_size(dec_ctx, "view_ids_available", + AV_OPT_SEARCH_CHILDREN, &nb_view_ids_av); + if (ret < 0) { + av_log(dp, AV_LOG_ERROR, + "Multiview decoding requested, but decoder '%s' does not " + "support it\n", dec_ctx->codec->name); + return AVERROR(ENOSYS); + } + + if (nb_view_ids_av) { + unsigned nb_view_pos_av; + + if (nb_view_ids_av >= sizeof(views_wanted) * 8) { + av_log(dp, AV_LOG_ERROR, "Too many views in video: %u\n", nb_view_ids_av); + ret = AVERROR(ENOSYS); + goto fail; + } + + view_ids_av = av_calloc(nb_view_ids_av, sizeof(*view_ids_av)); + if (!view_ids_av) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = av_opt_get_array(dec_ctx, "view_ids_available", + AV_OPT_SEARCH_CHILDREN, 0, nb_view_ids_av, + AV_OPT_TYPE_UINT, view_ids_av); + if (ret < 0) + goto fail; + + ret = av_opt_get_array_size(dec_ctx, "view_pos_available", + AV_OPT_SEARCH_CHILDREN, &nb_view_pos_av); + if (ret >= 0 && nb_view_pos_av == nb_view_ids_av) { + view_pos_av = av_calloc(nb_view_ids_av, sizeof(*view_pos_av)); + if (!view_pos_av) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = av_opt_get_array(dec_ctx, "view_pos_available", + AV_OPT_SEARCH_CHILDREN, 0, nb_view_ids_av, + AV_OPT_TYPE_UINT, view_pos_av); + if (ret < 0) + goto fail; + } + } else { + // assume there is a single view with ID=0 + nb_view_ids_av = 1; + view_ids_av = av_calloc(nb_view_ids_av, sizeof(*view_ids_av)); + view_pos_av = av_calloc(nb_view_ids_av, sizeof(*view_pos_av)); + if (!view_ids_av || !view_pos_av) { + ret = AVERROR(ENOMEM); + goto fail; + } + view_pos_av[0] = AV_STEREO3D_VIEW_UNSPEC; + } + + dp->view_map = av_calloc(nb_view_ids_av, sizeof(*dp->view_map)); + if (!dp->view_map) { + ret = AVERROR(ENOMEM); + goto fail; + } + dp->nb_view_map = nb_view_ids_av; + + for (int i = 0; i < dp->nb_view_map; i++) + dp->view_map[i].id = view_ids_av[i]; + + // figure out which views should go to which output + for (int i = 0; i < dp->nb_views_requested; i++) { + const ViewSpecifier *vs = &dp->views_requested[i].vs; + + switch (vs->type) { + case VIEW_SPECIFIER_TYPE_IDX: + if (vs->val >= nb_view_ids_av) { + av_log(dp, exit_on_error ? AV_LOG_ERROR : AV_LOG_WARNING, + "View with index %u requested, but only %u views available " + "in current video sequence (more views may or may not be " + "available in later sequences).\n", + vs->val, nb_view_ids_av); + if (exit_on_error) { + ret = AVERROR(EINVAL); + goto fail; + } + + continue; + } + views_wanted |= 1U << vs->val; + dp->view_map[vs->val].out_mask |= 1ULL << i; + + break; + case VIEW_SPECIFIER_TYPE_ID: { + int view_idx = -1; + + for (unsigned j = 0; j < nb_view_ids_av; j++) { + if (view_ids_av[j] == vs->val) { + view_idx = j; + break; + } + } + if (view_idx < 0) { + av_log(dp, exit_on_error ? AV_LOG_ERROR : AV_LOG_WARNING, + "View with ID %u requested, but is not available " + "in the video sequence\n", vs->val); + if (exit_on_error) { + ret = AVERROR(EINVAL); + goto fail; + } + + continue; + } + views_wanted |= 1U << view_idx; + dp->view_map[view_idx].out_mask |= 1ULL << i; + + break; + } + case VIEW_SPECIFIER_TYPE_POS: { + int view_idx = -1; + + for (unsigned j = 0; view_pos_av && j < nb_view_ids_av; j++) { + if (view_pos_av[j] == vs->val) { + view_idx = j; + break; + } + } + if (view_idx < 0) { + av_log(dp, exit_on_error ? AV_LOG_ERROR : AV_LOG_WARNING, + "View position '%s' requested, but is not available " + "in the video sequence\n", av_stereo3d_view_name(vs->val)); + if (exit_on_error) { + ret = AVERROR(EINVAL); + goto fail; + } + + continue; + } + views_wanted |= 1U << view_idx; + dp->view_map[view_idx].out_mask |= 1ULL << i; + + break; + } + case VIEW_SPECIFIER_TYPE_ALL: + views_wanted |= (1U << nb_view_ids_av) - 1; + + for (int j = 0; j < dp->nb_view_map; j++) + dp->view_map[j].out_mask |= 1ULL << i; + + break; + } + } + if (!views_wanted) { + av_log(dp, AV_LOG_ERROR, "No views were selected for decoding\n"); + ret = AVERROR(EINVAL); + goto fail; + } + + // signal to decoder which views we want + nb_view_ids = stdc_count_ones(views_wanted); + view_ids = av_malloc_array(nb_view_ids, sizeof(*view_ids)); + if (!view_ids) { + ret = AVERROR(ENOMEM); + goto fail; + } + + for (unsigned i = 0; i < nb_view_ids; i++) { + int pos; + + av_assert0(views_wanted); + pos = stdc_trailing_zeros(views_wanted); + views_wanted &= ~(1U << pos); + + view_ids[i] = view_ids_av[pos]; + } + + // unset view_ids in case we set it earlier + av_opt_set(dec_ctx, "view_ids", NULL, AV_OPT_SEARCH_CHILDREN); + + ret = av_opt_set_array(dec_ctx, "view_ids", AV_OPT_SEARCH_CHILDREN, + 0, nb_view_ids, AV_OPT_TYPE_INT, view_ids); + if (ret < 0) + goto fail; + + if (!dp->frame_tmp_ref) { + dp->frame_tmp_ref = av_frame_alloc(); + if (!dp->frame_tmp_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + +fail: + av_freep(&view_ids_av); + av_freep(&view_pos_av); + av_freep(&view_ids); + + return ret; +} + +static void multiview_check_manual(DecoderPriv *dp, const AVDictionary *dec_opts) +{ + if (av_dict_get(dec_opts, "view_ids", NULL, 0)) { + av_log(dp, AV_LOG_WARNING, "Manually selecting views with -view_ids " + "is not recommended, use view specifiers instead\n"); + dp->multiview_user_config = 1; + } +} + static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts) { DecoderPriv *dp = s->opaque; const enum AVPixelFormat *p; + int ret; + + ret = multiview_setup(dp, s); + if (ret < 0) { + av_log(dp, AV_LOG_ERROR, "Error setting up multiview decoding: %s\n", + av_err2str(ret)); + return AV_PIX_FMT_NONE; + } for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p); @@ -1009,6 +1354,26 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat return *p; } +static int get_buffer(AVCodecContext *dec_ctx, AVFrame *frame, int flags) +{ + DecoderPriv *dp = dec_ctx->opaque; + + // for multiview video, store the output mask in frame opaque + if (dp->nb_view_map) { + const AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_VIEW_ID); + int view_id = sd ? *(int*)sd->data : 0; + + for (int i = 0; i < dp->nb_view_map; i++) { + if (dp->view_map[i].id == view_id) { + frame->opaque = (void*)dp->view_map[i].out_mask; + break; + } + } + } + + return avcodec_default_get_buffer2(dec_ctx, frame, flags); +} + static HWDevice *hw_device_match_by_codec(const AVCodec *codec) { const AVCodecHWConfig *config; @@ -1202,6 +1567,7 @@ static int dec_open(DecoderPriv *dp, AVDictionary **dec_opts, dp->dec_ctx->opaque = dp; dp->dec_ctx->get_format = get_format; + dp->dec_ctx->get_buffer2 = get_buffer; dp->dec_ctx->pkt_timebase = o->time_base; if (!av_dict_get(*dec_opts, "threads", NULL, 0)) @@ -1291,6 +1657,8 @@ int dec_init(Decoder **pdec, Scheduler *sch, if (ret < 0) return ret; + multiview_check_manual(dp, *dec_opts); + ret = dec_open(dp, dec_opts, o, param_out); if (ret < 0) goto fail; @@ -1363,6 +1731,8 @@ int dec_create(const OptionsContext *o, const char *arg, Scheduler *sch) if (ret < 0) return ret; + multiview_check_manual(dp, dp->standalone_init.opts); + if (o->codec_names.nb_opt) { const char *name = o->codec_names.opt[o->codec_names.nb_opt - 1].u.str; dp->standalone_init.codec = avcodec_find_decoder_by_name(name); @@ -1375,7 +1745,8 @@ int dec_create(const OptionsContext *o, const char *arg, Scheduler *sch) return 0; } -int dec_filter_add(Decoder *d, InputFilter *ifilter, InputFilterOptions *opts) +int dec_filter_add(Decoder *d, InputFilter *ifilter, InputFilterOptions *opts, + const ViewSpecifier *vs, SchedulerNode *src) { DecoderPriv *dp = dp_from_dec(d); char name[16]; @@ -1385,5 +1756,5 @@ int dec_filter_add(Decoder *d, InputFilter *ifilter, InputFilterOptions *opts) if (!opts->name) return AVERROR(ENOMEM); - return dp->sch_idx; + return dec_request_view(d, vs, src); } diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 476efff127..7eb8ecdd89 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -874,7 +874,8 @@ void ifile_close(InputFile **pf) av_freep(pf); } -static int ist_use(InputStream *ist, int decoding_needed) +static int ist_use(InputStream *ist, int decoding_needed, + const ViewSpecifier *vs, SchedulerNode *src) { Demuxer *d = demuxer_from_ifile(ist->file); DemuxStream *ds = ds_from_ist(ist); @@ -961,15 +962,26 @@ static int ist_use(InputStream *ist, int decoding_needed) d->have_audio_dec |= is_audio; } + if (decoding_needed && ist->par->codec_type == AVMEDIA_TYPE_VIDEO) { + ret = dec_request_view(ist->decoder, vs, src); + if (ret < 0) + return ret; + } else { + *src = decoding_needed ? + SCH_DEC_OUT(ds->sch_idx_dec, 0) : + SCH_DSTREAM(d->f.index, ds->sch_idx_stream); + } + return 0; } int ist_output_add(InputStream *ist, OutputStream *ost) { DemuxStream *ds = ds_from_ist(ist); + SchedulerNode src; int ret; - ret = ist_use(ist, ost->enc ? DECODING_FOR_OST : 0); + ret = ist_use(ist, ost->enc ? DECODING_FOR_OST : 0, NULL, &src); if (ret < 0) return ret; @@ -983,14 +995,16 @@ int ist_output_add(InputStream *ist, OutputStream *ost) } int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple, - InputFilterOptions *opts) + const ViewSpecifier *vs, InputFilterOptions *opts, + SchedulerNode *src) { Demuxer *d = demuxer_from_ifile(ist->file); DemuxStream *ds = ds_from_ist(ist); int64_t tsoffset = 0; int ret; - ret = ist_use(ist, is_simple ? DECODING_FOR_OST : DECODING_FOR_FILTER); + ret = ist_use(ist, is_simple ? DECODING_FOR_OST : DECODING_FOR_FILTER, + vs, src); if (ret < 0) return ret; @@ -1074,7 +1088,7 @@ int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple, opts->flags |= IFILTER_FLAG_AUTOROTATE * !!(ds->autorotate) | IFILTER_FLAG_REINIT * !!(ds->reinit_filters); - return ds->sch_idx_dec; + return 0; } static int choose_decoder(const OptionsContext *o, void *logctx, diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 05f9b287fb..329f972780 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -659,11 +659,13 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg, enum AVMediaType type) return ofilter; } -static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist) +static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist, + const ViewSpecifier *vs) { InputFilterPriv *ifp = ifp_from_ifilter(ifilter); FilterGraphPriv *fgp = fgp_from_fg(ifilter->graph); - int ret, dec_idx; + SchedulerNode src; + int ret; av_assert0(!ifp->bound); ifp->bound = 1; @@ -681,13 +683,13 @@ static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist) if (!ifp->opts.fallback) return AVERROR(ENOMEM); - dec_idx = ist_filter_add(ist, ifilter, filtergraph_is_simple(ifilter->graph), - &ifp->opts); - if (dec_idx < 0) - return dec_idx; + ret = ist_filter_add(ist, ifilter, filtergraph_is_simple(ifilter->graph), + vs, &ifp->opts, &src); + if (ret < 0) + return ret; - ret = sch_connect(fgp->sch, SCH_DEC_OUT(dec_idx, 0), - SCH_FILTER_IN(fgp->sch_idx, ifp->index)); + ret = sch_connect(fgp->sch, + src, SCH_FILTER_IN(fgp->sch_idx, ifp->index)); if (ret < 0) return ret; @@ -712,10 +714,12 @@ static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist) return 0; } -static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder *dec) +static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder *dec, + const ViewSpecifier *vs) { FilterGraphPriv *fgp = fgp_from_fg(ifp->ifilter.graph); - int ret, dec_idx; + SchedulerNode src; + int ret; av_assert0(!ifp->bound); ifp->bound = 1; @@ -728,12 +732,11 @@ static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder *dec) ifp->type_src = ifp->type; - dec_idx = dec_filter_add(dec, &ifp->ifilter, &ifp->opts); - if (dec_idx < 0) - return dec_idx; + ret = dec_filter_add(dec, &ifp->ifilter, &ifp->opts, vs, &src); + if (ret < 0) + return ret; - ret = sch_connect(fgp->sch, SCH_DEC_OUT(dec_idx, 0), - SCH_FILTER_IN(fgp->sch_idx, ifp->index)); + ret = sch_connect(fgp->sch, src, SCH_FILTER_IN(fgp->sch_idx, ifp->index)); if (ret < 0) return ret; @@ -1216,7 +1219,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost, ost->filter = fg->outputs[0]; - ret = ifilter_bind_ist(fg->inputs[0], ist); + ret = ifilter_bind_ist(fg->inputs[0], ist, opts->vs); if (ret < 0) return ret; @@ -1240,28 +1243,38 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) InputFilterPriv *ifp = ifp_from_ifilter(ifilter); InputStream *ist = NULL; enum AVMediaType type = ifp->type; + ViewSpecifier vs = { .type = VIEW_SPECIFIER_TYPE_NONE }; + const char *spec; + char *p; int i, ret; if (ifp->linklabel && !strncmp(ifp->linklabel, "dec:", 4)) { // bind to a standalone decoder int dec_idx; - dec_idx = strtol(ifp->linklabel + 4, NULL, 0); + dec_idx = strtol(ifp->linklabel + 4, &p, 0); if (dec_idx < 0 || dec_idx >= nb_decoders) { av_log(fg, AV_LOG_ERROR, "Invalid decoder index %d in filtergraph description %s\n", dec_idx, fgp->graph_desc); return AVERROR(EINVAL); } - ret = ifilter_bind_dec(ifp, decoders[dec_idx]); + if (type == AVMEDIA_TYPE_VIDEO) { + spec = *p == ':' ? p + 1 : p; + ret = view_specifier_parse(&spec, &vs); + if (ret < 0) + return ret; + } + + ret = ifilter_bind_dec(ifp, decoders[dec_idx], &vs); if (ret < 0) av_log(fg, AV_LOG_ERROR, "Error binding a decoder to filtergraph input %s\n", ifilter->name); return ret; } else if (ifp->linklabel) { + StreamSpecifier ss; AVFormatContext *s; AVStream *st = NULL; - char *p; int file_idx; // try finding an unbound filtergraph output with this label @@ -1298,17 +1311,33 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) } s = input_files[file_idx]->ctx; + ret = stream_specifier_parse(&ss, *p == ':' ? p + 1 : p, 1, fg); + if (ret < 0) { + av_log(fg, AV_LOG_ERROR, "Invalid stream specifier: %s\n", p); + return ret; + } + + if (type == AVMEDIA_TYPE_VIDEO) { + spec = ss.remainder ? ss.remainder : ""; + ret = view_specifier_parse(&spec, &vs); + if (ret < 0) { + stream_specifier_uninit(&ss); + return ret; + } + } + for (i = 0; i < s->nb_streams; i++) { enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type; if (stream_type != type && !(stream_type == AVMEDIA_TYPE_SUBTITLE && type == AVMEDIA_TYPE_VIDEO /* sub2video hack */)) continue; - if (check_stream_specifier(s, s->streams[i], *p == ':' ? p + 1 : p) == 1) { + if (stream_specifier_match(&ss, s, s->streams[i], fg)) { st = s->streams[i]; break; } } + stream_specifier_uninit(&ss); if (!st) { av_log(fg, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s " "matches no streams.\n", p, fgp->graph_desc); @@ -1333,7 +1362,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter) } av_assert0(ist); - ret = ifilter_bind_ist(ifilter, ist); + ret = ifilter_bind_ist(ifilter, ist, &vs); if (ret < 0) { av_log(fg, AV_LOG_ERROR, "Error binding an input stream to complex filtergraph input %s.\n", diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 771fb2ef7b..aa1fcb6a42 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -920,7 +920,8 @@ static int ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter, const OptionsContext *o, char *filters, AVRational enc_tb, enum VideoSyncMethod vsync_method, - int keep_pix_fmt, int autoscale, int threads_manual) + int keep_pix_fmt, int autoscale, int threads_manual, + const ViewSpecifier *vs) { OutputStream *ost = &ms->ost; AVCodecContext *enc_ctx = ost->enc_ctx; @@ -946,6 +947,7 @@ ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter, .trim_duration_us = mux->of.recording_time, .ts_offset = mux->of.start_time == AV_NOPTS_VALUE ? 0 : mux->of.start_time, + .vs = vs, .flags = OFILTER_FLAG_DISABLE_CONVERT * !!keep_pix_fmt | OFILTER_FLAG_AUTOSCALE * !!autoscale | @@ -1140,7 +1142,7 @@ fail: } static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, - InputStream *ist, OutputFilter *ofilter, + InputStream *ist, OutputFilter *ofilter, const ViewSpecifier *vs, OutputStream **post) { AVFormatContext *oc = mux->fc; @@ -1500,7 +1502,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, if (ost->enc && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { ret = ost_bind_filter(mux, ms, ofilter, o, filters, enc_tb, vsync_method, - keep_pix_fmt, autoscale, threads_manual); + keep_pix_fmt, autoscale, threads_manual, vs); if (ret < 0) goto fail; } else if (ost->ist) { @@ -1602,7 +1604,7 @@ static int map_auto_video(Muxer *mux, const OptionsContext *o) } } if (best_ist) - return ost_add(mux, o, AVMEDIA_TYPE_VIDEO, best_ist, NULL, NULL); + return ost_add(mux, o, AVMEDIA_TYPE_VIDEO, best_ist, NULL, NULL, NULL); return 0; } @@ -1646,7 +1648,7 @@ static int map_auto_audio(Muxer *mux, const OptionsContext *o) } } if (best_ist) - return ost_add(mux, o, AVMEDIA_TYPE_AUDIO, best_ist, NULL, NULL); + return ost_add(mux, o, AVMEDIA_TYPE_AUDIO, best_ist, NULL, NULL, NULL); return 0; } @@ -1683,7 +1685,7 @@ static int map_auto_subtitle(Muxer *mux, const OptionsContext *o) input_descriptor && output_descriptor && (!input_descriptor->props || !output_descriptor->props)) { - return ost_add(mux, o, AVMEDIA_TYPE_SUBTITLE, ist, NULL, NULL); + return ost_add(mux, o, AVMEDIA_TYPE_SUBTITLE, ist, NULL, NULL, NULL); } } @@ -1704,7 +1706,7 @@ static int map_auto_data(Muxer *mux, const OptionsContext *o) continue; if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA && ist->st->codecpar->codec_id == codec_id) { - int ret = ost_add(mux, o, AVMEDIA_TYPE_DATA, ist, NULL, NULL); + int ret = ost_add(mux, o, AVMEDIA_TYPE_DATA, ist, NULL, NULL, NULL); if (ret < 0) return ret; } @@ -1746,10 +1748,13 @@ loop_end: av_log(mux, AV_LOG_VERBOSE, "Creating output stream from an explicitly " "mapped complex filtergraph %d, output [%s]\n", fg->index, map->linklabel); - ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL); + ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL, NULL); if (ret < 0) return ret; } else { + const ViewSpecifier *vs = map->vs.type == VIEW_SPECIFIER_TYPE_NONE ? + NULL : &map->vs; + ist = input_files[map->file_index]->streams[map->stream_index]; if (ist->user_set_discard == AVDISCARD_ALL) { av_log(mux, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n", @@ -1780,7 +1785,14 @@ loop_end: return 0; } - ret = ost_add(mux, o, ist->st->codecpar->codec_type, ist, NULL, NULL); + if (vs && ist->st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) { + av_log(mux, AV_LOG_ERROR, + "View specifier given for mapping a %s input stream\n", + av_get_media_type_string(ist->st->codecpar->codec_type)); + return AVERROR(EINVAL); + } + + ret = ost_add(mux, o, ist->st->codecpar->codec_type, ist, NULL, vs, NULL); if (ret < 0) return ret; } @@ -1850,7 +1862,7 @@ read_fail: return AVERROR(ENOMEM); } - err = ost_add(mux, o, AVMEDIA_TYPE_ATTACHMENT, NULL, NULL, &ost); + err = ost_add(mux, o, AVMEDIA_TYPE_ATTACHMENT, NULL, NULL, NULL, &ost); if (err < 0) { av_free(attachment_filename); av_freep(&attachment); @@ -1905,7 +1917,7 @@ static int create_streams(Muxer *mux, const OptionsContext *o) av_get_media_type_string(ofilter->type)); av_log(mux, AV_LOG_VERBOSE, "\n"); - ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL); + ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL, NULL); if (ret < 0) return ret; } diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 1aa187f706..f639a1cf0a 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -46,6 +46,7 @@ #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/parseutils.h" +#include "libavutil/stereo3d.h" HWDevice *filter_hw_device; @@ -228,6 +229,59 @@ OPT_MATCH_PER_STREAM(int, int, OPT_TYPE_INT, i); OPT_MATCH_PER_STREAM(int64, int64_t, OPT_TYPE_INT64, i64); OPT_MATCH_PER_STREAM(dbl, double, OPT_TYPE_DOUBLE, dbl); +int view_specifier_parse(const char **pspec, ViewSpecifier *vs) +{ + const char *spec = *pspec; + char *endptr; + + vs->type = VIEW_SPECIFIER_TYPE_NONE; + + if (!strncmp(spec, "view:", 5)) { + spec += 5; + + if (!strncmp(spec, "all", 3)) { + spec += 3; + vs->type = VIEW_SPECIFIER_TYPE_ALL; + } else { + vs->type = VIEW_SPECIFIER_TYPE_ID; + vs->val = strtoul(spec, &endptr, 0); + if (endptr == spec) { + av_log(NULL, AV_LOG_ERROR, "Invalid view ID: %s\n", spec); + return AVERROR(EINVAL); + } + spec = endptr; + } + } else if (!strncmp(spec, "vidx:", 5)) { + spec += 5; + vs->type = VIEW_SPECIFIER_TYPE_IDX; + vs->val = strtoul(spec, &endptr, 0); + if (endptr == spec) { + av_log(NULL, AV_LOG_ERROR, "Invalid view index: %s\n", spec); + return AVERROR(EINVAL); + } + spec = endptr; + } else if (!strncmp(spec, "vpos:", 5)) { + spec += 5; + vs->type = VIEW_SPECIFIER_TYPE_POS; + + if (!strncmp(spec, "left", 4) && !cmdutils_isalnum(spec[4])) { + spec += 4; + vs->val = AV_STEREO3D_VIEW_LEFT; + } else if (!strncmp(spec, "right", 5) && !cmdutils_isalnum(spec[5])) { + spec += 5; + vs->val = AV_STEREO3D_VIEW_RIGHT; + } else { + av_log(NULL, AV_LOG_ERROR, "Invalid view position: %s\n", spec); + return AVERROR(EINVAL); + } + } else + return 0; + + *pspec = spec; + + return 0; +} + int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global) { if (!av_strcasecmp(arg, "cfr")) *vsync_var = VSYNC_CFR; @@ -452,6 +506,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg) goto fail; } } else { + ViewSpecifier vs; char *endptr; file_idx = strtol(arg, &endptr, 0); @@ -468,12 +523,18 @@ static int opt_map(void *optctx, const char *opt, const char *arg) goto fail; } - if (ss.remainder) { - if (!strcmp(ss.remainder, "?")) + arg = ss.remainder ? ss.remainder : ""; + + ret = view_specifier_parse(&arg, &vs); + if (ret < 0) + goto fail; + + if (*arg) { + if (!strcmp(arg, "?")) allow_unused = 1; else { - av_log(NULL, AV_LOG_ERROR, "Trailing garbage after stream specifier: %s\n", - ss.remainder); + av_log(NULL, AV_LOG_ERROR, + "Trailing garbage after stream specifier: %s\n", arg); ret = AVERROR(EINVAL); goto fail; } @@ -509,6 +570,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg) m->file_index = file_idx; m->stream_index = i; + m->vs = vs; } } From patchwork Sat Sep 14 10:45:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51598 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp322919vqy; Sat, 14 Sep 2024 05:09:13 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXzq6I6iJNa/R4kwq3AM9t60ScQycgaJx8F4hG3pRzz/IWfKLVSGdRbMzx/pN55SzdgWkoH2AwFQZVmZ1KceB7R@gmail.com X-Google-Smtp-Source: AGHT+IFNmc8JEjMVvrKrfSOmLb4XBXZMWPQqzmk5+YSYLN1/FIlh0duVYjmc7v6kRLuC0VEzPan2 X-Received: by 2002:a17:907:2da3:b0:a7d:9f92:9107 with SMTP id a640c23a62f3a-a9029690793mr1081459366b.58.1726315753093; Sat, 14 Sep 2024 05:09:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726315753; cv=none; d=google.com; s=arc-20240605; b=fcHwbMH9kB/0TNfDEXKJ/KvcolzR0dnGdRLaD2dvdEZCuf39hgWeJ20f6+J7Tg5fmP oEYIpDFBDAZc/bj7dE6C79klbgdfP+ZzE1T3CJijglpjf+hGjwRgvvO0bZ05uDx59rwB ulSkk2rzRSYPAIbnUvvqZepQJmPNL0N9TNZ9G6naBFNJyePEg1I08x8UzSoc7MQwgO7U 33e2WSLBlx3pO3GkPzrSNeSLp0lrPyngS/CCGpVRSAiDaSXsnf4+SUkA+33Ad7/yhaRD d4VTevAprceIJdmzi1MGF1AKhmj7KcDHkAzwK4AxfYGxA/K43goiH615IDbegFXvjwKe JGMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=yWewPniQJo+V1y3v1D9UWYuZt1X7nUhmplVMyqRSyW4=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=eIKdL/KIs9Xw73OmeMyA1mDOl57c8PW1qf/G5x74D2MwFyjz8gt3UKnfjR/u5n0sgn jHrRu11Y013HKesw2YR+qMl14hi/z+Psr8mlh5HcyMtp89eH4JVMz1FXf2QhL/UWcXna GirpXJzgyyhwmESHvr0uQwbPNZXgwGH4bwEIhm0dK4EIxPwyKh/HD2Pd74g79fYNP6d9 TmhA5zvtcuNHSRcNHBkDVkDmKAdEcU5u1wcc15JJJLIl4uWbDyn7RyiHk5PwBaME36Ls 6FvxWVj8x+t2f3sLKnmQzF9a2nc8ByMuGPQa0oqAzTtGxJ0K43JtVc6BFyUY14l6j5P0 zqkw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=iBUGETtR; 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 a640c23a62f3a-a9061336c2esi95365266b.782.2024.09.14.05.09.12; Sat, 14 Sep 2024 05:09:13 -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=@khirnov.net header.s=mail header.b=iBUGETtR; 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 D2BE568DE80; Sat, 14 Sep 2024 14:11:13 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2508B68DDDF for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=iBUGETtR; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id ADEFC4E13 for ; Sat, 14 Sep 2024 13:10:51 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id xGihYV4TQ4Du for ; Sat, 14 Sep 2024 13:10:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=nCB49wS9ra6G+KY7bE65EkXHrQSm5V15RsSXSOXL6ac=; h=From:To:Subject:Date:In-Reply-To:References:From; b=iBUGETtRJj0uroX92RyPgVWhiU6FiOXwRUw+P9oplLkQtjanb6TlCvvmxiWgggJp9 sPKqMsM1uES46zAZBorcGjd2YU7dVeXaFKWIySABWP6EZ5OksrENwmhjWTATPfoyY1 hDb+eoBf8Q7muc7d/jE6GchrMx4OBHin5ApNYopKPYrW4wdxaC4s0pz9JYgNKdF5v7 +Yzn+MYfIhVSWie9ZbJRRTuoTT4Lb/VQqrZvX2atv2MMx8aJH3yQ9KCHMj3C+axn1h gP66GTbBX8sYRfsCl6ZRXXlS7vgGGX5Mh89LxsK8pH82KmbM2jj7FgeZ2k9lldykGW 1oxndEO3KYGuw== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 8F15B4E23 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id C72863A21B3 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:45 +0200 Message-ID: <20240914111036.17164-21-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 20/23] tests/fate/hevc: add MV-HEVC conformance sample tests 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: b477+DqzVM09 Only those that can be decoded with our implementation, so excluding * C and D - independent layers * G, H, I - more than 2 layers Frame hashes verified against the reference implementation from https://hevc.hhi.fraunhofer.de/svn/svn_3DVCSoftware/ --- tests/fate/hevc.mak | 13 +- tests/ref/fate/hevc-conformance-MVHEVCS_A | 106 +++++++++++++++++ tests/ref/fate/hevc-conformance-MVHEVCS_B | 138 ++++++++++++++++++++++ tests/ref/fate/hevc-conformance-MVHEVCS_E | 106 +++++++++++++++++ tests/ref/fate/hevc-conformance-MVHEVCS_F | 106 +++++++++++++++++ 5 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 tests/ref/fate/hevc-conformance-MVHEVCS_A create mode 100644 tests/ref/fate/hevc-conformance-MVHEVCS_B create mode 100644 tests/ref/fate/hevc-conformance-MVHEVCS_E create mode 100644 tests/ref/fate/hevc-conformance-MVHEVCS_F diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index 88aeb9cebd..eb9d3a875c 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -178,7 +178,14 @@ HEVC_SAMPLES_444_12BIT = \ PERSIST_RPARAM_A_RExt_Sony_3\ $(if $(CONFIG_LARGE_TESTS), $(HEVC_SAMPLES_444_12BIT_LARGE)) -FATE_HEVC_VARS := 8BIT 10BIT 422_10BIT 422_10BIN 444_8BIT 444_12BIT +HEVC_SAMPLES_MULTIVIEW = \ + MVHEVCS_A \ + MVHEVCS_B \ + MVHEVCS_E \ + MVHEVCS_F \ + + +FATE_HEVC_VARS := 8BIT 10BIT 422_10BIT 422_10BIN 444_8BIT 444_12BIT MULTIVIEW $(foreach VAR,$(FATE_HEVC_VARS), $(eval HEVC_TESTS_$(VAR) := $(addprefix fate-hevc-conformance-, $(HEVC_SAMPLES_$(VAR))))) # equivalent bitstreams @@ -202,6 +209,8 @@ $(HEVC_TESTS_422_10BIT) $(HEVC_TESTS_422_10BIN): SCALE_OPTS := -pix_fmt yuv422p1 $(HEVC_TESTS_444_12BIT): SCALE_OPTS := -pix_fmt yuv444p12le -vf scale fate-hevc-conformance-%: CMD = framecrc -i $(TARGET_SAMPLES)/hevc-conformance/$(subst fate-hevc-conformance-,,$(@)).bit $(SCALE_OPTS) $(HEVC_TESTS_422_10BIN): CMD = framecrc -i $(TARGET_SAMPLES)/hevc-conformance/$(subst fate-hevc-conformance-,,$(@)).bin $(SCALE_OPTS) +$(HEVC_TESTS_MULTIVIEW): CMD = framecrc -i $(TARGET_SAMPLES)/hevc-conformance/$(subst fate-hevc-conformance-,,$(@)).bit \ + -pix_fmt yuv420p -map "0:view:0" -map "0:view:1" -vf setpts=N FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_PARSER) += $(HEVC_TESTS_8BIT) $(HEVC_TESTS_444_8BIT) FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_PARSER SCALE_FILTER) += \ @@ -210,6 +219,8 @@ FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_PARSER SCALE_FILTER) += \ $(HEVC_TESTS_422_10BIN) \ $(HEVC_TESTS_444_12BIT) \ +FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_PARSER SCALE_FILTER) += $(HEVC_TESTS_MULTIVIEW) + fate-hevc-paramchange-yuv420p-yuv420p10: CMD = framecrc -i $(TARGET_SAMPLES)/hevc/paramchange_yuv420p_yuv420p10.hevc -fps_mode passthrough -sws_flags area+accurate_rnd+bitexact FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_PARSER SCALE_FILTER LARGE_TESTS) += fate-hevc-paramchange-yuv420p-yuv420p10 diff --git a/tests/ref/fate/hevc-conformance-MVHEVCS_A b/tests/ref/fate/hevc-conformance-MVHEVCS_A new file mode 100644 index 0000000000..c919889207 --- /dev/null +++ b/tests/ref/fate/hevc-conformance-MVHEVCS_A @@ -0,0 +1,106 @@ +#tb 0: 1/1200000 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 1024x768 +#sar 0: 0/1 +#tb 1: 1/1200000 +#media_type 1: video +#codec_id 1: rawvideo +#dimensions 1: 1024x768 +#sar 1: 0/1 +0, 0, 0, 0, 1179648, 0x4a15620e +1, 0, 0, 0, 1179648, 0x5b752453 +0, 1, 1, 0, 1179648, 0xb33277fe +1, 1, 1, 0, 1179648, 0xacf4376d +0, 2, 2, 0, 1179648, 0x97b969bd +1, 2, 2, 0, 1179648, 0xa9d6e75d +0, 3, 3, 0, 1179648, 0x3c6b7b81 +1, 3, 3, 0, 1179648, 0x2142cc59 +0, 4, 4, 0, 1179648, 0xdf83fe63 +1, 4, 4, 0, 1179648, 0x838d4f0a +0, 5, 5, 0, 1179648, 0x93fc3bdf +1, 5, 5, 0, 1179648, 0x29bc71c2 +0, 6, 6, 0, 1179648, 0x18f90aa3 +1, 6, 6, 0, 1179648, 0x3b25ee18 +0, 7, 7, 0, 1179648, 0x84c730c5 +1, 7, 7, 0, 1179648, 0x60ecae5b +0, 8, 8, 0, 1179648, 0x7b49f2b1 +1, 8, 8, 0, 1179648, 0x8c3c635e +0, 9, 9, 0, 1179648, 0x71f1b862 +1, 9, 9, 0, 1179648, 0x16c2a6fc +0, 10, 10, 0, 1179648, 0x92be991a +1, 10, 10, 0, 1179648, 0x092d6378 +0, 11, 11, 0, 1179648, 0xa948322d +1, 11, 11, 0, 1179648, 0x5d977eec +0, 12, 12, 0, 1179648, 0x54838c22 +1, 12, 12, 0, 1179648, 0x66fc891e +0, 13, 13, 0, 1179648, 0xc2682668 +1, 13, 13, 0, 1179648, 0x0b60bd06 +0, 14, 14, 0, 1179648, 0x1fa22020 +1, 14, 14, 0, 1179648, 0x201706e2 +0, 15, 15, 0, 1179648, 0x3a686683 +1, 15, 15, 0, 1179648, 0x9c59849c +0, 16, 16, 0, 1179648, 0x991431ab +1, 16, 16, 0, 1179648, 0xb495ba09 +0, 17, 17, 0, 1179648, 0xd394e067 +1, 17, 17, 0, 1179648, 0x1d1db0c6 +0, 18, 18, 0, 1179648, 0xbe694632 +1, 18, 18, 0, 1179648, 0x22beec67 +0, 19, 19, 0, 1179648, 0x8a48c7a7 +1, 19, 19, 0, 1179648, 0x3515ac62 +0, 20, 20, 0, 1179648, 0x8d7e9e6d +1, 20, 20, 0, 1179648, 0x3b73015b +0, 21, 21, 0, 1179648, 0x14f28d47 +1, 21, 21, 0, 1179648, 0x4e01fdb7 +0, 22, 22, 0, 1179648, 0x1885631b +1, 22, 22, 0, 1179648, 0xca33f8de +0, 23, 23, 0, 1179648, 0x29c795f1 +1, 23, 23, 0, 1179648, 0x925517c1 +0, 24, 24, 0, 1179648, 0xee23fd91 +1, 24, 24, 0, 1179648, 0x0894bf6a +0, 25, 25, 0, 1179648, 0xa57dce94 +1, 25, 25, 0, 1179648, 0xebfe296d +0, 26, 26, 0, 1179648, 0x6c3b16d8 +1, 26, 26, 0, 1179648, 0x62acb3e0 +0, 27, 27, 0, 1179648, 0xbf5a112f +1, 27, 27, 0, 1179648, 0x72f6ae90 +0, 28, 28, 0, 1179648, 0x5e7ce2a7 +1, 28, 28, 0, 1179648, 0xb4c6bcbc +0, 29, 29, 0, 1179648, 0x0529ad59 +1, 29, 29, 0, 1179648, 0x438c8160 +0, 30, 30, 0, 1179648, 0xc94d561d +1, 30, 30, 0, 1179648, 0x1b3a02af +0, 31, 31, 0, 1179648, 0x7079bbc0 +1, 31, 31, 0, 1179648, 0x6034d275 +0, 32, 32, 0, 1179648, 0x6c8e1265 +1, 32, 32, 0, 1179648, 0x9e688ee2 +0, 33, 33, 0, 1179648, 0x5e1494ee +1, 33, 33, 0, 1179648, 0xe39cab5d +0, 34, 34, 0, 1179648, 0xe3654994 +1, 34, 34, 0, 1179648, 0xeefe533b +0, 35, 35, 0, 1179648, 0x329510fa +1, 35, 35, 0, 1179648, 0x48ed2162 +0, 36, 36, 0, 1179648, 0x92120a9f +1, 36, 36, 0, 1179648, 0xb0fb26b3 +0, 37, 37, 0, 1179648, 0x6f279a56 +1, 37, 37, 0, 1179648, 0xc4185523 +0, 38, 38, 0, 1179648, 0xd2ad5c1d +1, 38, 38, 0, 1179648, 0x8124687d +0, 39, 39, 0, 1179648, 0xd7e5bbaa +1, 39, 39, 0, 1179648, 0x39f1b702 +0, 40, 40, 0, 1179648, 0xb5628743 +1, 40, 40, 0, 1179648, 0xee5802d7 +0, 41, 41, 0, 1179648, 0x2760515e +1, 41, 41, 0, 1179648, 0xdeac4fbd +0, 42, 42, 0, 1179648, 0x11a2f57a +1, 42, 42, 0, 1179648, 0xb1c7977f +0, 43, 43, 0, 1179648, 0x2c47dd8f +1, 43, 43, 0, 1179648, 0xaaaddace +0, 44, 44, 0, 1179648, 0x890fe8c2 +1, 44, 44, 0, 1179648, 0x7ff8e81e +0, 45, 45, 0, 1179648, 0x65e9f9ac +1, 45, 45, 0, 1179648, 0xf9b1b99c +0, 46, 46, 0, 1179648, 0x3e4fa8d9 +1, 46, 46, 0, 1179648, 0xfc3659e6 +0, 47, 47, 0, 1179648, 0x356e13ee +1, 47, 47, 0, 1179648, 0xff8bfa3f diff --git a/tests/ref/fate/hevc-conformance-MVHEVCS_B b/tests/ref/fate/hevc-conformance-MVHEVCS_B new file mode 100644 index 0000000000..07155c50e1 --- /dev/null +++ b/tests/ref/fate/hevc-conformance-MVHEVCS_B @@ -0,0 +1,138 @@ +#tb 0: 1/1200000 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 1024x768 +#sar 0: 0/1 +#tb 1: 1/1200000 +#media_type 1: video +#codec_id 1: rawvideo +#dimensions 1: 1024x768 +#sar 1: 0/1 +0, 0, 0, 0, 1179648, 0x4b39cdfe +1, 0, 0, 0, 1179648, 0x1afcd2a3 +0, 1, 1, 0, 1179648, 0xef0da64e +1, 1, 1, 0, 1179648, 0x2bb1d07b +0, 2, 2, 0, 1179648, 0x9dd9e5a7 +1, 2, 2, 0, 1179648, 0xcc0547f2 +0, 3, 3, 0, 1179648, 0xee948285 +1, 3, 3, 0, 1179648, 0x3375f14b +0, 4, 4, 0, 1179648, 0x75117927 +1, 4, 4, 0, 1179648, 0x1e059655 +0, 5, 5, 0, 1179648, 0xad9fec31 +1, 5, 5, 0, 1179648, 0xfed7ef37 +0, 6, 6, 0, 1179648, 0x53cd0f53 +1, 6, 6, 0, 1179648, 0xa725f316 +0, 7, 7, 0, 1179648, 0xcbda04b5 +1, 7, 7, 0, 1179648, 0xd13b99db +0, 8, 8, 0, 1179648, 0x71861302 +1, 8, 8, 0, 1179648, 0x911d2c79 +0, 9, 9, 0, 1179648, 0x5d2564dd +1, 9, 9, 0, 1179648, 0x70fa087a +0, 10, 10, 0, 1179648, 0xcfa6d394 +1, 10, 10, 0, 1179648, 0x69a27b84 +0, 11, 11, 0, 1179648, 0x18fe7393 +1, 11, 11, 0, 1179648, 0xcc665fd1 +0, 12, 12, 0, 1179648, 0xb329d489 +1, 12, 12, 0, 1179648, 0xf8d93bbf +0, 13, 13, 0, 1179648, 0x3b029004 +1, 13, 13, 0, 1179648, 0x39655020 +0, 14, 14, 0, 1179648, 0x6c81bf8e +1, 14, 14, 0, 1179648, 0x13da6f67 +0, 15, 15, 0, 1179648, 0x25e3e0a9 +1, 15, 15, 0, 1179648, 0xdc372a0f +0, 16, 16, 0, 1179648, 0x8f2c789f +1, 16, 16, 0, 1179648, 0xba8a3e23 +0, 17, 17, 0, 1179648, 0x372b866f +1, 17, 17, 0, 1179648, 0x27d31b48 +0, 18, 18, 0, 1179648, 0x5cfc8119 +1, 18, 18, 0, 1179648, 0x50aca559 +0, 19, 19, 0, 1179648, 0x593af76c +1, 19, 19, 0, 1179648, 0x27c0e522 +0, 20, 20, 0, 1179648, 0x852864b7 +1, 20, 20, 0, 1179648, 0xa8739c77 +0, 21, 21, 0, 1179648, 0x71f4b961 +1, 21, 21, 0, 1179648, 0x27c16037 +0, 22, 22, 0, 1179648, 0x6c5ebb84 +1, 22, 22, 0, 1179648, 0x74a6ede9 +0, 23, 23, 0, 1179648, 0xb5467da9 +1, 23, 23, 0, 1179648, 0x1ea455b9 +0, 24, 24, 0, 1179648, 0x92d58478 +1, 24, 24, 0, 1179648, 0x9e464f3a +0, 25, 25, 0, 1179648, 0xa6181655 +1, 25, 25, 0, 1179648, 0x8af4fd5b +0, 26, 26, 0, 1179648, 0x15e9ee9a +1, 26, 26, 0, 1179648, 0xa6ed4580 +0, 27, 27, 0, 1179648, 0x4782abf9 +1, 27, 27, 0, 1179648, 0x73fc62e6 +0, 28, 28, 0, 1179648, 0x8c06f337 +1, 28, 28, 0, 1179648, 0xb2d3dfbf +0, 29, 29, 0, 1179648, 0x2e6b1a88 +1, 29, 29, 0, 1179648, 0x2066f08e +0, 30, 30, 0, 1179648, 0x584eac3e +1, 30, 30, 0, 1179648, 0xa0bfb75b +0, 31, 31, 0, 1179648, 0x9a2dae49 +1, 31, 31, 0, 1179648, 0x89445161 +0, 32, 32, 0, 1179648, 0x3a50c6f4 +1, 32, 32, 0, 1179648, 0x9befaa17 +0, 33, 33, 0, 1179648, 0x1afcbfd6 +1, 33, 33, 0, 1179648, 0xb243de65 +0, 34, 34, 0, 1179648, 0xfdda4e8c +1, 34, 34, 0, 1179648, 0xf945451a +0, 35, 35, 0, 1179648, 0x8fffa546 +1, 35, 35, 0, 1179648, 0x06b20109 +0, 36, 36, 0, 1179648, 0xbc2c9dfc +1, 36, 36, 0, 1179648, 0x344c1ed8 +0, 37, 37, 0, 1179648, 0xb2d08414 +1, 37, 37, 0, 1179648, 0xccd35195 +0, 38, 38, 0, 1179648, 0x54886d31 +1, 38, 38, 0, 1179648, 0x653ed9df +0, 39, 39, 0, 1179648, 0x07c3b249 +1, 39, 39, 0, 1179648, 0xf92b9e88 +0, 40, 40, 0, 1179648, 0x073b9491 +1, 40, 40, 0, 1179648, 0x4ed7ee12 +0, 41, 41, 0, 1179648, 0xcd669799 +1, 41, 41, 0, 1179648, 0xa7faed20 +0, 42, 42, 0, 1179648, 0xd21b0a28 +1, 42, 42, 0, 1179648, 0xb34d0f7f +0, 43, 43, 0, 1179648, 0xb4b820c9 +1, 43, 43, 0, 1179648, 0xf496d13d +0, 44, 44, 0, 1179648, 0x2d2940d0 +1, 44, 44, 0, 1179648, 0x985d67f5 +0, 45, 45, 0, 1179648, 0x919c554a +1, 45, 45, 0, 1179648, 0x697d0b66 +0, 46, 46, 0, 1179648, 0x7dd28f61 +1, 46, 46, 0, 1179648, 0x504d6971 +0, 47, 47, 0, 1179648, 0x51af9760 +1, 47, 47, 0, 1179648, 0x956d7fb1 +0, 48, 48, 0, 1179648, 0x8801beba +1, 48, 48, 0, 1179648, 0xec62570e +0, 49, 49, 0, 1179648, 0x80b37318 +1, 49, 49, 0, 1179648, 0x48284486 +0, 50, 50, 0, 1179648, 0x91c52522 +1, 50, 50, 0, 1179648, 0xe3a72477 +0, 51, 51, 0, 1179648, 0x6721373b +1, 51, 51, 0, 1179648, 0x9fb05dfa +0, 52, 52, 0, 1179648, 0xd2a250ca +1, 52, 52, 0, 1179648, 0xbd294daf +0, 53, 53, 0, 1179648, 0x6005c976 +1, 53, 53, 0, 1179648, 0x7f311bbb +0, 54, 54, 0, 1179648, 0x2d42f334 +1, 54, 54, 0, 1179648, 0x3bea1741 +0, 55, 55, 0, 1179648, 0xd696879d +1, 55, 55, 0, 1179648, 0x9b3259fd +0, 56, 56, 0, 1179648, 0x3324c463 +1, 56, 56, 0, 1179648, 0xc90f475d +0, 57, 57, 0, 1179648, 0x824c47df +1, 57, 57, 0, 1179648, 0x0effe63f +0, 58, 58, 0, 1179648, 0x06abf15f +1, 58, 58, 0, 1179648, 0x646ee426 +0, 59, 59, 0, 1179648, 0x34ef0c34 +1, 59, 59, 0, 1179648, 0x0fe901c7 +0, 60, 60, 0, 1179648, 0x54a6ef58 +1, 60, 60, 0, 1179648, 0xb726f458 +0, 61, 61, 0, 1179648, 0x4e9c7db9 +1, 61, 61, 0, 1179648, 0xf28adc7e +0, 62, 62, 0, 1179648, 0x70887af9 +1, 62, 62, 0, 1179648, 0x00258e2f +0, 63, 63, 0, 1179648, 0x661779d7 +1, 63, 63, 0, 1179648, 0x4598b8f7 diff --git a/tests/ref/fate/hevc-conformance-MVHEVCS_E b/tests/ref/fate/hevc-conformance-MVHEVCS_E new file mode 100644 index 0000000000..19a4a3e863 --- /dev/null +++ b/tests/ref/fate/hevc-conformance-MVHEVCS_E @@ -0,0 +1,106 @@ +#tb 0: 1/1200000 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 1024x768 +#sar 0: 0/1 +#tb 1: 1/1200000 +#media_type 1: video +#codec_id 1: rawvideo +#dimensions 1: 1024x768 +#sar 1: 0/1 +0, 0, 0, 0, 1179648, 0x4a15620e +1, 0, 0, 0, 1179648, 0x5b752453 +0, 1, 1, 0, 1179648, 0xb33277fe +1, 1, 1, 0, 1179648, 0xacf4376d +0, 2, 2, 0, 1179648, 0x97b969bd +1, 2, 2, 0, 1179648, 0xa9d6e75d +0, 3, 3, 0, 1179648, 0x3c6b7b81 +1, 3, 3, 0, 1179648, 0x2142cc59 +0, 4, 4, 0, 1179648, 0xdf83fe63 +1, 4, 4, 0, 1179648, 0x838d4f0a +0, 5, 5, 0, 1179648, 0x93fc3bdf +1, 5, 5, 0, 1179648, 0x29bc71c2 +0, 6, 6, 0, 1179648, 0x18f90aa3 +1, 6, 6, 0, 1179648, 0x3b25ee18 +0, 7, 7, 0, 1179648, 0x84c730c5 +1, 7, 7, 0, 1179648, 0x60ecae5b +0, 8, 8, 0, 1179648, 0x7b49f2b1 +1, 8, 8, 0, 1179648, 0x8c3c635e +0, 9, 9, 0, 1179648, 0x60956482 +1, 9, 9, 0, 1179648, 0x8f4cb379 +0, 10, 10, 0, 1179648, 0x7af31124 +1, 10, 10, 0, 1179648, 0x398fec3c +0, 11, 11, 0, 1179648, 0xf56c7994 +1, 11, 11, 0, 1179648, 0xced70ad2 +0, 12, 12, 0, 1179648, 0x1fbd6730 +1, 12, 12, 0, 1179648, 0x4d85d789 +0, 13, 13, 0, 1179648, 0xf986b387 +1, 13, 13, 0, 1179648, 0xca3a70ea +0, 14, 14, 0, 1179648, 0xe3d5f7c5 +1, 14, 14, 0, 1179648, 0xcda13236 +0, 15, 15, 0, 1179648, 0xc646c7d1 +1, 15, 15, 0, 1179648, 0xe64a93c3 +0, 16, 16, 0, 1179648, 0xed69e4bc +1, 16, 16, 0, 1179648, 0x4426cbae +0, 17, 17, 0, 1179648, 0xaea6e7da +1, 17, 17, 0, 1179648, 0x544d045f +0, 18, 18, 0, 1179648, 0xbde3196f +1, 18, 18, 0, 1179648, 0x62b07e2a +0, 19, 19, 0, 1179648, 0x86beaf83 +1, 19, 19, 0, 1179648, 0x4ae8ac0e +0, 20, 20, 0, 1179648, 0xe162f75d +1, 20, 20, 0, 1179648, 0x092cad19 +0, 21, 21, 0, 1179648, 0xee24e674 +1, 21, 21, 0, 1179648, 0x8eab2b13 +0, 22, 22, 0, 1179648, 0xe887594a +1, 22, 22, 0, 1179648, 0x71fa0330 +0, 23, 23, 0, 1179648, 0x34a281d4 +1, 23, 23, 0, 1179648, 0xb0924dbb +0, 24, 24, 0, 1179648, 0x7ec4e840 +1, 24, 24, 0, 1179648, 0x895d98be +0, 25, 25, 0, 1179648, 0xd89577ca +1, 25, 25, 0, 1179648, 0xd91c1ea6 +0, 26, 26, 0, 1179648, 0xdc6e9c96 +1, 26, 26, 0, 1179648, 0x1b4c5dee +0, 27, 27, 0, 1179648, 0x51add2ea +1, 27, 27, 0, 1179648, 0x88c1a214 +0, 28, 28, 0, 1179648, 0x2fc19963 +1, 28, 28, 0, 1179648, 0x5861006d +0, 29, 29, 0, 1179648, 0x32243191 +1, 29, 29, 0, 1179648, 0xd4ed787c +0, 30, 30, 0, 1179648, 0xb7e2a2d8 +1, 30, 30, 0, 1179648, 0x1911a0e0 +0, 31, 31, 0, 1179648, 0x81662c81 +1, 31, 31, 0, 1179648, 0x5a37d3db +0, 32, 32, 0, 1179648, 0x4e12d459 +1, 32, 32, 0, 1179648, 0x05d5a5a9 +0, 33, 33, 0, 1179648, 0x1dc706da +1, 33, 33, 0, 1179648, 0x59f898f8 +0, 34, 34, 0, 1179648, 0x585dd375 +1, 34, 34, 0, 1179648, 0x7aa2fa66 +0, 35, 35, 0, 1179648, 0x24f7efb1 +1, 35, 35, 0, 1179648, 0x868149ad +0, 36, 36, 0, 1179648, 0xf56aa128 +1, 36, 36, 0, 1179648, 0x4c0a3019 +0, 37, 37, 0, 1179648, 0x1b87470b +1, 37, 37, 0, 1179648, 0x94bea701 +0, 38, 38, 0, 1179648, 0x368f745f +1, 38, 38, 0, 1179648, 0xf6c2b923 +0, 39, 39, 0, 1179648, 0xf0e62ce7 +1, 39, 39, 0, 1179648, 0xcc7c08c4 +0, 40, 40, 0, 1179648, 0xfc66a8a2 +1, 40, 40, 0, 1179648, 0x21afffac +0, 41, 41, 0, 1179648, 0xd136f02f +1, 41, 41, 0, 1179648, 0x0339f774 +0, 42, 42, 0, 1179648, 0x370dec8e +1, 42, 42, 0, 1179648, 0x6a66793e +0, 43, 43, 0, 1179648, 0x5e4de669 +1, 43, 43, 0, 1179648, 0x17f5ae53 +0, 44, 44, 0, 1179648, 0xc0f0e971 +1, 44, 44, 0, 1179648, 0xa741e3bf +0, 45, 45, 0, 1179648, 0x88315d92 +1, 45, 45, 0, 1179648, 0xa7895cc1 +0, 46, 46, 0, 1179648, 0x1c4eb46c +1, 46, 46, 0, 1179648, 0x0228cf31 +0, 47, 47, 0, 1179648, 0x30384288 +1, 47, 47, 0, 1179648, 0x870f2d06 diff --git a/tests/ref/fate/hevc-conformance-MVHEVCS_F b/tests/ref/fate/hevc-conformance-MVHEVCS_F new file mode 100644 index 0000000000..3770354413 --- /dev/null +++ b/tests/ref/fate/hevc-conformance-MVHEVCS_F @@ -0,0 +1,106 @@ +#tb 0: 1/1200000 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 1024x768 +#sar 0: 0/1 +#tb 1: 1/1200000 +#media_type 1: video +#codec_id 1: rawvideo +#dimensions 1: 1024x768 +#sar 1: 0/1 +0, 0, 0, 0, 1179648, 0x4a15620e +1, 0, 0, 0, 1179648, 0x5b752453 +0, 1, 1, 0, 1179648, 0x568f99cf +1, 1, 1, 0, 1179648, 0xacf4376d +0, 2, 2, 0, 1179648, 0xea67491c +1, 2, 2, 0, 1179648, 0xa9d6e75d +0, 3, 3, 0, 1179648, 0x57ed0a7f +1, 3, 3, 0, 1179648, 0x2142cc59 +0, 4, 4, 0, 1179648, 0x5b218d68 +1, 4, 4, 0, 1179648, 0x838d4f0a +0, 5, 5, 0, 1179648, 0x8075c0c0 +1, 5, 5, 0, 1179648, 0x29bc71c2 +0, 6, 6, 0, 1179648, 0x75e0bb9f +1, 6, 6, 0, 1179648, 0x3b25ee18 +0, 7, 7, 0, 1179648, 0xaef237d0 +1, 7, 7, 0, 1179648, 0x60ecae5b +0, 8, 8, 0, 1179648, 0x9943126a +1, 8, 8, 0, 1179648, 0x8c3c635e +0, 9, 9, 0, 1179648, 0x3c8bbac8 +1, 9, 9, 0, 1179648, 0x8f4cb379 +0, 10, 10, 0, 1179648, 0xad824cae +1, 10, 10, 0, 1179648, 0x398fec3c +0, 11, 11, 0, 1179648, 0x3c156c58 +1, 11, 11, 0, 1179648, 0xced70ad2 +0, 12, 12, 0, 1179648, 0x18261259 +1, 12, 12, 0, 1179648, 0x4d85d789 +0, 13, 13, 0, 1179648, 0xd481dafa +1, 13, 13, 0, 1179648, 0xca3a70ea +0, 14, 14, 0, 1179648, 0x6a0d3af8 +1, 14, 14, 0, 1179648, 0xcda13236 +0, 15, 15, 0, 1179648, 0xaa355e8f +1, 15, 15, 0, 1179648, 0xe64a93c3 +0, 16, 16, 0, 1179648, 0xed69e4bc +1, 16, 16, 0, 1179648, 0x4426cbae +0, 17, 17, 0, 1179648, 0x340d6c4a +1, 17, 17, 0, 1179648, 0x544d045f +0, 18, 18, 0, 1179648, 0xd52398d0 +1, 18, 18, 0, 1179648, 0x62b07e2a +0, 19, 19, 0, 1179648, 0x39d92b93 +1, 19, 19, 0, 1179648, 0x4ae8ac0e +0, 20, 20, 0, 1179648, 0x364fd94f +1, 20, 20, 0, 1179648, 0x092cad19 +0, 21, 21, 0, 1179648, 0x977cabf5 +1, 21, 21, 0, 1179648, 0x8eab2b13 +0, 22, 22, 0, 1179648, 0x23febfaf +1, 22, 22, 0, 1179648, 0x71fa0330 +0, 23, 23, 0, 1179648, 0xd7e5afa0 +1, 23, 23, 0, 1179648, 0xb0924dbb +0, 24, 24, 0, 1179648, 0x83799fed +1, 24, 24, 0, 1179648, 0x895d98be +0, 25, 25, 0, 1179648, 0xaec7466c +1, 25, 25, 0, 1179648, 0xd91c1ea6 +0, 26, 26, 0, 1179648, 0x4c4de340 +1, 26, 26, 0, 1179648, 0x1b4c5dee +0, 27, 27, 0, 1179648, 0x1c8c5bf6 +1, 27, 27, 0, 1179648, 0x88c1a214 +0, 28, 28, 0, 1179648, 0xc980311c +1, 28, 28, 0, 1179648, 0x5861006d +0, 29, 29, 0, 1179648, 0xb55dbf43 +1, 29, 29, 0, 1179648, 0xd4ed787c +0, 30, 30, 0, 1179648, 0xbc29868a +1, 30, 30, 0, 1179648, 0x1911a0e0 +0, 31, 31, 0, 1179648, 0x3d1dfc87 +1, 31, 31, 0, 1179648, 0x5a37d3db +0, 32, 32, 0, 1179648, 0x4e12d459 +1, 32, 32, 0, 1179648, 0x05d5a5a9 +0, 33, 33, 0, 1179648, 0xb4eb0d99 +1, 33, 33, 0, 1179648, 0x59f898f8 +0, 34, 34, 0, 1179648, 0x1d91ae23 +1, 34, 34, 0, 1179648, 0x7aa2fa66 +0, 35, 35, 0, 1179648, 0x0adf2e05 +1, 35, 35, 0, 1179648, 0x868149ad +0, 36, 36, 0, 1179648, 0x947e48dd +1, 36, 36, 0, 1179648, 0x4c0a3019 +0, 37, 37, 0, 1179648, 0xb7dddffd +1, 37, 37, 0, 1179648, 0x94bea701 +0, 38, 38, 0, 1179648, 0x027f1113 +1, 38, 38, 0, 1179648, 0xf6c2b923 +0, 39, 39, 0, 1179648, 0xc2a0afa2 +1, 39, 39, 0, 1179648, 0xcc7c08c4 +0, 40, 40, 0, 1179648, 0xd12a6bc0 +1, 40, 40, 0, 1179648, 0x21afffac +0, 41, 41, 0, 1179648, 0xf8f5d7ee +1, 41, 41, 0, 1179648, 0x0339f774 +0, 42, 42, 0, 1179648, 0xa7e5fd01 +1, 42, 42, 0, 1179648, 0x6a66793e +0, 43, 43, 0, 1179648, 0xe9aee64d +1, 43, 43, 0, 1179648, 0x17f5ae53 +0, 44, 44, 0, 1179648, 0x989fc660 +1, 44, 44, 0, 1179648, 0xa741e3bf +0, 45, 45, 0, 1179648, 0x43e1d4d0 +1, 45, 45, 0, 1179648, 0xa7895cc1 +0, 46, 46, 0, 1179648, 0x38be7f17 +1, 46, 46, 0, 1179648, 0x0228cf31 +0, 47, 47, 0, 1179648, 0xd867c854 +1, 47, 47, 0, 1179648, 0x870f2d06 From patchwork Sat Sep 14 10:45:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51596 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp311043vqy; Sat, 14 Sep 2024 04:39:20 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUQRBrC7zKq0eFWaKLXTgwPvpdHEABFoZXIEPmV+McEdDfCVRadzjBY6Ru75YjK01giRczHUVL1NTO+Vq/C9s4Z@gmail.com X-Google-Smtp-Source: AGHT+IG5xfZJL7XB82C6LgJ4r0eOGh0mqx5Dcmsa0L7xQVHwmIyu/4bNEZtgxb7jKbVwz7TncbL2 X-Received: by 2002:a17:907:94d4:b0:a90:34e8:780f with SMTP id a640c23a62f3a-a9034e87ae4mr768853166b.63.1726313960168; Sat, 14 Sep 2024 04:39:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313960; cv=none; d=google.com; s=arc-20240605; b=IGVZ1x1t8bjA/PTLQ7d6xcvR0pOHIwD+Vncb0YHkpWTQOy4fmrSOVpzE1bqNT75Cco I/oqhLQFyfMTpCgUMG0o5AxjNbOap/wz3WYX3uUaA1aDmPcut72SyZovNGu5G5bh53ec awtRHxCjvwGmnS2uCrlG918BJXfi6rR/DmYPoT9+7Nc65Nf7R/u1otkiP7q+tZ3uOlxS xdZ82JA5H6b89K0rvV7pgPmRPRTynONDrDQu1Ut1+pjWYqDwRrsRHdTyJR1QJOAEldki b/DiwkxEGBd15v9RrNAPcCKKDkAc7yDUkG4pJivDiCtRl+GJIByj5wCPd5f6VTVh8Gjs nGnw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=8yUV2O6P4RrvUbiq4QixVg2B4GMv0QDz3Hrk8c8hvpE=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=Af/cb0O0mrnGsVmJU/m/qd0yMw6OpUhwhOW3jqwTMe4EAV+zgKh+vI++CKqQyqSij8 ClZT002JM0h3uGdMZAJlNBd6q2sqNwiJiPFylo5izJldKsy7FsC32HF3HVDmSKQfEj7w iHNpM6K3rqtDi15bIUWgt7wIxi7lIE/+xXnj914K4jwFl460d1uU7EnT6ebRAOx3VwhN eH01qu19sirXiQqoYUhCHvQP0c9TGXsBYp89HvWAIbzUFnzgGClwB/MPV23UMwu6lCG4 M5XJSD3jpy5RigKKmVTMhdv2pYJENP4NqFHw/rs5ouBUaVNj02/AElCi3RCoXKHoBZS8 Lntg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=rskY7mN1; 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 a640c23a62f3a-a90612e92desi91102866b.530.2024.09.14.04.39.19; Sat, 14 Sep 2024 04:39:20 -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=@khirnov.net header.s=mail header.b=rskY7mN1; 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 46B5368DE8B; Sat, 14 Sep 2024 14:11:15 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2C98F68DDE8 for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=rskY7mN1; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 7434A4E1B for ; Sat, 14 Sep 2024 13:10:52 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id F89yYOBz-BFL for ; Sat, 14 Sep 2024 13:10:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=9iKg3cUcvDD+c47ybj4dmO+wUqJrKaOUcSLrV9C8nUg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=rskY7mN14VzmNQSmS8fwlX7irWOs+rXkXCpy4589kZTOXJE37lvR36UByYr4N7mgB U7hb2PV58HoD4UZ6+YKRUDipHyo/pwSOCOrCzDGxEvtk3RHerl1SPkJx43ucbDXi/P ZzSAoakde71SWiliOc5VJhe1mLHgkQ3GEvDxneDdGS4yhuBiHlE9pclhitbd4ASSvS IgrZx9Qm8OYxyce1bUAAxA/88kGXeCyVhN/CI/SktdFr94w3rw3LRsx+JRdUrHaawi ZB1RKEt6ZUzG7mc23nqiyUtBDGlSSKlUgo7UoD0PrY4SQ5FH5H+HkM9iMR04jLg13M bLG+aUQrRy6lg== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 9FA384E25 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id D29A53A25C4 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:46 +0200 Message-ID: <20240914111036.17164-22-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 21/23] tests/fate/hevc: add a test for nontrivial values of nuh_layer_id 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: fGuTgLzCxVhd Typical files use 0 for the base layer and 1 for the secondary one, but any value for the secondary layer should be supported. --- tests/fate/hevc.mak | 4 ++++ tests/ref/fate/hevc-mv-nuh-layer-id | 15 +++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/ref/fate/hevc-mv-nuh-layer-id diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index eb9d3a875c..df827d821f 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -272,6 +272,10 @@ FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, HEVC_PARSER SCALE_FILTER) += fate-hevc-sm fate-hevc-pir: CMD = framecrc -i $(TARGET_SAMPLES)/hevc/pir.hevc FATE_HEVC-$(call FRAMECRC, HEVC, HEVC) += fate-hevc-pir +# multiview stream, where the secondary layer has a nontrivial nuh_layer_id=6 +fate-hevc-mv-nuh-layer-id: CMD = framecrc -i $(TARGET_SAMPLES)/hevc/mv_nuh_layer_id.bit -map 0:view:all +FATE_HEVC-$(call FRAMECRC, HEVC, HEVC) += fate-hevc-mv-nuh-layer-id + FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) diff --git a/tests/ref/fate/hevc-mv-nuh-layer-id b/tests/ref/fate/hevc-mv-nuh-layer-id new file mode 100644 index 0000000000..3cbefe17f6 --- /dev/null +++ b/tests/ref/fate/hevc-mv-nuh-layer-id @@ -0,0 +1,15 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x128 +#sar 0: 0/1 +0, 0, 0, 1, 24576, 0xdfd350a6 +0, 1, 1, 1, 24576, 0xf8f638da +0, 2, 2, 1, 24576, 0x8ac574d5 +0, 3, 3, 1, 24576, 0xd22675a4 +0, 4, 4, 1, 24576, 0xdd0f4704 +0, 5, 5, 1, 24576, 0x60da42e6 +0, 6, 6, 1, 24576, 0x8bf28fdd +0, 7, 7, 1, 24576, 0xe0577f6e +0, 8, 8, 1, 24576, 0x8b3e3c29 +0, 9, 9, 1, 24576, 0x8d9944bd From patchwork Sat Sep 14 10:45:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51593 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp310976vqy; Sat, 14 Sep 2024 04:39:10 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVfyoNb2bYmiy5Bm7wA5kbRkLU/NmEPk2RDIF5HJFWBT4kMqIrmseV+30eN/ZgeSvQXvng85v1/FTZLnGxai8rC@gmail.com X-Google-Smtp-Source: AGHT+IFvcBq3OKvpWFU26yhSxqvsTEqUG0UAZcqV8KW53u/E82z/IryEPF7YdJ6N4mudATw5vpYA X-Received: by 2002:a05:6512:12c8:b0:533:46cc:a71e with SMTP id 2adb3069b0e04-53678fec522mr5383851e87.54.1726313950708; Sat, 14 Sep 2024 04:39:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726313950; cv=none; d=google.com; s=arc-20240605; b=esNcOniiS2YcnnswNW3xXaWUN4UZxhfc2bZDNLtVIO8ubMetK3EXhnzPkwfZKp+m5O z88Xole8J6tiwNsZWD/50zDFMcyEFx+DlkFmPnYQxyLpngoInuFP7RF3mRAJCRBSATs7 8WBZPaUCy6TVEv/0bG8JXVctcckVf09Gvc+P2RHJ1FgDPzTYrdoKGTtUUflx/zpVY1tP dKxbyW2eU2Q4gKhwfF8wNVQsfhOGANznPXlCm/B7Fy2t9tnScV/Yc3LJW4AqendsM7It pFu4959eyQ2bEor7IlmXEPq4B+Fk+EDSwMk7qwEipHH4op5kxymTZjtFBKO+gb/WzPk1 5wuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=xi4l4gSWQl9KrmziGMNOtO/s3sCE90Xc9izms3AGNYM=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=ByfCnH+ZE+QzJ6FOeR3beKIbcvCST8GyRIyEYq6hGS+QVCguz0YnK/FbnwwC+472Rp A688xeWjO6EKM/JRro2+oE67wT/WO72AJaB5XZJO1VhoWXkPmk48P7S3QoXPkFHusvRC jiAMP227T1oV8WNr3hK4rHSuAFwbgRoA9P6MANONcq8d+rFyEYScNCE0xQRyO0rRngYg Zp03hIjodmGIfTeepgLkNMeb6oqztmkIbP9sqxY2p7nTHiDQUqPsr5nlyDDnR25n9gQK d/ZJ6nRBK2Xm9XMVx2N+U+SseShP7TXMBrffggFZQIYGArpGfBn05FrjRFGBQO1SUW/j L4qQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=XvmJazZo; 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 2adb3069b0e04-53687048f05si411235e87.139.2024.09.14.04.39.10; Sat, 14 Sep 2024 04:39:10 -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=@khirnov.net header.s=mail header.b=XvmJazZo; 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 7C5BC68DE92; Sat, 14 Sep 2024 14:11:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 49C8A68DDC8 for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=XvmJazZo; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 143DF4E20 for ; Sat, 14 Sep 2024 13:10:53 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id wvW3hJw82-m4 for ; Sat, 14 Sep 2024 13:10:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312246; bh=iTA5CmzCs+IaZzOPpMVFe2IBSwcS/+bVBoh/HjDHS20=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XvmJazZoKh0sqpegc1jJTYZSg3nygPqrJOSBWj3IFh+6bfr6lJBBObQCKD1Kn51dB q/A84uxXZLc8aWAXfDeAFFhHtP1uVAF/1xMjFSOsCWwstFPIYW1Kf8f+X46EHhntPb p+4fM5koOYs9krynmy7two0wBjpathLlt4M/Z74aHpr+n5YUGFczY2qL6XHRGXC0sk 4RMRlYXnmLHXxcjKwI0tZo4kw82HzOO5m4n3cPd5i5dzBAutZBe/QWGk/Fz2fs+N94 1z+twRpPSy4Dtfa39v9KeNEOvaxsFMfBnW+Bm3KwpT7StubG8vuq25+762L5l9Hw2t +n3RsB18yv1Hg== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id A15F54E27 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id DE6B13A25F9 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:47 +0200 Message-ID: <20240914111036.17164-23-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 22/23] tests/fate/hevc: add a test for switching between single and multi-view 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: pFM+nEpwue38 --- tests/fate/hevc.mak | 10 ++ tests/ref/fate/hevc-mv-switch | 172 ++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 tests/ref/fate/hevc-mv-switch diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index df827d821f..2511730edf 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -276,6 +276,16 @@ FATE_HEVC-$(call FRAMECRC, HEVC, HEVC) += fate-hevc-pir fate-hevc-mv-nuh-layer-id: CMD = framecrc -i $(TARGET_SAMPLES)/hevc/mv_nuh_layer_id.bit -map 0:view:all FATE_HEVC-$(call FRAMECRC, HEVC, HEVC) += fate-hevc-mv-nuh-layer-id +# NB: $\ at the end of line joins lines without adding whitespace; +# this trick is recommended by GNU make manual +fate-hevc-mv-switch: INPUT = \ +$(TARGET_SAMPLES)/hevc-conformance/LS_A_Orange_2.bit|$\ +$(TARGET_SAMPLES)/hevc/mv_nuh_layer_id.bit|$\ +$(TARGET_SAMPLES)/hevc-conformance/NoOutPrior_B_Qualcomm_1.bit|$\ +$(TARGET_SAMPLES)/hevc-conformance/MVHEVCS_A.bit +fate-hevc-mv-switch: CMD = framecrc -i "concat:$(INPUT)" -fps_mode passthrough -map 0:vidx:0 -map 0:vidx:1 +FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, CONCAT_PROTOCOL) += fate-hevc-mv-switch + FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) diff --git a/tests/ref/fate/hevc-mv-switch b/tests/ref/fate/hevc-mv-switch new file mode 100644 index 0000000000..0fc3630637 --- /dev/null +++ b/tests/ref/fate/hevc-mv-switch @@ -0,0 +1,172 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 416x240 +#sar 0: 0/1 +#tb 1: 1/25 +#media_type 1: video +#codec_id 1: rawvideo +#dimensions 1: 128x128 +#sar 1: 0/1 +0, 0, 0, 1, 149760, 0x94a51701 +0, 1, 1, 1, 149760, 0x67c71885 +0, 2, 2, 1, 149760, 0x218f1751 +0, 3, 3, 1, 149760, 0x56951bef +0, 4, 4, 1, 149760, 0x76aec81e +0, 5, 5, 1, 149760, 0x20df61ac +0, 6, 6, 1, 149760, 0x2eacf616 +0, 7, 7, 1, 149760, 0x06322ce2 +0, 8, 8, 1, 149760, 0xf14aa104 +0, 9, 9, 1, 149760, 0xc948dcba +1, 10, 10, 1, 24576, 0xf8f638da +0, 11, 11, 1, 149760, 0x674e34b1 +1, 12, 12, 1, 24576, 0xd22675a4 +0, 13, 13, 1, 149760, 0x41d3acd6 +1, 14, 14, 1, 24576, 0x60da42e6 +0, 15, 15, 1, 149760, 0x55a5b835 +1, 16, 16, 1, 24576, 0xe0577f6e +0, 17, 17, 1, 149760, 0xc6958049 +1, 18, 18, 1, 24576, 0x8d9944bd +0, 19, 19, 1, 149760, 0x94b37050 +0, 20, 20, 1, 149760, 0xed72a560 +0, 21, 21, 1, 149760, 0xd0ccac61 +0, 22, 22, 1, 149760, 0x6cc2d7fa +0, 23, 23, 1, 149760, 0x3a02b5ba +0, 24, 24, 1, 149760, 0xce7ef09c +0, 25, 25, 1, 149760, 0xa518fc05 +0, 26, 26, 1, 149760, 0x01d238fe +0, 27, 27, 1, 149760, 0x5f5012fa +0, 28, 28, 1, 149760, 0x5b8e7405 +0, 29, 29, 1, 149760, 0xcc2e5b33 +0, 30, 30, 1, 149760, 0x590a6890 +0, 31, 31, 1, 149760, 0x9c7b189f +0, 32, 32, 1, 149760, 0xd0752ef4 +0, 33, 33, 1, 149760, 0x367513ce +0, 34, 34, 1, 149760, 0xb64c209d +0, 35, 35, 1, 149760, 0x6e50994c +0, 36, 36, 1, 149760, 0x8276cce4 +0, 37, 37, 1, 149760, 0xb292ac8f +0, 38, 38, 1, 149760, 0x57de9d2c +0, 39, 39, 1, 149760, 0xe8533f38 +0, 40, 40, 1, 149760, 0xde9b536d +0, 41, 41, 1, 149760, 0x83173b1d +0, 42, 42, 1, 149760, 0x853a83a4 +0, 43, 43, 1, 149760, 0x481af1bf +0, 44, 44, 1, 149760, 0x27221abb +0, 45, 45, 1, 149760, 0x094eac00 +0, 46, 46, 1, 149760, 0x3f3a27c8 +0, 47, 47, 1, 149760, 0x8f19b2af +0, 48, 48, 1, 149760, 0x93e7e591 +0, 49, 49, 1, 149760, 0x0c531ab8 +0, 50, 50, 1, 149760, 0x3456ef8a +0, 51, 51, 1, 149760, 0xfee2ec1e +0, 52, 52, 1, 149760, 0x76b4b750 +0, 53, 53, 1, 149760, 0xa48bb670 +0, 54, 54, 1, 149760, 0x3dee7cac +0, 55, 55, 1, 149760, 0x2b20561d +0, 56, 56, 1, 149760, 0xd3c5bf9f +0, 57, 57, 1, 149760, 0x2e87d747 +0, 58, 58, 1, 149760, 0x9952760b +0, 59, 59, 1, 149760, 0xa3f5cbda +0, 60, 60, 1, 149760, 0x56e3f94d +0, 61, 61, 1, 149760, 0x902f743f +0, 62, 62, 1, 149760, 0xeffcfd85 +0, 63, 63, 1, 149760, 0xe7fc31b2 +0, 64, 64, 1, 149760, 0x2e876286 +0, 65, 65, 1, 149760, 0x6358b0b2 +0, 66, 66, 1, 149760, 0x3e569a4d +1, 67, 67, 1, 24576, 0xa18c481f +0, 68, 68, 1, 149760, 0x641cbce0 +1, 69, 69, 1, 24576, 0x9ee94df2 +0, 70, 70, 1, 149760, 0x0357d35c +1, 71, 71, 1, 24576, 0x60c55365 +0, 72, 72, 1, 149760, 0xe9b5b077 +1, 73, 73, 1, 24576, 0x8951536a +0, 74, 74, 1, 149760, 0x3b9c605f +1, 75, 75, 1, 24576, 0xfea04ba5 +0, 76, 76, 1, 149760, 0x16d7028b +1, 77, 77, 1, 24576, 0x78094226 +0, 78, 78, 1, 149760, 0xf4896eff +1, 79, 79, 1, 24576, 0xacf9314e +0, 80, 80, 1, 149760, 0xc90de4b9 +1, 81, 81, 1, 24576, 0x6a6b1c87 +0, 82, 82, 1, 149760, 0x2ec258ad +1, 83, 83, 1, 24576, 0x9f360661 +0, 84, 84, 1, 149760, 0x3bf720ef +1, 85, 85, 1, 24576, 0x52e80514 +0, 86, 86, 1, 149760, 0x67eab73f +1, 87, 87, 1, 24576, 0xe10df48c +0, 88, 88, 1, 149760, 0x020e17ce +1, 89, 89, 1, 24576, 0x71fbdd03 +0, 90, 90, 1, 149760, 0xcd677640 +1, 91, 91, 1, 24576, 0x1d08c3f6 +0, 92, 92, 1, 149760, 0x194cfbc1 +1, 93, 93, 1, 24576, 0x4b93b6ca +0, 94, 94, 1, 149760, 0x740f6261 +1, 95, 95, 1, 24576, 0x0dea9c12 +0, 96, 96, 1, 149760, 0x104b3175 +1, 97, 97, 1, 24576, 0x195a92da +0, 98, 98, 1, 149760, 0xc8fd17d1 +1, 99, 99, 1, 24576, 0x55dd870b +0, 100, 100, 1, 149760, 0x6f4e7787 +1, 101, 101, 1, 24576, 0x7e6b905b +0, 102, 102, 1, 149760, 0xe853418e +1, 103, 103, 1, 24576, 0x0f3fad1d +0, 104, 104, 1, 149760, 0x3dba3e4e +1, 105, 105, 1, 24576, 0xe724d536 +0, 106, 106, 1, 149760, 0xba0b4c38 +1, 107, 107, 1, 24576, 0xb212fed4 +0, 108, 108, 1, 149760, 0x28f8ef1d +1, 109, 109, 1, 24576, 0x3bb423ce +0, 110, 110, 1, 149760, 0xb5d92e4e +1, 111, 111, 1, 24576, 0x20f432db +0, 112, 112, 1, 149760, 0xbaa0d0a2 +1, 113, 113, 1, 24576, 0x27412981 +0, 114, 114, 1, 149760, 0x0acde200 +1, 115, 115, 1, 24576, 0xb7f70143 +0, 116, 116, 1, 149760, 0x7388aad3 +1, 117, 117, 1, 24576, 0xf31acffb +0, 118, 118, 1, 149760, 0xbac95723 +1, 119, 119, 1, 24576, 0x283d8c2c +0, 120, 120, 1, 149760, 0x7633d4af +1, 121, 121, 1, 24576, 0x9fb08184 +0, 122, 122, 1, 149760, 0x836e54fc +1, 123, 123, 1, 24576, 0x09696ad1 +0, 124, 124, 1, 149760, 0x49096e63 +1, 125, 125, 1, 24576, 0x034e69c2 +0, 126, 126, 1, 149760, 0x98e14158 +1, 127, 127, 1, 24576, 0x1ce4882c +0, 128, 128, 1, 149760, 0x955a43e4 +1, 129, 129, 1, 24576, 0x490fda13 +0, 130, 130, 1, 149760, 0x3a76c087 +1, 131, 131, 1, 24576, 0x4c2e1c09 +0, 132, 132, 1, 149760, 0xa221e763 +1, 133, 133, 1, 24576, 0x82dd5f8b +0, 134, 134, 1, 149760, 0x1eb33f17 +1, 135, 135, 1, 24576, 0xcfb07d6b +0, 136, 136, 1, 149760, 0x13ef3914 +1, 137, 137, 1, 24576, 0xef468129 +0, 138, 138, 1, 149760, 0x2521b880 +1, 139, 139, 1, 24576, 0x24c970fa +0, 140, 140, 1, 149760, 0x78a4faf0 +1, 141, 141, 1, 24576, 0x6df14e99 +0, 142, 142, 1, 149760, 0xc5f71d65 +1, 143, 143, 1, 24576, 0x78f44854 +0, 144, 144, 1, 149760, 0x5dbc0a9f +1, 145, 145, 1, 24576, 0x5a7269fd +0, 146, 146, 1, 149760, 0x8ebfd7c3 +1, 147, 147, 1, 24576, 0xb1fd8924 +0, 148, 148, 1, 149760, 0xb45f0581 +1, 149, 149, 1, 24576, 0xa165b829 +0, 150, 150, 1, 149760, 0x3b84540b +1, 151, 151, 1, 24576, 0x694cf0e5 +0, 152, 152, 1, 149760, 0xec921f35 +1, 153, 153, 1, 24576, 0x2fef157b +0, 154, 154, 1, 149760, 0x7b23826a +1, 155, 155, 1, 24576, 0x62ea25dd +0, 156, 156, 1, 149760, 0x518d1f11 +1, 157, 157, 1, 24576, 0xfc02365e +0, 158, 158, 1, 149760, 0xc5e694a4 +1, 159, 159, 1, 24576, 0x073b3ebd +0, 160, 160, 1, 149760, 0xeb79c961 +1, 161, 161, 1, 24576, 0x5ee13be2 From patchwork Sat Sep 14 10:45:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51602 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9fc3:0:b0:48e:c0f8:d0de with SMTP id k3csp380895vqy; Sat, 14 Sep 2024 07:19:11 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVYQyL/tIOH6qyQSIF8yoDtFBKi8udetoiyia5vOjayEJwdZGGVEvjM8AiJx2h6iotvPNMgg6F4R6C99inLXcE9@gmail.com X-Google-Smtp-Source: AGHT+IF45TeT5aMR8CmcMXYYZ0GvFdVkw/JjNQdbUAAWRI7svqOg5USinj29shJ0kNBnRjnrNrjz X-Received: by 2002:a17:907:e660:b0:a8a:9070:a6ed with SMTP id a640c23a62f3a-a902949a1ccmr1022873066b.31.1726323550936; Sat, 14 Sep 2024 07:19:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726323550; cv=none; d=google.com; s=arc-20240605; b=T91j7tu6eJgIcUl2hhiXydO4+FN0Z7RX5pFSMJugh0UKdtKFgWrf7+dZAXNXklB2c9 BlYc4fbW/SIXSeVqp+T2WecmQAQw2wDXlwgA297iK7cYtdHsgxvKcTRZDDAWdlbDYKgG a7ZfU6x/TmE2Uqh/rRIqfgiZuFgEP+n7GEesDKPbsaxtIiBYeehFbjZVRhUTlMP6ZnXC Fd/NvGZ6h6ek65JLA9l/hPBAISA6YZzCy51YiqhKErmmihzFciFQ7SG7zQSIGqaBcBqU RANol0t+ZIGuaXozBUURQmiKtY2BsCfxaNRw+h5WS/3Fnf+OrSjTYjOmtMF7TEl78HoS mOWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=c89bMGGO6RZRw282xbRKv+NQqnwOLNlmioCajU6stR4=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=RdnfnkRJV0rukCUsOVoIXkoi1csn/xHQ2rAcLuO3H+WCgafPKx8GJmgF/kBTD6+5bI 64NkYYXYLTNXTnP6zHTjxYsQHU5q+Gko2dFJUxe5RGnCEk12az0uMXSmtB4YDDZIiLje Mmepa6oMvH6EIDm2j7YjbJyTaO9MpS3fMOttG/c4cGSTAi7pVjf6bjLukmqWYRmuaje9 yUI9Cuq3iKaZB00JTh6B2WyGFr6H7r4TduMz3z3Yrnx337QJXcGXzVcZin8Cc/oy2Ky8 FNHCJia3tgJI/utx95IDuU9FzcYO3QWfP77Ir7tvjxoWYUr7GdH1biQru0H65fRoz/XE dsSQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=EiLKriQe; 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 a640c23a62f3a-a90612efa5fsi105777066b.657.2024.09.14.07.19.10; Sat, 14 Sep 2024 07:19:10 -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=@khirnov.net header.s=mail header.b=EiLKriQe; 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 D75D868DE71; Sat, 14 Sep 2024 14:11:11 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 159A668DDBB for ; Sat, 14 Sep 2024 14:10:54 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=EiLKriQe; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 54E454E16 for ; Sat, 14 Sep 2024 13:10:53 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id oijdhZJwwxys for ; Sat, 14 Sep 2024 13:10:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1726312247; bh=7rbi1Vr960OASknGeaZaeaZO0NBR2VqoMCtpKLRbmFs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=EiLKriQeKemyJt8H1jcRGLGyseo4nFm9e4h7J7DZPlLwSbzqZahWTnQTKV0z8pYse 7bFqP2BjrFopUnGDtUMJOSVI5lJniJczJIX+Mn+ka4YddpBaoG9zZ4uKs+IoByIriR cPVbI219Vk+dju14d6WzeQJjN8SC06iBU//OylQsImIV+ADKVntzuhZXvAzDeWPYVU Qaod4m9NQIuFEnf0KHAh733yFlP7TiVQ5w4WAuz5dZzeBuTSYlyfH8K8EWG71u0+Zj mqmXRSpiHm4otM4eiLveIYwZ8EBJM+teG8ZCa9VX7kIDAqjoci8K/xSbL/A1C0Z7Kn ZI8lefxm7fu0A== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id A29FB4E29 for ; Sat, 14 Sep 2024 13:10:46 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id E9FC63A2668 for ; Sat, 14 Sep 2024 13:10:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 14 Sep 2024 12:45:48 +0200 Message-ID: <20240914111036.17164-24-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240914111036.17164-1-anton@khirnov.net> References: <20240914111036.17164-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 23/23] tests/fate/hevc: add a test for selecting view by position 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: pJA5aVsxEmnc Using a real-world iPhone-recorded file. --- tests/fate/hevc.mak | 5 +++++ tests/ref/fate/hevc-mv-position | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/ref/fate/hevc-mv-position diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak index 2511730edf..6d8865ea66 100644 --- a/tests/fate/hevc.mak +++ b/tests/fate/hevc.mak @@ -286,6 +286,11 @@ $(TARGET_SAMPLES)/hevc-conformance/MVHEVCS_A.bit fate-hevc-mv-switch: CMD = framecrc -i "concat:$(INPUT)" -fps_mode passthrough -map 0:vidx:0 -map 0:vidx:1 FATE_HEVC-$(call FRAMECRC, HEVC, HEVC, CONCAT_PROTOCOL) += fate-hevc-mv-switch +# multiview stream, select view by position +# (depends on Three Dimensional Reference Displays Information SEI) +fate-hevc-mv-position: CMD = framecrc -i $(TARGET_SAMPLES)/hevc/multiview.mov -map 0:v:vpos:left -map 0:v:vpos:right +FATE_HEVC-$(call FRAMECRC, MOV, HEVC) += fate-hevc-mv-position + FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes) FATE_SAMPLES_FFPROBE += $(FATE_HEVC_FFPROBE-yes) diff --git a/tests/ref/fate/hevc-mv-position b/tests/ref/fate/hevc-mv-position new file mode 100644 index 0000000000..660789557c --- /dev/null +++ b/tests/ref/fate/hevc-mv-position @@ -0,0 +1,32 @@ +#tb 0: 1/30 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 1920x1080 +#sar 0: 0/1 +#tb 1: 1/30 +#media_type 1: video +#codec_id 1: rawvideo +#dimensions 1: 1920x1080 +#sar 1: 0/1 +0, 0, 0, 1, 3110400, 0xd0ce90de +1, 0, 0, 1, 3110400, 0x1859a3ba +0, 1, 1, 1, 3110400, 0x5ce1bc1a +1, 1, 1, 1, 3110400, 0x43cf57e5 +0, 2, 2, 1, 3110400, 0x14cf9f7f +1, 2, 2, 1, 3110400, 0x4ffc98ea +0, 3, 3, 1, 3110400, 0x9a6bb93c +1, 3, 3, 1, 3110400, 0x96a2bcfb +0, 4, 4, 1, 3110400, 0x69e5377d +1, 4, 4, 1, 3110400, 0xec4561f0 +0, 5, 5, 1, 3110400, 0x66b3bd5d +1, 5, 5, 1, 3110400, 0x633f23f5 +0, 6, 6, 1, 3110400, 0x83a2ada2 +1, 6, 6, 1, 3110400, 0xe10a2fe7 +0, 7, 7, 1, 3110400, 0x503bbe42 +1, 7, 7, 1, 3110400, 0x8ecd5c39 +0, 8, 8, 1, 3110400, 0xaeb27981 +1, 8, 8, 1, 3110400, 0xe571a478 +0, 9, 9, 1, 3110400, 0xbe14bf1e +1, 9, 9, 1, 3110400, 0x87d4dbe3 +0, 10, 10, 1, 3110400, 0xbd329d79 +1, 10, 10, 1, 3110400, 0xc78097f4