diff options
author | Moonchild <mcwerewolf@gmail.com> | 2018-10-02 00:21:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-02 00:21:32 +0200 |
commit | 69d83c8fbe47b89d1d14f75ee99e638cbfb5dc31 (patch) | |
tree | ce4b486ac8e13e1f5a8a918e532826c3ae09415d /media/ffvpx/libavutil | |
parent | 8e8fcee4a55de171303ebe526d3cf051522111bf (diff) | |
parent | 41ccd52bfd7f3604d3ad3917af5f030994e13762 (diff) | |
download | UXP-69d83c8fbe47b89d1d14f75ee99e638cbfb5dc31.tar UXP-69d83c8fbe47b89d1d14f75ee99e638cbfb5dc31.tar.gz UXP-69d83c8fbe47b89d1d14f75ee99e638cbfb5dc31.tar.lz UXP-69d83c8fbe47b89d1d14f75ee99e638cbfb5dc31.tar.xz UXP-69d83c8fbe47b89d1d14f75ee99e638cbfb5dc31.zip |
Merge pull request #806 from trav90/ffvpx-resync
Update ffvpx code to 4.0.2 (take 2)
Diffstat (limited to 'media/ffvpx/libavutil')
46 files changed, 1753 insertions, 743 deletions
diff --git a/media/ffvpx/libavutil/atomic.c b/media/ffvpx/libavutil/atomic.c deleted file mode 100644 index 64cff2576..000000000 --- a/media/ffvpx/libavutil/atomic.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "atomic.h" - -#if !HAVE_ATOMICS_NATIVE - -#if HAVE_PTHREADS - -#include <pthread.h> - -static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER; - -int avpriv_atomic_int_get(volatile int *ptr) -{ - int res; - - pthread_mutex_lock(&atomic_lock); - res = *ptr; - pthread_mutex_unlock(&atomic_lock); - - return res; -} - -void avpriv_atomic_int_set(volatile int *ptr, int val) -{ - pthread_mutex_lock(&atomic_lock); - *ptr = val; - pthread_mutex_unlock(&atomic_lock); -} - -int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc) -{ - int res; - - pthread_mutex_lock(&atomic_lock); - *ptr += inc; - res = *ptr; - pthread_mutex_unlock(&atomic_lock); - - return res; -} - -void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval) -{ - void *ret; - pthread_mutex_lock(&atomic_lock); - ret = *ptr; - if (ret == oldval) - *ptr = newval; - pthread_mutex_unlock(&atomic_lock); - return ret; -} - -#elif !HAVE_THREADS - -int avpriv_atomic_int_get(volatile int *ptr) -{ - return *ptr; -} - -void avpriv_atomic_int_set(volatile int *ptr, int val) -{ - *ptr = val; -} - -int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc) -{ - *ptr += inc; - return *ptr; -} - -void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval) -{ - if (*ptr == oldval) { - *ptr = newval; - return oldval; - } - return *ptr; -} - -#else /* HAVE_THREADS */ - -/* This should never trigger, unless a new threading implementation - * without correct atomics dependencies in configure or a corresponding - * atomics implementation is added. */ -#error "Threading is enabled, but there is no implementation of atomic operations available" - -#endif /* HAVE_PTHREADS */ - -#endif /* !HAVE_ATOMICS_NATIVE */ diff --git a/media/ffvpx/libavutil/atomic.h b/media/ffvpx/libavutil/atomic.h deleted file mode 100644 index 15906d24c..000000000 --- a/media/ffvpx/libavutil/atomic.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com> - * - * 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 AVUTIL_ATOMIC_H -#define AVUTIL_ATOMIC_H - -#include "config.h" - -#if HAVE_ATOMICS_NATIVE - -#if HAVE_ATOMICS_GCC -#include "atomic_gcc.h" -#elif HAVE_ATOMICS_WIN32 -#include "atomic_win32.h" -#elif HAVE_ATOMICS_SUNCC -#include "atomic_suncc.h" -#endif - -#else - -/** - * Load the current value stored in an atomic integer. - * - * @param ptr atomic integer - * @return the current value of the atomic integer - * @note This acts as a memory barrier. - */ -int avpriv_atomic_int_get(volatile int *ptr); - -/** - * Store a new value in an atomic integer. - * - * @param ptr atomic integer - * @param val the value to store in the atomic integer - * @note This acts as a memory barrier. - */ -void avpriv_atomic_int_set(volatile int *ptr, int val); - -/** - * Add a value to an atomic integer. - * - * @param ptr atomic integer - * @param inc the value to add to the atomic integer (may be negative) - * @return the new value of the atomic integer. - * @note This does NOT act as a memory barrier. This is primarily - * intended for reference counting. - */ -int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc); - -/** - * Atomic pointer compare and swap. - * - * @param ptr pointer to the pointer to operate on - * @param oldval do the swap if the current value of *ptr equals to oldval - * @param newval value to replace *ptr with - * @return the value of *ptr before comparison - */ -void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval); - -#endif /* HAVE_ATOMICS_NATIVE */ - -#endif /* AVUTIL_ATOMIC_H */ diff --git a/media/ffvpx/libavutil/atomic_gcc.h b/media/ffvpx/libavutil/atomic_gcc.h deleted file mode 100644 index 2bb43c3ce..000000000 --- a/media/ffvpx/libavutil/atomic_gcc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com> - * - * 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 AVUTIL_ATOMIC_GCC_H -#define AVUTIL_ATOMIC_GCC_H - -#include <stdint.h> - -#include "atomic.h" - -#define avpriv_atomic_int_get atomic_int_get_gcc -static inline int atomic_int_get_gcc(volatile int *ptr) -{ - __sync_synchronize(); - return *ptr; -} - -#define avpriv_atomic_int_set atomic_int_set_gcc -static inline void atomic_int_set_gcc(volatile int *ptr, int val) -{ - *ptr = val; - __sync_synchronize(); -} - -#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_gcc -static inline int atomic_int_add_and_fetch_gcc(volatile int *ptr, int inc) -{ - return __sync_add_and_fetch(ptr, inc); -} - -#define avpriv_atomic_ptr_cas atomic_ptr_cas_gcc -static inline void *atomic_ptr_cas_gcc(void * volatile *ptr, - void *oldval, void *newval) -{ -#ifdef __ARMCC_VERSION - // armcc will throw an error if ptr is not an integer type - volatile uintptr_t *tmp = (volatile uintptr_t*)ptr; - return (void*)__sync_val_compare_and_swap(tmp, oldval, newval); -#else - return __sync_val_compare_and_swap(ptr, oldval, newval); -#endif -} - -#endif /* AVUTIL_ATOMIC_GCC_H */ diff --git a/media/ffvpx/libavutil/atomic_win32.h b/media/ffvpx/libavutil/atomic_win32.h deleted file mode 100644 index f7299336f..000000000 --- a/media/ffvpx/libavutil/atomic_win32.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com> - * - * 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 AVUTIL_ATOMIC_WIN32_H -#define AVUTIL_ATOMIC_WIN32_H - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -#define avpriv_atomic_int_get atomic_int_get_win32 -static inline int atomic_int_get_win32(volatile int *ptr) -{ - MemoryBarrier(); - return *ptr; -} - -#define avpriv_atomic_int_set atomic_int_set_win32 -static inline void atomic_int_set_win32(volatile int *ptr, int val) -{ - *ptr = val; - MemoryBarrier(); -} - -#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_win32 -static inline int atomic_int_add_and_fetch_win32(volatile int *ptr, int inc) -{ - return inc + InterlockedExchangeAdd(ptr, inc); -} - -#define avpriv_atomic_ptr_cas atomic_ptr_cas_win32 -static inline void *atomic_ptr_cas_win32(void * volatile *ptr, - void *oldval, void *newval) -{ - return InterlockedCompareExchangePointer(ptr, newval, oldval); -} - -#endif /* AVUTIL_ATOMIC_WIN32_H */ diff --git a/media/ffvpx/libavutil/attributes.h b/media/ffvpx/libavutil/attributes.h index 54d190111..ced108aa2 100644 --- a/media/ffvpx/libavutil/attributes.h +++ b/media/ffvpx/libavutil/attributes.h @@ -66,19 +66,19 @@ # define av_noinline #endif -#if AV_GCC_VERSION_AT_LEAST(3,1) +#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) # define av_pure __attribute__((pure)) #else # define av_pure #endif -#if AV_GCC_VERSION_AT_LEAST(2,6) +#if AV_GCC_VERSION_AT_LEAST(2,6) || defined(__clang__) # define av_const __attribute__((const)) #else # define av_const #endif -#if AV_GCC_VERSION_AT_LEAST(4,3) +#if AV_GCC_VERSION_AT_LEAST(4,3) || defined(__clang__) # define av_cold __attribute__((cold)) #else # define av_cold @@ -138,19 +138,19 @@ # define av_used #endif -#if AV_GCC_VERSION_AT_LEAST(3,3) +#if AV_GCC_VERSION_AT_LEAST(3,3) || defined(__clang__) # define av_alias __attribute__((may_alias)) #else # define av_alias #endif -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER) # define av_uninit(x) x=x #else # define av_uninit(x) x #endif -#ifdef __GNUC__ +#if defined(__GNUC__) || defined(__clang__) # define av_builtin_constant_p __builtin_constant_p # define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos))) #else @@ -158,7 +158,7 @@ # define av_printf_format(fmtpos, attrpos) #endif -#if AV_GCC_VERSION_AT_LEAST(2,5) +#if AV_GCC_VERSION_AT_LEAST(2,5) || defined(__clang__) # define av_noreturn __attribute__((noreturn)) #else # define av_noreturn diff --git a/media/ffvpx/libavutil/avutil.symbols b/media/ffvpx/libavutil/avutil.symbols index ba68dc33c..ede2ff9ac 100644 --- a/media/ffvpx/libavutil/avutil.symbols +++ b/media/ffvpx/libavutil/avutil.symbols @@ -1,10 +1,7 @@ av_add_q av_add_stable -av_adler32_update av_append_path_component av_asprintf -av_base64_decode -av_base64_encode av_basename av_bprint_append_data av_bprint_channel_layout @@ -177,8 +174,10 @@ av_image_get_buffer_size av_image_get_linesize av_int_list_length_for_size av_log +#ifndef MOZ_FFVPX_FLACONLY av_log2 av_log2_16bit +#endif av_log_default_callback av_log_format_line av_log_get_flags @@ -257,7 +256,6 @@ av_pix_fmt_desc_get_id av_pix_fmt_desc_next av_pix_fmt_get_chroma_sub_sample av_pix_fmt_swap_endianness -av_pixelutils_get_sad_fn av_q2intfloat av_read_image_line av_realloc @@ -296,20 +294,6 @@ av_strstart av_strtod av_strtok av_sub_q -av_thread_message_queue_alloc -av_thread_message_queue_free -av_thread_message_queue_recv -av_thread_message_queue_send -av_thread_message_queue_set_err_recv -av_thread_message_queue_set_err_send -av_timecode_adjust_ntsc_framenum2 -av_timecode_check_frame_rate -av_timecode_get_smpte_from_framenum -av_timecode_init -av_timecode_init_from_string -av_timecode_make_mpeg_tc_string -av_timecode_make_smpte_tc_string -av_timecode_make_string av_timegm av_usleep av_utf8_decode @@ -320,14 +304,10 @@ av_vlog av_write_image_line avpriv_alloc_fixed_dsp avpriv_float_dsp_alloc -avpriv_frame_get_metadatap -avpriv_get_gamma_from_trc -avpriv_init_lls avpriv_report_missing_feature avpriv_request_sample avpriv_scalarproduct_float_c avpriv_set_systematic_pal2 -avpriv_solve_lls avutil_configuration avutil_license avutil_version @@ -337,3 +317,8 @@ avpriv_emms_asm avpriv_slicethread_create avpriv_slicethread_execute avpriv_slicethread_free +av_hwdevice_get_type_name +av_hwframe_ctx_alloc +av_hwframe_ctx_init +av_malloc_array +av_mallocz_array diff --git a/media/ffvpx/libavutil/common.h b/media/ffvpx/libavutil/common.h index 8142b31fd..8db029117 100644 --- a/media/ffvpx/libavutil/common.h +++ b/media/ffvpx/libavutil/common.h @@ -158,7 +158,7 @@ static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, in */ static av_always_inline av_const uint8_t av_clip_uint8_c(int a) { - if (a&(~0xFF)) return (-a)>>31; + if (a&(~0xFF)) return (~a)>>31; else return a; } @@ -180,7 +180,7 @@ static av_always_inline av_const int8_t av_clip_int8_c(int a) */ static av_always_inline av_const uint16_t av_clip_uint16_c(int a) { - if (a&(~0xFFFF)) return (-a)>>31; + if (a&(~0xFFFF)) return (~a)>>31; else return a; } @@ -228,7 +228,7 @@ static av_always_inline av_const int av_clip_intp2_c(int a, int p) */ static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) { - if (a & ~((1<<p) - 1)) return -a >> 31 & ((1<<p) - 1); + if (a & ~((1<<p) - 1)) return (~a) >> 31 & ((1<<p) - 1); else return a; } @@ -260,7 +260,7 @@ static av_always_inline int av_sat_add32_c(int a, int b) * * @param a first value * @param b value doubled and added to a - * @return sum with signed saturation + * @return sum sat(a + sat(2*b)) with signed saturation */ static av_always_inline int av_sat_dadd32_c(int a, int b) { @@ -268,6 +268,30 @@ static av_always_inline int av_sat_dadd32_c(int a, int b) } /** + * Subtract two signed 32-bit values with saturation. + * + * @param a one value + * @param b another value + * @return difference with signed saturation + */ +static av_always_inline int av_sat_sub32_c(int a, int b) +{ + return av_clipl_int32((int64_t)a - b); +} + +/** + * Subtract a doubled value from another value with saturation at both stages. + * + * @param a first value + * @param b value doubled and subtracted from a + * @return difference sat(a - sat(2*b)) with signed saturation + */ +static av_always_inline int av_sat_dsub32_c(int a, int b) +{ + return av_sat_sub32(a, av_sat_add32(b, b)); +} + +/** * Clip a float value into the amin-amax range. * @param a value to clip * @param amin minimum value of the clip range @@ -513,6 +537,12 @@ static av_always_inline av_const int av_parity_c(uint32_t v) #ifndef av_sat_dadd32 # define av_sat_dadd32 av_sat_dadd32_c #endif +#ifndef av_sat_sub32 +# define av_sat_sub32 av_sat_sub32_c +#endif +#ifndef av_sat_dsub32 +# define av_sat_dsub32 av_sat_dsub32_c +#endif #ifndef av_clipf # define av_clipf av_clipf_c #endif diff --git a/media/ffvpx/libavutil/cpu.c b/media/ffvpx/libavutil/cpu.c index c8401b825..6548cc304 100644 --- a/media/ffvpx/libavutil/cpu.c +++ b/media/ffvpx/libavutil/cpu.c @@ -80,7 +80,8 @@ void av_force_cpu_flags(int arg){ AV_CPU_FLAG_XOP | AV_CPU_FLAG_FMA3 | AV_CPU_FLAG_FMA4 | - AV_CPU_FLAG_AVX2 )) + AV_CPU_FLAG_AVX2 | + AV_CPU_FLAG_AVX512 )) && !(arg & AV_CPU_FLAG_MMX)) { av_log(NULL, AV_LOG_WARNING, "MMX implied by specified flags\n"); arg |= AV_CPU_FLAG_MMX; @@ -126,6 +127,7 @@ int av_parse_cpu_flags(const char *s) #define CPUFLAG_AVX2 (AV_CPU_FLAG_AVX2 | CPUFLAG_AVX) #define CPUFLAG_BMI2 (AV_CPU_FLAG_BMI2 | AV_CPU_FLAG_BMI1) #define CPUFLAG_AESNI (AV_CPU_FLAG_AESNI | CPUFLAG_SSE42) +#define CPUFLAG_AVX512 (AV_CPU_FLAG_AVX512 | CPUFLAG_AVX2) static const AVOption cpuflags_opts[] = { { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, #if ARCH_PPC @@ -154,6 +156,7 @@ int av_parse_cpu_flags(const char *s) { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOWEXT }, .unit = "flags" }, { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" }, { "aesni" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AESNI }, .unit = "flags" }, + { "avx512" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX512 }, .unit = "flags" }, #elif ARCH_ARM { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV5TE }, .unit = "flags" }, { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" }, @@ -216,6 +219,7 @@ int av_parse_cpu_caps(unsigned *flags, const char *s) { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOWEXT }, .unit = "flags" }, { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" }, { "aesni", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AESNI }, .unit = "flags" }, + { "avx512" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX512 }, .unit = "flags" }, #define CPU_FLAG_P2 AV_CPU_FLAG_CMOV | AV_CPU_FLAG_MMX #define CPU_FLAG_P3 CPU_FLAG_P2 | AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE diff --git a/media/ffvpx/libavutil/cpu.h b/media/ffvpx/libavutil/cpu.h index 9e5d40aff..8bb9eb606 100644 --- a/media/ffvpx/libavutil/cpu.h +++ b/media/ffvpx/libavutil/cpu.h @@ -55,6 +55,7 @@ #define AV_CPU_FLAG_FMA3 0x10000 ///< Haswell FMA3 functions #define AV_CPU_FLAG_BMI1 0x20000 ///< Bit Manipulation Instruction Set 1 #define AV_CPU_FLAG_BMI2 0x40000 ///< Bit Manipulation Instruction Set 2 +#define AV_CPU_FLAG_AVX512 0x100000 ///< AVX-512 functions: requires OS support even if YMM/ZMM registers aren't used #define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard #define AV_CPU_FLAG_VSX 0x0002 ///< ISA 2.06 diff --git a/media/ffvpx/libavutil/cpu_internal.h b/media/ffvpx/libavutil/cpu_internal.h index b8bf1e539..37122d1c5 100644 --- a/media/ffvpx/libavutil/cpu_internal.h +++ b/media/ffvpx/libavutil/cpu_internal.h @@ -19,6 +19,8 @@ #ifndef AVUTIL_CPU_INTERNAL_H #define AVUTIL_CPU_INTERNAL_H +#include "config.h" + #include "cpu.h" #define CPUEXT_SUFFIX(flags, suffix, cpuext) \ diff --git a/media/ffvpx/libavutil/crc.c b/media/ffvpx/libavutil/crc.c index 495732b16..c45ea63a6 100644 --- a/media/ffvpx/libavutil/crc.c +++ b/media/ffvpx/libavutil/crc.c @@ -20,6 +20,8 @@ #include "config.h" +#include "thread.h" +#include "avassert.h" #include "bswap.h" #include "common.h" #include "crc.h" @@ -50,6 +52,30 @@ static const AVCRC av_crc_table[AV_CRC_MAX][257] = { 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3, 0x01 }, + [AV_CRC_8_EBU] = { + 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, + 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, + 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0, + 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, + 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, + 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, + 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, + 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, + 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, + 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, + 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, + 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, + 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, + 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, + 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, + 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, + 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, + 0xA9, 0xB4, 0x93, 0x8E, 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, + 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95, + 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, + 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, + 0xE3, 0xFE, 0xD9, 0xC4, 0x01 + }, [AV_CRC_16_ANSI] = { 0x0000, 0x0580, 0x0F80, 0x0A00, 0x1B80, 0x1E00, 0x1400, 0x1180, 0x3380, 0x3600, 0x3C00, 0x3980, 0x2800, 0x2D80, 0x2780, 0x2200, @@ -291,20 +317,25 @@ static const AVCRC av_crc_table[AV_CRC_MAX][257] = { #else #define CRC_TABLE_SIZE 1024 #endif -static struct { - uint8_t le; - uint8_t bits; - uint32_t poly; -} av_crc_table_params[AV_CRC_MAX] = { - [AV_CRC_8_ATM] = { 0, 8, 0x07 }, - [AV_CRC_16_ANSI] = { 0, 16, 0x8005 }, - [AV_CRC_16_CCITT] = { 0, 16, 0x1021 }, - [AV_CRC_24_IEEE] = { 0, 24, 0x864CFB }, - [AV_CRC_32_IEEE] = { 0, 32, 0x04C11DB7 }, - [AV_CRC_32_IEEE_LE] = { 1, 32, 0xEDB88320 }, - [AV_CRC_16_ANSI_LE] = { 1, 16, 0xA001 }, -}; static AVCRC av_crc_table[AV_CRC_MAX][CRC_TABLE_SIZE]; + +#define DECLARE_CRC_INIT_TABLE_ONCE(id, le, bits, poly) \ +static AVOnce id ## _once_control = AV_ONCE_INIT; \ +static void id ## _init_table_once(void) \ +{ \ + av_assert0(av_crc_init(av_crc_table[id], le, bits, poly, sizeof(av_crc_table[id])) >= 0); \ +} + +#define CRC_INIT_TABLE_ONCE(id) ff_thread_once(&id ## _once_control, id ## _init_table_once) + +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_8_ATM, 0, 8, 0x07) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_8_EBU, 0, 8, 0x1D) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI, 0, 16, 0x8005) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_CCITT, 0, 16, 0x1021) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_24_IEEE, 0, 24, 0x864CFB) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE, 0, 32, 0x04C11DB7) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE_LE, 1, 32, 0xEDB88320) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI_LE, 1, 16, 0xA001) #endif int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size) @@ -343,13 +374,17 @@ int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size) const AVCRC *av_crc_get_table(AVCRCId crc_id) { #if !CONFIG_HARDCODED_TABLES - if (!av_crc_table[crc_id][FF_ARRAY_ELEMS(av_crc_table[crc_id]) - 1]) - if (av_crc_init(av_crc_table[crc_id], - av_crc_table_params[crc_id].le, - av_crc_table_params[crc_id].bits, - av_crc_table_params[crc_id].poly, - sizeof(av_crc_table[crc_id])) < 0) - return NULL; + switch (crc_id) { + case AV_CRC_8_ATM: CRC_INIT_TABLE_ONCE(AV_CRC_8_ATM); break; + case AV_CRC_8_EBU: CRC_INIT_TABLE_ONCE(AV_CRC_8_EBU); break; + case AV_CRC_16_ANSI: CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI); break; + case AV_CRC_16_CCITT: CRC_INIT_TABLE_ONCE(AV_CRC_16_CCITT); break; + case AV_CRC_24_IEEE: CRC_INIT_TABLE_ONCE(AV_CRC_24_IEEE); break; + case AV_CRC_32_IEEE: CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE); break; + case AV_CRC_32_IEEE_LE: CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE_LE); break; + case AV_CRC_16_ANSI_LE: CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI_LE); break; + default: av_assert0(0); + } #endif return av_crc_table[crc_id]; } diff --git a/media/ffvpx/libavutil/crc.h b/media/ffvpx/libavutil/crc.h index 2a1b0d762..47e22b4c7 100644 --- a/media/ffvpx/libavutil/crc.h +++ b/media/ffvpx/libavutil/crc.h @@ -53,11 +53,8 @@ typedef enum { AV_CRC_32_IEEE, AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */ AV_CRC_16_ANSI_LE, /*< reversed bitorder version of AV_CRC_16_ANSI */ -#if FF_API_CRC_BIG_TABLE - AV_CRC_24_IEEE = 12, -#else AV_CRC_24_IEEE, -#endif /* FF_API_CRC_BIG_TABLE */ + AV_CRC_8_EBU, AV_CRC_MAX, /*< Not part of public API! Do not use outside libavutil. */ }AVCRCId; diff --git a/media/ffvpx/libavutil/dummy_funcs.c b/media/ffvpx/libavutil/dummy_funcs.c index 3a2381074..5d1cdc819 100644 --- a/media/ffvpx/libavutil/dummy_funcs.c +++ b/media/ffvpx/libavutil/dummy_funcs.c @@ -5,22 +5,27 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "avutil.h" +#include "hwcontext.h" // cpu_internal.c int ff_get_cpu_flags_aarch64(void) { return 0; } +#if !defined(__arm__) int ff_get_cpu_flags_arm(void) { return 0; } +#endif int ff_get_cpu_flags_ppc(void) { return 0; } // float_dsp.c #include "float_dsp.h" void ff_float_dsp_init_aarch64(AVFloatDSPContext *fdsp) {} -void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp) {} void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int strict) {} void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp) {} - -int av_hwframe_get_buffer(struct AVBufferRef* hwframe_ref, struct AVFrame* frame, int flags) { return 0; } +#if !defined(__arm__) +void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp) {} +#endif // cpu.c size_t ff_get_cpu_max_align_aarch64() { return 0; } -size_t ff_get_cpu_max_align_arm() { return 0; } size_t ff_get_cpu_max_align_ppc() { return 0; } +#if !defined(__arm__) +size_t ff_get_cpu_max_align_arm() { return 0; } +#endif diff --git a/media/ffvpx/libavutil/eval.c b/media/ffvpx/libavutil/eval.c index e5948793b..efed91b6e 100644 --- a/media/ffvpx/libavutil/eval.c +++ b/media/ffvpx/libavutil/eval.c @@ -57,7 +57,14 @@ typedef struct Parser { double *var; } Parser; -static const AVClass eval_class = { "Eval", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(Parser,log_offset), offsetof(Parser,log_ctx) }; +static const AVClass eval_class = { + .class_name = "Eval", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(Parser, log_offset), + .parent_log_context_offset = offsetof(Parser, log_ctx), +}; static const struct { double bin_val; diff --git a/media/ffvpx/libavutil/ffversion.h b/media/ffvpx/libavutil/ffversion.h index 3da2a6bf1..9b533e039 100644 --- a/media/ffvpx/libavutil/ffversion.h +++ b/media/ffvpx/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "n3.4.2" +#define FFMPEG_VERSION "n4.0.2" #endif /* AVUTIL_FFVERSION_H */ diff --git a/media/ffvpx/libavutil/frame.c b/media/ffvpx/libavutil/frame.c index d5fd2932e..00215ac29 100644 --- a/media/ffvpx/libavutil/frame.c +++ b/media/ffvpx/libavutil/frame.c @@ -26,11 +26,7 @@ #include "mem.h" #include "samplefmt.h" - -static AVFrameSideData *frame_new_side_data(AVFrame *frame, - enum AVFrameSideDataType type, - AVBufferRef *buf); - +#if FF_API_FRAME_GET_SET MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp) MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_duration) MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_pos) @@ -42,41 +38,84 @@ MAKE_ACCESSORS(AVFrame, frame, int, decode_error_flags) MAKE_ACCESSORS(AVFrame, frame, int, pkt_size) MAKE_ACCESSORS(AVFrame, frame, enum AVColorSpace, colorspace) MAKE_ACCESSORS(AVFrame, frame, enum AVColorRange, color_range) +#endif #define CHECK_CHANNELS_CONSISTENCY(frame) \ av_assert2(!(frame)->channel_layout || \ (frame)->channels == \ av_get_channel_layout_nb_channels((frame)->channel_layout)) -AVDictionary **avpriv_frame_get_metadatap(AVFrame *frame) {return &frame->metadata;}; - #if FF_API_FRAME_QP +struct qp_properties { + int stride; + int type; +}; + int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type) { + struct qp_properties *p; + AVFrameSideData *sd; + AVBufferRef *ref; + +FF_DISABLE_DEPRECATION_WARNINGS av_buffer_unref(&f->qp_table_buf); f->qp_table_buf = buf; - -FF_DISABLE_DEPRECATION_WARNINGS f->qscale_table = buf->data; f->qstride = stride; f->qscale_type = qp_type; FF_ENABLE_DEPRECATION_WARNINGS + av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES); + av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE_DATA); + + ref = av_buffer_ref(buf); + if (!av_frame_new_side_data_from_buf(f, AV_FRAME_DATA_QP_TABLE_DATA, ref)) { + av_buffer_unref(&ref); + return AVERROR(ENOMEM); + } + + sd = av_frame_new_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES, + sizeof(struct qp_properties)); + if (!sd) + return AVERROR(ENOMEM); + + p = (struct qp_properties *)sd->data; + p->stride = stride; + p->type = qp_type; + return 0; } int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type) { + AVBufferRef *buf = NULL; + + *stride = 0; + *type = 0; + FF_DISABLE_DEPRECATION_WARNINGS - *stride = f->qstride; - *type = f->qscale_type; + if (f->qp_table_buf) { + *stride = f->qstride; + *type = f->qscale_type; + buf = f->qp_table_buf; FF_ENABLE_DEPRECATION_WARNINGS + } else { + AVFrameSideData *sd; + struct qp_properties *p; + sd = av_frame_get_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES); + if (!sd) + return NULL; + p = (struct qp_properties *)sd->data; + sd = av_frame_get_side_data(f, AV_FRAME_DATA_QP_TABLE_DATA); + if (!sd) + return NULL; + *stride = p->stride; + *type = p->type; + buf = sd->buf; + } - if (!f->qp_table_buf) - return NULL; - - return f->qp_table_buf->data; + return buf ? buf->data : NULL; } #endif @@ -208,7 +247,7 @@ static int get_video_buffer(AVFrame *frame, int align) frame->data[i] = frame->buf[i]->data; } - if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & FF_PSEUDOPAL) { av_buffer_unref(&frame->buf[1]); frame->buf[1] = av_buffer_alloc(AVPALETTE_SIZE); if (!frame->buf[1]) @@ -356,8 +395,10 @@ FF_ENABLE_DEPRECATION_WARNINGS } memcpy(sd_dst->data, sd_src->data, sd_src->size); } else { - sd_dst = frame_new_side_data(dst, sd_src->type, av_buffer_ref(sd_src->buf)); + AVBufferRef *ref = av_buffer_ref(sd_src->buf); + sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref); if (!sd_dst) { + av_buffer_unref(&ref); wipe_side_data(dst); return AVERROR(ENOMEM); } @@ -383,12 +424,17 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif av_buffer_unref(&dst->opaque_ref); + av_buffer_unref(&dst->private_ref); if (src->opaque_ref) { dst->opaque_ref = av_buffer_ref(src->opaque_ref); if (!dst->opaque_ref) return AVERROR(ENOMEM); } - + if (src->private_ref) { + dst->private_ref = av_buffer_ref(src->private_ref); + if (!dst->private_ref) + return AVERROR(ENOMEM); + } return 0; } @@ -518,12 +564,15 @@ void av_frame_unref(AVFrame *frame) av_freep(&frame->extended_buf); av_dict_free(&frame->metadata); #if FF_API_FRAME_QP +FF_DISABLE_DEPRECATION_WARNINGS av_buffer_unref(&frame->qp_table_buf); +FF_ENABLE_DEPRECATION_WARNINGS #endif av_buffer_unref(&frame->hw_frames_ctx); av_buffer_unref(&frame->opaque_ref); + av_buffer_unref(&frame->private_ref); get_frame_defaults(frame); } @@ -636,9 +685,9 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane) return NULL; } -static AVFrameSideData *frame_new_side_data(AVFrame *frame, - enum AVFrameSideDataType type, - AVBufferRef *buf) +AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf) { AVFrameSideData *ret, **tmp; @@ -646,17 +695,17 @@ static AVFrameSideData *frame_new_side_data(AVFrame *frame, return NULL; if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1) - goto fail; + return NULL; tmp = av_realloc(frame->side_data, (frame->nb_side_data + 1) * sizeof(*frame->side_data)); if (!tmp) - goto fail; + return NULL; frame->side_data = tmp; ret = av_mallocz(sizeof(*ret)); if (!ret) - goto fail; + return NULL; ret->buf = buf; ret->data = ret->buf->data; @@ -666,17 +715,18 @@ static AVFrameSideData *frame_new_side_data(AVFrame *frame, frame->side_data[frame->nb_side_data++] = ret; return ret; -fail: - av_buffer_unref(&buf); - return NULL; } AVFrameSideData *av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, int size) { - - return frame_new_side_data(frame, type, av_buffer_alloc(size)); + AVFrameSideData *ret; + AVBufferRef *buf = av_buffer_alloc(size); + ret = av_frame_new_side_data_from_buf(frame, type, buf); + if (!ret) + av_buffer_unref(&buf); + return ret; } AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, @@ -782,6 +832,8 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type) case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; case AV_FRAME_DATA_GOP_TIMECODE: return "GOP timecode"; case AV_FRAME_DATA_ICC_PROFILE: return "ICC profile"; + case AV_FRAME_DATA_QP_TABLE_PROPERTIES: return "QP table properties"; + case AV_FRAME_DATA_QP_TABLE_DATA: return "QP table data"; } return NULL; } @@ -796,7 +848,7 @@ static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; - if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL) && i == 1) { + if (desc->flags & (AV_PIX_FMT_FLAG_PAL | FF_PSEUDOPAL) && i == 1) { offsets[i] = 0; break; } diff --git a/media/ffvpx/libavutil/frame.h b/media/ffvpx/libavutil/frame.h index abe4f4fd1..9d57d6ce6 100644 --- a/media/ffvpx/libavutil/frame.h +++ b/media/ffvpx/libavutil/frame.h @@ -141,6 +141,23 @@ enum AVFrameSideDataType { * metadata key entry "name". */ AV_FRAME_DATA_ICC_PROFILE, + +#if FF_API_FRAME_QP + /** + * Implementation-specific description of the format of AV_FRAME_QP_TABLE_DATA. + * The contents of this side data are undocumented and internal; use + * av_frame_set_qp_table() and av_frame_get_qp_table() to access this in a + * meaningful way instead. + */ + AV_FRAME_DATA_QP_TABLE_PROPERTIES, + + /** + * Raw QP table data. Its format is described by + * AV_FRAME_DATA_QP_TABLE_PROPERTIES. Use av_frame_set_qp_table() and + * av_frame_get_qp_table() to access this instead. + */ + AV_FRAME_DATA_QP_TABLE_DATA, +#endif }; enum AVActiveFormatDescription { @@ -529,6 +546,7 @@ typedef struct AVFrame { attribute_deprecated int qscale_type; + attribute_deprecated AVBufferRef *qp_table_buf; #endif /** @@ -563,39 +581,77 @@ typedef struct AVFrame { /** * @} */ + + /** + * AVBufferRef for internal use by a single libav* library. + * Must not be used to transfer data between libraries. + * Has to be NULL when ownership of the frame leaves the respective library. + * + * Code outside the FFmpeg libs should never check or change the contents of the buffer ref. + * + * FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. + * av_frame_copy_props() calls create a new reference with av_buffer_ref() + * for the target frame's private_ref field. + */ + AVBufferRef *private_ref; } AVFrame; +#if FF_API_FRAME_GET_SET /** * Accessors for some AVFrame fields. These used to be provided for ABI * compatibility, and do not need to be used anymore. */ +attribute_deprecated int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame); +attribute_deprecated void av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val); +attribute_deprecated int64_t av_frame_get_pkt_duration (const AVFrame *frame); +attribute_deprecated void av_frame_set_pkt_duration (AVFrame *frame, int64_t val); +attribute_deprecated int64_t av_frame_get_pkt_pos (const AVFrame *frame); +attribute_deprecated void av_frame_set_pkt_pos (AVFrame *frame, int64_t val); +attribute_deprecated int64_t av_frame_get_channel_layout (const AVFrame *frame); +attribute_deprecated void av_frame_set_channel_layout (AVFrame *frame, int64_t val); +attribute_deprecated int av_frame_get_channels (const AVFrame *frame); +attribute_deprecated void av_frame_set_channels (AVFrame *frame, int val); +attribute_deprecated int av_frame_get_sample_rate (const AVFrame *frame); +attribute_deprecated void av_frame_set_sample_rate (AVFrame *frame, int val); +attribute_deprecated AVDictionary *av_frame_get_metadata (const AVFrame *frame); +attribute_deprecated void av_frame_set_metadata (AVFrame *frame, AVDictionary *val); +attribute_deprecated int av_frame_get_decode_error_flags (const AVFrame *frame); +attribute_deprecated void av_frame_set_decode_error_flags (AVFrame *frame, int val); +attribute_deprecated int av_frame_get_pkt_size(const AVFrame *frame); +attribute_deprecated void av_frame_set_pkt_size(AVFrame *frame, int val); -AVDictionary **avpriv_frame_get_metadatap(AVFrame *frame); #if FF_API_FRAME_QP +attribute_deprecated int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type); +attribute_deprecated int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int type); #endif +attribute_deprecated enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame); +attribute_deprecated void av_frame_set_colorspace(AVFrame *frame, enum AVColorSpace val); +attribute_deprecated enum AVColorRange av_frame_get_color_range(const AVFrame *frame); +attribute_deprecated void av_frame_set_color_range(AVFrame *frame, enum AVColorRange val); +#endif /** * Get the name of a colorspace. @@ -763,6 +819,22 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame, int size); /** + * Add a new side data to a frame from an existing AVBufferRef + * + * @param frame a frame to which the side data should be added + * @param type the type of the added side data + * @param buf an AVBufferRef to add as side data. The ownership of + * the reference is transferred to the frame. + * + * @return newly added side data on success, NULL on error. On failure + * the frame is unchanged and the AVBufferRef remains owned by + * the caller. + */ +AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf); + +/** * @return a pointer to the side data of a given type on success, NULL if there * is no side data with such type in this frame. */ diff --git a/media/ffvpx/libavutil/hwcontext.c b/media/ffvpx/libavutil/hwcontext.c new file mode 100644 index 000000000..70c556eca --- /dev/null +++ b/media/ffvpx/libavutil/hwcontext.c @@ -0,0 +1,873 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "imgutils.h" +#include "log.h" +#include "mem.h" +#include "pixdesc.h" +#include "pixfmt.h" + +static const HWContextType * const hw_table[] = { +#if CONFIG_CUDA + &ff_hwcontext_type_cuda, +#endif +#if CONFIG_D3D11VA + &ff_hwcontext_type_d3d11va, +#endif +#if CONFIG_LIBDRM + &ff_hwcontext_type_drm, +#endif +#if CONFIG_DXVA2 + &ff_hwcontext_type_dxva2, +#endif +#if CONFIG_OPENCL + &ff_hwcontext_type_opencl, +#endif +#if CONFIG_QSV + &ff_hwcontext_type_qsv, +#endif +#if CONFIG_VAAPI + &ff_hwcontext_type_vaapi, +#endif +#if CONFIG_VDPAU + &ff_hwcontext_type_vdpau, +#endif +#if CONFIG_VIDEOTOOLBOX + &ff_hwcontext_type_videotoolbox, +#endif +#if CONFIG_MEDIACODEC + &ff_hwcontext_type_mediacodec, +#endif + NULL, +}; + +static const char *const hw_type_names[] = { + [AV_HWDEVICE_TYPE_CUDA] = "cuda", + [AV_HWDEVICE_TYPE_DRM] = "drm", + [AV_HWDEVICE_TYPE_DXVA2] = "dxva2", + [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va", + [AV_HWDEVICE_TYPE_OPENCL] = "opencl", + [AV_HWDEVICE_TYPE_QSV] = "qsv", + [AV_HWDEVICE_TYPE_VAAPI] = "vaapi", + [AV_HWDEVICE_TYPE_VDPAU] = "vdpau", + [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox", + [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec", +}; + +enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name) +{ + int type; + for (type = 0; type < FF_ARRAY_ELEMS(hw_type_names); type++) { + if (hw_type_names[type] && !strcmp(hw_type_names[type], name)) + return type; + } + return AV_HWDEVICE_TYPE_NONE; +} + +const char *av_hwdevice_get_type_name(enum AVHWDeviceType type) +{ + if (type > AV_HWDEVICE_TYPE_NONE && + type < FF_ARRAY_ELEMS(hw_type_names)) + return hw_type_names[type]; + else + return NULL; +} + +enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev) +{ + enum AVHWDeviceType next; + int i, set = 0; + for (i = 0; hw_table[i]; i++) { + if (prev != AV_HWDEVICE_TYPE_NONE && hw_table[i]->type <= prev) + continue; + if (!set || hw_table[i]->type < next) { + next = hw_table[i]->type; + set = 1; + } + } + return set ? next : AV_HWDEVICE_TYPE_NONE; +} + +static const AVClass hwdevice_ctx_class = { + .class_name = "AVHWDeviceContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +static void hwdevice_ctx_free(void *opaque, uint8_t *data) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)data; + + /* uninit might still want access the hw context and the user + * free() callback might destroy it, so uninit has to be called first */ + if (ctx->internal->hw_type->device_uninit) + ctx->internal->hw_type->device_uninit(ctx); + + if (ctx->free) + ctx->free(ctx); + + av_buffer_unref(&ctx->internal->source_device); + + av_freep(&ctx->hwctx); + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx); +} + +AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type) +{ + AVHWDeviceContext *ctx; + AVBufferRef *buf; + const HWContextType *hw_type = NULL; + int i; + + for (i = 0; hw_table[i]; i++) { + if (hw_table[i]->type == type) { + hw_type = hw_table[i]; + break; + } + } + if (!hw_type) + return NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) + goto fail; + + if (hw_type->device_priv_size) { + ctx->internal->priv = av_mallocz(hw_type->device_priv_size); + if (!ctx->internal->priv) + goto fail; + } + + if (hw_type->device_hwctx_size) { + ctx->hwctx = av_mallocz(hw_type->device_hwctx_size); + if (!ctx->hwctx) + goto fail; + } + + buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx), + hwdevice_ctx_free, NULL, + AV_BUFFER_FLAG_READONLY); + if (!buf) + goto fail; + + ctx->type = type; + ctx->av_class = &hwdevice_ctx_class; + + ctx->internal->hw_type = hw_type; + + return buf; + +fail: + if (ctx->internal) + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx->hwctx); + av_freep(&ctx); + return NULL; +} + +int av_hwdevice_ctx_init(AVBufferRef *ref) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + int ret; + + if (ctx->internal->hw_type->device_init) { + ret = ctx->internal->hw_type->device_init(ctx); + if (ret < 0) + goto fail; + } + + return 0; +fail: + if (ctx->internal->hw_type->device_uninit) + ctx->internal->hw_type->device_uninit(ctx); + return ret; +} + +static const AVClass hwframe_ctx_class = { + .class_name = "AVHWFramesContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +static void hwframe_ctx_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)data; + + if (ctx->internal->pool_internal) + av_buffer_pool_uninit(&ctx->internal->pool_internal); + + if (ctx->internal->hw_type->frames_uninit) + ctx->internal->hw_type->frames_uninit(ctx); + + if (ctx->free) + ctx->free(ctx); + + av_buffer_unref(&ctx->internal->source_frames); + + av_buffer_unref(&ctx->device_ref); + + av_freep(&ctx->hwctx); + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx); +} + +AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in) +{ + AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data; + const HWContextType *hw_type = device_ctx->internal->hw_type; + AVHWFramesContext *ctx; + AVBufferRef *buf, *device_ref = NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) + goto fail; + + if (hw_type->frames_priv_size) { + ctx->internal->priv = av_mallocz(hw_type->frames_priv_size); + if (!ctx->internal->priv) + goto fail; + } + + if (hw_type->frames_hwctx_size) { + ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size); + if (!ctx->hwctx) + goto fail; + } + + device_ref = av_buffer_ref(device_ref_in); + if (!device_ref) + goto fail; + + buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx), + hwframe_ctx_free, NULL, + AV_BUFFER_FLAG_READONLY); + if (!buf) + goto fail; + + ctx->av_class = &hwframe_ctx_class; + ctx->device_ref = device_ref; + ctx->device_ctx = device_ctx; + ctx->format = AV_PIX_FMT_NONE; + ctx->sw_format = AV_PIX_FMT_NONE; + + ctx->internal->hw_type = hw_type; + + return buf; + +fail: + if (device_ref) + av_buffer_unref(&device_ref); + if (ctx->internal) + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx->hwctx); + av_freep(&ctx); + return NULL; +} + +static int hwframe_pool_prealloc(AVBufferRef *ref) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data; + AVFrame **frames; + int i, ret = 0; + + frames = av_mallocz_array(ctx->initial_pool_size, sizeof(*frames)); + if (!frames) + return AVERROR(ENOMEM); + + for (i = 0; i < ctx->initial_pool_size; i++) { + frames[i] = av_frame_alloc(); + if (!frames[i]) + goto fail; + + ret = av_hwframe_get_buffer(ref, frames[i], 0); + if (ret < 0) + goto fail; + } + +fail: + for (i = 0; i < ctx->initial_pool_size; i++) + av_frame_free(&frames[i]); + av_freep(&frames); + + return ret; +} + +int av_hwframe_ctx_init(AVBufferRef *ref) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data; + const enum AVPixelFormat *pix_fmt; + int ret; + + if (ctx->internal->source_frames) { + /* A derived frame context is already initialised. */ + return 0; + } + + /* validate the pixel format */ + for (pix_fmt = ctx->internal->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) { + if (*pix_fmt == ctx->format) + break; + } + if (*pix_fmt == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, + "The hardware pixel format '%s' is not supported by the device type '%s'\n", + av_get_pix_fmt_name(ctx->format), ctx->internal->hw_type->name); + return AVERROR(ENOSYS); + } + + /* validate the dimensions */ + ret = av_image_check_size(ctx->width, ctx->height, 0, ctx); + if (ret < 0) + return ret; + + /* format-specific init */ + if (ctx->internal->hw_type->frames_init) { + ret = ctx->internal->hw_type->frames_init(ctx); + if (ret < 0) + goto fail; + } + + if (ctx->internal->pool_internal && !ctx->pool) + ctx->pool = ctx->internal->pool_internal; + + /* preallocate the frames in the pool, if requested */ + if (ctx->initial_pool_size > 0) { + ret = hwframe_pool_prealloc(ref); + if (ret < 0) + goto fail; + } + + return 0; +fail: + if (ctx->internal->hw_type->frames_uninit) + ctx->internal->hw_type->frames_uninit(ctx); + return ret; +} + +int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats, int flags) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + + if (!ctx->internal->hw_type->transfer_get_formats) + return AVERROR(ENOSYS); + + return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats); +} + +static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; + AVFrame *frame_tmp; + int ret = 0; + + frame_tmp = av_frame_alloc(); + if (!frame_tmp) + return AVERROR(ENOMEM); + + /* if the format is set, use that + * otherwise pick the first supported one */ + if (dst->format >= 0) { + frame_tmp->format = dst->format; + } else { + enum AVPixelFormat *formats; + + ret = av_hwframe_transfer_get_formats(src->hw_frames_ctx, + AV_HWFRAME_TRANSFER_DIRECTION_FROM, + &formats, 0); + if (ret < 0) + goto fail; + frame_tmp->format = formats[0]; + av_freep(&formats); + } + frame_tmp->width = ctx->width; + frame_tmp->height = ctx->height; + + ret = av_frame_get_buffer(frame_tmp, 32); + if (ret < 0) + goto fail; + + ret = av_hwframe_transfer_data(frame_tmp, src, flags); + if (ret < 0) + goto fail; + + frame_tmp->width = src->width; + frame_tmp->height = src->height; + + av_frame_move_ref(dst, frame_tmp); + +fail: + av_frame_free(&frame_tmp); + return ret; +} + +int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *ctx; + int ret; + + if (!dst->buf[0]) + return transfer_data_alloc(dst, src, flags); + + if (src->hw_frames_ctx) { + ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; + + ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src); + if (ret < 0) + return ret; + } else if (dst->hw_frames_ctx) { + ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src); + if (ret < 0) + return ret; + } else + return AVERROR(ENOSYS); + + return 0; +} + +int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + int ret; + + if (ctx->internal->source_frames) { + // This is a derived frame context, so we allocate in the source + // and map the frame immediately. + AVFrame *src_frame; + + frame->format = ctx->format; + frame->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!frame->hw_frames_ctx) + return AVERROR(ENOMEM); + + src_frame = av_frame_alloc(); + if (!src_frame) + return AVERROR(ENOMEM); + + ret = av_hwframe_get_buffer(ctx->internal->source_frames, + src_frame, 0); + if (ret < 0) { + av_frame_free(&src_frame); + return ret; + } + + ret = av_hwframe_map(frame, src_frame, + ctx->internal->source_allocation_map_flags); + if (ret) { + av_log(ctx, AV_LOG_ERROR, "Failed to map frame into derived " + "frame context: %d.\n", ret); + av_frame_free(&src_frame); + return ret; + } + + // Free the source frame immediately - the mapped frame still + // contains a reference to it. + av_frame_free(&src_frame); + + return 0; + } + + if (!ctx->internal->hw_type->frames_get_buffer) + return AVERROR(ENOSYS); + + if (!ctx->pool) + return AVERROR(EINVAL); + + frame->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!frame->hw_frames_ctx) + return AVERROR(ENOMEM); + + ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame); + if (ret < 0) { + av_buffer_unref(&frame->hw_frames_ctx); + return ret; + } + + return 0; +} + +void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + const HWContextType *hw_type = ctx->internal->hw_type; + + if (hw_type->device_hwconfig_size == 0) + return NULL; + + return av_mallocz(hw_type->device_hwconfig_size); +} + +AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, + const void *hwconfig) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + const HWContextType *hw_type = ctx->internal->hw_type; + AVHWFramesConstraints *constraints; + + if (!hw_type->frames_get_constraints) + return NULL; + + constraints = av_mallocz(sizeof(*constraints)); + if (!constraints) + return NULL; + + constraints->min_width = constraints->min_height = 0; + constraints->max_width = constraints->max_height = INT_MAX; + + if (hw_type->frames_get_constraints(ctx, hwconfig, constraints) >= 0) { + return constraints; + } else { + av_hwframe_constraints_free(&constraints); + return NULL; + } +} + +void av_hwframe_constraints_free(AVHWFramesConstraints **constraints) +{ + if (*constraints) { + av_freep(&(*constraints)->valid_hw_formats); + av_freep(&(*constraints)->valid_sw_formats); + } + av_freep(constraints); +} + +int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, + const char *device, AVDictionary *opts, int flags) +{ + AVBufferRef *device_ref = NULL; + AVHWDeviceContext *device_ctx; + int ret = 0; + + device_ref = av_hwdevice_ctx_alloc(type); + if (!device_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + device_ctx = (AVHWDeviceContext*)device_ref->data; + + if (!device_ctx->internal->hw_type->device_create) { + ret = AVERROR(ENOSYS); + goto fail; + } + + ret = device_ctx->internal->hw_type->device_create(device_ctx, device, + opts, flags); + if (ret < 0) + goto fail; + + ret = av_hwdevice_ctx_init(device_ref); + if (ret < 0) + goto fail; + + *pdevice_ref = device_ref; + return 0; +fail: + av_buffer_unref(&device_ref); + *pdevice_ref = NULL; + return ret; +} + +int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, + enum AVHWDeviceType type, + AVBufferRef *src_ref, int flags) +{ + AVBufferRef *dst_ref = NULL, *tmp_ref; + AVHWDeviceContext *dst_ctx, *tmp_ctx; + int ret = 0; + + tmp_ref = src_ref; + while (tmp_ref) { + tmp_ctx = (AVHWDeviceContext*)tmp_ref->data; + if (tmp_ctx->type == type) { + dst_ref = av_buffer_ref(tmp_ref); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + goto done; + } + tmp_ref = tmp_ctx->internal->source_device; + } + + dst_ref = av_hwdevice_ctx_alloc(type); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst_ctx = (AVHWDeviceContext*)dst_ref->data; + + tmp_ref = src_ref; + while (tmp_ref) { + tmp_ctx = (AVHWDeviceContext*)tmp_ref->data; + if (dst_ctx->internal->hw_type->device_derive) { + ret = dst_ctx->internal->hw_type->device_derive(dst_ctx, + tmp_ctx, + flags); + if (ret == 0) { + dst_ctx->internal->source_device = av_buffer_ref(src_ref); + if (!dst_ctx->internal->source_device) { + ret = AVERROR(ENOMEM); + goto fail; + } + goto done; + } + if (ret != AVERROR(ENOSYS)) + goto fail; + } + tmp_ref = tmp_ctx->internal->source_device; + } + + ret = AVERROR(ENOSYS); + goto fail; + +done: + ret = av_hwdevice_ctx_init(dst_ref); + if (ret < 0) + goto fail; + + *dst_ref_ptr = dst_ref; + return 0; + +fail: + av_buffer_unref(&dst_ref); + *dst_ref_ptr = NULL; + return ret; +} + +static void ff_hwframe_unmap(void *opaque, uint8_t *data) +{ + HWMapDescriptor *hwmap = (HWMapDescriptor*)data; + AVHWFramesContext *ctx = opaque; + + if (hwmap->unmap) + hwmap->unmap(ctx, hwmap); + + av_frame_free(&hwmap->source); + + av_buffer_unref(&hwmap->hw_frames_ctx); + + av_free(hwmap); +} + +int ff_hwframe_map_create(AVBufferRef *hwframe_ref, + AVFrame *dst, const AVFrame *src, + void (*unmap)(AVHWFramesContext *ctx, + HWMapDescriptor *hwmap), + void *priv) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + HWMapDescriptor *hwmap; + int ret; + + hwmap = av_mallocz(sizeof(*hwmap)); + if (!hwmap) { + ret = AVERROR(ENOMEM); + goto fail; + } + + hwmap->source = av_frame_alloc(); + if (!hwmap->source) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = av_frame_ref(hwmap->source, src); + if (ret < 0) + goto fail; + + hwmap->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!hwmap->hw_frames_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + + hwmap->unmap = unmap; + hwmap->priv = priv; + + dst->buf[0] = av_buffer_create((uint8_t*)hwmap, sizeof(*hwmap), + &ff_hwframe_unmap, ctx, 0); + if (!dst->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + return 0; + +fail: + if (hwmap) { + av_buffer_unref(&hwmap->hw_frames_ctx); + av_frame_free(&hwmap->source); + } + av_free(hwmap); + return ret; +} + +int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *src_frames, *dst_frames; + HWMapDescriptor *hwmap; + int ret; + + if (src->hw_frames_ctx && dst->hw_frames_ctx) { + src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; + dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if ((src_frames == dst_frames && + src->format == dst_frames->sw_format && + dst->format == dst_frames->format) || + (src_frames->internal->source_frames && + src_frames->internal->source_frames->data == + (uint8_t*)dst_frames)) { + // This is an unmap operation. We don't need to directly + // do anything here other than fill in the original frame, + // because the real unmap will be invoked when the last + // reference to the mapped frame disappears. + if (!src->buf[0]) { + av_log(src_frames, AV_LOG_ERROR, "Invalid mapping " + "found when attempting unmap.\n"); + return AVERROR(EINVAL); + } + hwmap = (HWMapDescriptor*)src->buf[0]->data; + av_frame_unref(dst); + return av_frame_ref(dst, hwmap->source); + } + } + + if (src->hw_frames_ctx) { + src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; + + if (src_frames->format == src->format && + src_frames->internal->hw_type->map_from) { + ret = src_frames->internal->hw_type->map_from(src_frames, + dst, src, flags); + if (ret != AVERROR(ENOSYS)) + return ret; + } + } + + if (dst->hw_frames_ctx) { + dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if (dst_frames->format == dst->format && + dst_frames->internal->hw_type->map_to) { + ret = dst_frames->internal->hw_type->map_to(dst_frames, + dst, src, flags); + if (ret != AVERROR(ENOSYS)) + return ret; + } + } + + return AVERROR(ENOSYS); +} + +int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, + enum AVPixelFormat format, + AVBufferRef *derived_device_ctx, + AVBufferRef *source_frame_ctx, + int flags) +{ + AVBufferRef *dst_ref = NULL; + AVHWFramesContext *dst = NULL; + AVHWFramesContext *src = (AVHWFramesContext*)source_frame_ctx->data; + int ret; + + if (src->internal->source_frames) { + AVHWFramesContext *src_src = + (AVHWFramesContext*)src->internal->source_frames->data; + AVHWDeviceContext *dst_dev = + (AVHWDeviceContext*)derived_device_ctx->data; + + if (src_src->device_ctx == dst_dev) { + // This is actually an unmapping, so we just return a + // reference to the source frame context. + *derived_frame_ctx = + av_buffer_ref(src->internal->source_frames); + if (!*derived_frame_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + return 0; + } + } + + dst_ref = av_hwframe_ctx_alloc(derived_device_ctx); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + + dst = (AVHWFramesContext*)dst_ref->data; + + dst->format = format; + dst->sw_format = src->sw_format; + dst->width = src->width; + dst->height = src->height; + + dst->internal->source_frames = av_buffer_ref(source_frame_ctx); + if (!dst->internal->source_frames) { + ret = AVERROR(ENOMEM); + goto fail; + } + + dst->internal->source_allocation_map_flags = + flags & (AV_HWFRAME_MAP_READ | + AV_HWFRAME_MAP_WRITE | + AV_HWFRAME_MAP_OVERWRITE | + AV_HWFRAME_MAP_DIRECT); + + ret = AVERROR(ENOSYS); + if (src->internal->hw_type->frames_derive_from) + ret = src->internal->hw_type->frames_derive_from(dst, src, flags); + if (ret == AVERROR(ENOSYS) && + dst->internal->hw_type->frames_derive_to) + ret = dst->internal->hw_type->frames_derive_to(dst, src, flags); + if (ret == AVERROR(ENOSYS)) + ret = 0; + if (ret) + goto fail; + + *derived_frame_ctx = dst_ref; + return 0; + +fail: + if (dst) + av_buffer_unref(&dst->internal->source_frames); + av_buffer_unref(&dst_ref); + return ret; +} diff --git a/media/ffvpx/libavutil/hwcontext.h b/media/ffvpx/libavutil/hwcontext.h index 03334e20e..f5a4b6238 100644 --- a/media/ffvpx/libavutil/hwcontext.h +++ b/media/ffvpx/libavutil/hwcontext.h @@ -25,15 +25,17 @@ #include "pixfmt.h" enum AVHWDeviceType { + AV_HWDEVICE_TYPE_NONE, AV_HWDEVICE_TYPE_VDPAU, AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_DXVA2, AV_HWDEVICE_TYPE_QSV, AV_HWDEVICE_TYPE_VIDEOTOOLBOX, - AV_HWDEVICE_TYPE_NONE, AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DRM, + AV_HWDEVICE_TYPE_OPENCL, + AV_HWDEVICE_TYPE_MEDIACODEC, }; typedef struct AVHWDeviceInternal AVHWDeviceInternal; diff --git a/media/ffvpx/libavutil/hwcontext_internal.h b/media/ffvpx/libavutil/hwcontext_internal.h new file mode 100644 index 000000000..332062dda --- /dev/null +++ b/media/ffvpx/libavutil/hwcontext_internal.h @@ -0,0 +1,171 @@ +/* + * 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 AVUTIL_HWCONTEXT_INTERNAL_H +#define AVUTIL_HWCONTEXT_INTERNAL_H + +#include <stddef.h> + +#include "buffer.h" +#include "hwcontext.h" +#include "frame.h" +#include "pixfmt.h" + +typedef struct HWContextType { + enum AVHWDeviceType type; + const char *name; + + /** + * An array of pixel formats supported by the AVHWFramesContext instances + * Terminated by AV_PIX_FMT_NONE. + */ + const enum AVPixelFormat *pix_fmts; + + /** + * size of the public hardware-specific context, + * i.e. AVHWDeviceContext.hwctx + */ + size_t device_hwctx_size; + /** + * size of the private data, i.e. + * AVHWDeviceInternal.priv + */ + size_t device_priv_size; + + /** + * Size of the hardware-specific device configuration. + * (Used to query hwframe constraints.) + */ + size_t device_hwconfig_size; + + /** + * size of the public frame pool hardware-specific context, + * i.e. AVHWFramesContext.hwctx + */ + size_t frames_hwctx_size; + /** + * size of the private data, i.e. + * AVHWFramesInternal.priv + */ + size_t frames_priv_size; + + int (*device_create)(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags); + int (*device_derive)(AVHWDeviceContext *dst_ctx, + AVHWDeviceContext *src_ctx, int flags); + + int (*device_init)(AVHWDeviceContext *ctx); + void (*device_uninit)(AVHWDeviceContext *ctx); + + int (*frames_get_constraints)(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints); + + int (*frames_init)(AVHWFramesContext *ctx); + void (*frames_uninit)(AVHWFramesContext *ctx); + + int (*frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame); + int (*transfer_get_formats)(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats); + int (*transfer_data_to)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src); + int (*transfer_data_from)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src); + + int (*map_to)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src, int flags); + int (*map_from)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src, int flags); + + int (*frames_derive_to)(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags); + int (*frames_derive_from)(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags); +} HWContextType; + +struct AVHWDeviceInternal { + const HWContextType *hw_type; + void *priv; + + /** + * For a derived device, a reference to the original device + * context it was derived from. + */ + AVBufferRef *source_device; +}; + +struct AVHWFramesInternal { + const HWContextType *hw_type; + void *priv; + + AVBufferPool *pool_internal; + + /** + * For a derived context, a reference to the original frames + * context it was derived from. + */ + AVBufferRef *source_frames; + /** + * Flags to apply to the mapping from the source to the derived + * frame context when trying to allocate in the derived context. + */ + int source_allocation_map_flags; +}; + +typedef struct HWMapDescriptor { + /** + * A reference to the original source of the mapping. + */ + AVFrame *source; + /** + * A reference to the hardware frames context in which this + * mapping was made. May be the same as source->hw_frames_ctx, + * but need not be. + */ + AVBufferRef *hw_frames_ctx; + /** + * Unmap function. + */ + void (*unmap)(AVHWFramesContext *ctx, + struct HWMapDescriptor *hwmap); + /** + * Hardware-specific private data associated with the mapping. + */ + void *priv; +} HWMapDescriptor; + +int ff_hwframe_map_create(AVBufferRef *hwframe_ref, + AVFrame *dst, const AVFrame *src, + void (*unmap)(AVHWFramesContext *ctx, + HWMapDescriptor *hwmap), + void *priv); + + +extern const HWContextType ff_hwcontext_type_cuda; +extern const HWContextType ff_hwcontext_type_d3d11va; +extern const HWContextType ff_hwcontext_type_drm; +extern const HWContextType ff_hwcontext_type_dxva2; +extern const HWContextType ff_hwcontext_type_opencl; +extern const HWContextType ff_hwcontext_type_qsv; +extern const HWContextType ff_hwcontext_type_vaapi; +extern const HWContextType ff_hwcontext_type_vdpau; +extern const HWContextType ff_hwcontext_type_videotoolbox; +extern const HWContextType ff_hwcontext_type_mediacodec; + +#endif /* AVUTIL_HWCONTEXT_INTERNAL_H */ diff --git a/media/ffvpx/libavutil/imgutils.c b/media/ffvpx/libavutil/imgutils.c index 500517880..4938a7ef6 100644 --- a/media/ffvpx/libavutil/imgutils.c +++ b/media/ffvpx/libavutil/imgutils.c @@ -125,7 +125,7 @@ int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int hei size[0] = linesizes[0] * height; if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + desc->flags & FF_PSEUDOPAL) { data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */ return size[0] + 256 * 4; } @@ -216,7 +216,7 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4], av_free(buf); return ret; } - if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + if (desc->flags & AV_PIX_FMT_FLAG_PAL || (desc->flags & FF_PSEUDOPAL && pointers[1])) { avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt); if (align < 4) { av_log(NULL, AV_LOG_ERROR, "Formats with a palette require a minimum alignment of 4\n"); @@ -225,7 +225,7 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4], } if ((desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) && + desc->flags & FF_PSEUDOPAL) && pointers[1] && pointers[1] - pointers[0] > linesizes[0] * h) { /* zero-initialize the padding before the palette */ memset(pointers[0] + linesizes[0] * h, 0, @@ -242,9 +242,10 @@ typedef struct ImgUtils { } ImgUtils; static const AVClass imgutils_class = { - .class_name = "IMGUTILS", - .item_name = av_default_item_name, - .version = LIBAVUTIL_VERSION_INT, + .class_name = "IMGUTILS", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, .log_level_offset_offset = offsetof(ImgUtils, log_offset), .parent_log_context_offset = offsetof(ImgUtils, log_ctx), }; @@ -353,12 +354,13 @@ static void image_copy(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], return; if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + desc->flags & FF_PSEUDOPAL) { copy_plane(dst_data[0], dst_linesizes[0], src_data[0], src_linesizes[0], width, height); /* copy the palette */ - memcpy(dst_data[1], src_data[1], 4*256); + if ((desc->flags & AV_PIX_FMT_FLAG_PAL) || (dst_data[1] && src_data[1])) + memcpy(dst_data[1], src_data[1], 4*256); } else { int i, planes_nb = 0; @@ -441,7 +443,7 @@ int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, return ret; // do not include palette for these pseudo-paletted formats - if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) + if (desc->flags & FF_PSEUDOPAL) return FFALIGN(width, align) * height; return av_image_fill_arrays(data, linesize, NULL, pix_fmt, diff --git a/media/ffvpx/libavutil/integer.c b/media/ffvpx/libavutil/integer.c index 6d6855fa1..890e314dc 100644 --- a/media/ffvpx/libavutil/integer.c +++ b/media/ffvpx/libavutil/integer.c @@ -164,41 +164,3 @@ int64_t av_i2int(AVInteger a){ } return out; } - -#ifdef TEST - -const uint8_t ff_log2_tab[256]={ - 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 -}; - -int main(void){ - int64_t a,b; - - for(a=7; a<256*256*256; a+=13215){ - for(b=3; b<256*256*256; b+=27118){ - AVInteger ai= av_int2i(a); - AVInteger bi= av_int2i(b); - - av_assert0(av_i2int(ai) == a); - av_assert0(av_i2int(bi) == b); - av_assert0(av_i2int(av_add_i(ai,bi)) == a+b); - av_assert0(av_i2int(av_sub_i(ai,bi)) == a-b); - av_assert0(av_i2int(av_mul_i(ai,bi)) == a*b); - av_assert0(av_i2int(av_shr_i(ai, 9)) == a>>9); - av_assert0(av_i2int(av_shr_i(ai,-9)) == a<<9); - av_assert0(av_i2int(av_shr_i(ai, 17)) == a>>17); - av_assert0(av_i2int(av_shr_i(ai,-17)) == a<<17); - av_assert0(av_log2_i(ai) == av_log2(a)); - av_assert0(av_i2int(av_div_i(ai,bi)) == a/b); - } - } - return 0; -} -#endif diff --git a/media/ffvpx/libavutil/internal.h b/media/ffvpx/libavutil/internal.h index a2d73e3cc..06bd561e8 100644 --- a/media/ffvpx/libavutil/internal.h +++ b/media/ffvpx/libavutil/internal.h @@ -43,6 +43,7 @@ #include "cpu.h" #include "dict.h" #include "macros.h" +#include "mem.h" #include "pixfmt.h" #include "version.h" @@ -62,10 +63,10 @@ #endif #endif -#if defined(_MSC_VER) && CONFIG_SHARED -# define av_export __declspec(dllimport) +#if defined(_WIN32) && CONFIG_SHARED && !defined(BUILDING_avutil) +# define av_export_avutil __declspec(dllimport) #else -# define av_export +# define av_export_avutil #endif #if HAVE_PRAGMA_DEPRECATED @@ -76,8 +77,8 @@ # define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996)) # define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop)) # else -# define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -# define FF_ENABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"") +# define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define FF_ENABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic pop") # endif #else # define FF_DISABLE_DEPRECATION_WARNINGS @@ -110,24 +111,30 @@ DECLARE_ALIGNED(a, t, la_##v) s o; \ t (*v) o = la_##v -#define LOCAL_ALIGNED(a, t, v, ...) E1(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,)) +#define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__) -#if HAVE_LOCAL_ALIGNED_8 +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED # define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,)) #else -# define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__) +# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,)) #endif -#if HAVE_LOCAL_ALIGNED_16 +#if HAVE_LOCAL_ALIGNED # define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,)) #else -# define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__) +# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,)) #endif -#if HAVE_LOCAL_ALIGNED_32 +#if HAVE_LOCAL_ALIGNED # define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,)) #else -# define LOCAL_ALIGNED_32(t, v, ...) LOCAL_ALIGNED(32, t, v, __VA_ARGS__) +# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,)) #endif #define FF_ALLOC_OR_GOTO(ctx, p, size, label)\ @@ -353,4 +360,13 @@ void ff_check_pixfmt_descriptors(void); */ int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp); +// Helper macro for AV_PIX_FMT_FLAG_PSEUDOPAL deprecation. Code inside FFmpeg +// should always use FF_PSEUDOPAL. Once the public API flag gets removed, all +// code using it is dead code. +#if FF_API_PSEUDOPAL +#define FF_PSEUDOPAL AV_PIX_FMT_FLAG_PSEUDOPAL +#else +#define FF_PSEUDOPAL 0 +#endif + #endif /* AVUTIL_INTERNAL_H */ diff --git a/media/ffvpx/libavutil/intreadwrite.h b/media/ffvpx/libavutil/intreadwrite.h index d54d4b91d..67c763b13 100644 --- a/media/ffvpx/libavutil/intreadwrite.h +++ b/media/ffvpx/libavutil/intreadwrite.h @@ -215,7 +215,7 @@ typedef union { * by per-arch headers. */ -#if defined(__GNUC__) && !defined(__TI_COMPILER_VERSION__) +#if defined(__GNUC__) union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; @@ -224,12 +224,7 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; # define AV_RN(s, p) (((const union unaligned_##s *) (p))->l) # define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v)) -#elif defined(__DECC) - -# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) -# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) - -#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64)) && AV_HAVE_FAST_UNALIGNED +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64) || defined(_M_ARM64)) && AV_HAVE_FAST_UNALIGNED # define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) # define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) diff --git a/media/ffvpx/libavutil/log.c b/media/ffvpx/libavutil/log.c index be806202f..9b7d48487 100644 --- a/media/ffvpx/libavutil/log.c +++ b/media/ffvpx/libavutil/log.c @@ -39,11 +39,9 @@ #include "common.h" #include "internal.h" #include "log.h" +#include "thread.h" -#if HAVE_PTHREADS -#include <pthread.h> -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -#endif +static AVMutex mutex = AV_MUTEX_INITIALIZER; #define LINE_SZ 1024 @@ -57,7 +55,7 @@ static int av_log_level = AV_LOG_INFO; static int flags; #define NB_LEVELS 8 -#if defined(_WIN32) && !defined(__MINGW32CE__) && HAVE_SETCONSOLETEXTATTRIBUTE +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE #include <windows.h> static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = { [AV_LOG_PANIC /8] = 12, @@ -124,7 +122,7 @@ static int use_color = -1; static void check_color_terminal(void) { -#if defined(_WIN32) && !defined(__MINGW32CE__) && HAVE_SETCONSOLETEXTATTRIBUTE +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE CONSOLE_SCREEN_BUFFER_INFO con_info; con = GetStdHandle(STD_ERROR_HANDLE); use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") && @@ -159,7 +157,7 @@ static void colored_fputs(int level, int tint, const char *str) if (level == AV_LOG_INFO/8) local_use_color = 0; else local_use_color = use_color; -#if defined(_WIN32) && !defined(__MINGW32CE__) && HAVE_SETCONSOLETEXTATTRIBUTE +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE if (local_use_color) SetConsoleTextAttribute(con, background | color[level]); fputs(str, stderr); @@ -268,11 +266,11 @@ static void format_line(void *avcl, int level, const char *fmt, va_list vl, av_bprintf(part+1, "[%s @ %p] ", avc->item_name(avcl), avcl); if(type) type[1] = get_category(avcl); - - if (flags & AV_LOG_PRINT_LEVEL) - av_bprintf(part+2, "[%s] ", get_level_str(level)); } + if (*print_prefix && (level > AV_LOG_QUIET) && (flags & AV_LOG_PRINT_LEVEL)) + av_bprintf(part+2, "[%s] ", get_level_str(level)); + av_vbprintf(part+3, fmt, vl); if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) { @@ -317,9 +315,7 @@ void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) if (level > av_log_level) return; -#if HAVE_PTHREADS - pthread_mutex_lock(&mutex); -#endif + ff_mutex_lock(&mutex); format_line(ptr, level, fmt, vl, part, &print_prefix, type); snprintf(line, sizeof(line), "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str); @@ -356,9 +352,7 @@ void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) #endif end: av_bprint_finalize(part+3, NULL); -#if HAVE_PTHREADS - pthread_mutex_unlock(&mutex); -#endif + ff_mutex_unlock(&mutex); } static void (*av_log_callback)(void*, int, const char*, va_list) = diff --git a/media/ffvpx/libavutil/log.h b/media/ffvpx/libavutil/log.h index f0a57385d..d9554e609 100644 --- a/media/ffvpx/libavutil/log.h +++ b/media/ffvpx/libavutil/log.h @@ -334,20 +334,6 @@ void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, char *line, int line_size, int *print_prefix); -#if FF_API_DLOG -/** - * av_dlog macros - * @deprecated unused - * Useful to print debug messages that shouldn't get compiled in normally. - */ - -#ifdef DEBUG -# define av_dlog(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__) -#else -# define av_dlog(pctx, ...) do { if (0) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0) -#endif -#endif /* FF_API_DLOG */ - /** * Skip repeated messages, this requires the user app to use av_log() instead of * (f)printf as the 2 would otherwise interfere and lead to diff --git a/media/ffvpx/libavutil/mem.c b/media/ffvpx/libavutil/mem.c index 36740f115..6149755a6 100644 --- a/media/ffvpx/libavutil/mem.c +++ b/media/ffvpx/libavutil/mem.c @@ -61,7 +61,7 @@ void free(void *ptr); #include "mem_internal.h" -#define ALIGN (HAVE_AVX ? 32 : 16) +#define ALIGN (HAVE_AVX512 ? 64 : (HAVE_AVX ? 32 : 16)) /* NOTE: if you want to override these functions with your own * implementations (not recommended) you have to link libav* as @@ -181,6 +181,20 @@ int av_reallocp(void *ptr, size_t size) return 0; } +void *av_malloc_array(size_t nmemb, size_t size) +{ + if (!size || nmemb >= INT_MAX / size) + return NULL; + return av_malloc(nmemb * size); +} + +void *av_mallocz_array(size_t nmemb, size_t size) +{ + if (!size || nmemb >= INT_MAX / size) + return NULL; + return av_mallocz(nmemb * size); +} + void *av_realloc_array(void *ptr, size_t nmemb, size_t size) { if (!size || nmemb >= INT_MAX / size) @@ -449,10 +463,15 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt) void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) { - if (min_size < *size) + if (min_size <= *size) return ptr; - min_size = FFMAX(min_size + min_size / 16 + 32, min_size); + if (min_size > max_alloc_size - 32) { + *size = 0; + return NULL; + } + + min_size = FFMIN(max_alloc_size - 32, FFMAX(min_size + min_size / 16 + 32, min_size)); ptr = av_realloc(ptr, min_size); /* we could set this to the unmodified min_size but this is safer diff --git a/media/ffvpx/libavutil/mem.h b/media/ffvpx/libavutil/mem.h index 527cd0319..7e0b12a8a 100644 --- a/media/ffvpx/libavutil/mem.h +++ b/media/ffvpx/libavutil/mem.h @@ -74,6 +74,19 @@ */ /** + * @def DECLARE_ASM_ALIGNED(n,t,v) + * Declare an aligned variable appropriate for use in inline assembly code. + * + * @code{.c} + * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** * @def DECLARE_ASM_CONST(n,t,v) * Declare a static constant aligned variable appropriate for use in inline * assembly code. @@ -89,25 +102,23 @@ #if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v -#elif defined(__TI_COMPILER_VERSION__) - #define DECLARE_ALIGNED(n,t,v) \ - AV_PRAGMA(DATA_ALIGN(v,n)) \ - t __attribute__((aligned(n))) v - #define DECLARE_ASM_CONST(n,t,v) \ - AV_PRAGMA(DATA_ALIGN(v,n)) \ - static const t __attribute__((aligned(n))) v #elif defined(__DJGPP__) #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v #elif defined(__GNUC__) || defined(__clang__) #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v #elif defined(_MSC_VER) #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v #else #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_ALIGNED(n,t,v) t v #define DECLARE_ASM_CONST(n,t,v) static const t v #endif @@ -206,12 +217,7 @@ void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1); * be allocated * @see av_malloc() */ -av_alloc_size(1, 2) static inline void *av_malloc_array(size_t nmemb, size_t size) -{ - if (!size || nmemb >= INT_MAX / size) - return NULL; - return av_malloc(nmemb * size); -} +av_alloc_size(1, 2) void *av_malloc_array(size_t nmemb, size_t size); /** * Allocate a memory block for an array with av_mallocz(). @@ -226,12 +232,7 @@ av_alloc_size(1, 2) static inline void *av_malloc_array(size_t nmemb, size_t siz * @see av_mallocz() * @see av_malloc_array() */ -av_alloc_size(1, 2) static inline void *av_mallocz_array(size_t nmemb, size_t size) -{ - if (!size || nmemb >= INT_MAX / size) - return NULL; - return av_mallocz(nmemb * size); -} +av_alloc_size(1, 2) void *av_mallocz_array(size_t nmemb, size_t size); /** * Non-inlined equivalent of av_mallocz_array(). diff --git a/media/ffvpx/libavutil/moz.build b/media/ffvpx/libavutil/moz.build index 201b62fed..040ab76ba 100644 --- a/media/ffvpx/libavutil/moz.build +++ b/media/ffvpx/libavutil/moz.build @@ -12,7 +12,6 @@ if CONFIG['FFVPX_ASFLAGS']: SharedLibrary('mozavutil') SOURCES += [ 'adler32.c', - 'atomic.c', 'avstring.c', 'base64.c', 'bprint.c', @@ -29,6 +28,7 @@ SOURCES += [ 'fixed_dsp.c', 'float_dsp.c', 'frame.c', + 'hwcontext.c', 'imgutils.c', 'integer.c', 'intmath.c', diff --git a/media/ffvpx/libavutil/opt.c b/media/ffvpx/libavutil/opt.c index df88663e3..3b0aab4ee 100644 --- a/media/ffvpx/libavutil/opt.c +++ b/media/ffvpx/libavutil/opt.c @@ -1181,6 +1181,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.'); if (opt->help) av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); diff --git a/media/ffvpx/libavutil/opt.h b/media/ffvpx/libavutil/opt.h index 0d893795d..07da68ea2 100644 --- a/media/ffvpx/libavutil/opt.h +++ b/media/ffvpx/libavutil/opt.h @@ -229,15 +229,15 @@ enum AVOptionType{ AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length AV_OPT_TYPE_DICT, AV_OPT_TYPE_UINT64, - AV_OPT_TYPE_CONST = 128, - AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), ///< offset must point to two consecutive integers - AV_OPT_TYPE_PIXEL_FMT = MKBETAG('P','F','M','T'), - AV_OPT_TYPE_SAMPLE_FMT = MKBETAG('S','F','M','T'), - AV_OPT_TYPE_VIDEO_RATE = MKBETAG('V','R','A','T'), ///< offset must point to AVRational - AV_OPT_TYPE_DURATION = MKBETAG('D','U','R',' '), - AV_OPT_TYPE_COLOR = MKBETAG('C','O','L','R'), - AV_OPT_TYPE_CHANNEL_LAYOUT = MKBETAG('C','H','L','A'), - AV_OPT_TYPE_BOOL = MKBETAG('B','O','O','L'), + AV_OPT_TYPE_CONST, + AV_OPT_TYPE_IMAGE_SIZE, ///< offset must point to two consecutive integers + AV_OPT_TYPE_PIXEL_FMT, + AV_OPT_TYPE_SAMPLE_FMT, + AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational + AV_OPT_TYPE_DURATION, + AV_OPT_TYPE_COLOR, + AV_OPT_TYPE_CHANNEL_LAYOUT, + AV_OPT_TYPE_BOOL, }; /** @@ -275,9 +275,6 @@ typedef struct AVOption { int flags; #define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding #define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding -#if FF_API_OPT_TYPE_METADATA -#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... -#endif #define AV_OPT_FLAG_AUDIO_PARAM 8 #define AV_OPT_FLAG_VIDEO_PARAM 16 #define AV_OPT_FLAG_SUBTITLE_PARAM 32 @@ -290,6 +287,7 @@ typedef struct AVOption { * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set. */ #define AV_OPT_FLAG_READONLY 128 +#define AV_OPT_FLAG_BSF_PARAM (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering #define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering //FIXME think about enc-audio, ... style flags diff --git a/media/ffvpx/libavutil/parseutils.c b/media/ffvpx/libavutil/parseutils.c index be4ea1ee1..9de19d1c1 100644 --- a/media/ffvpx/libavutil/parseutils.c +++ b/media/ffvpx/libavutil/parseutils.c @@ -590,7 +590,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) int64_t t, now64; time_t now; struct tm dt = { 0 }, tmbuf; - int today = 0, negative = 0, microseconds = 0; + int today = 0, negative = 0, microseconds = 0, suffix = 1000000; int i; static const char * const date_fmt[] = { "%Y - %m - %d", @@ -689,6 +689,16 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) if (duration) { t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec; + if (q[0] == 'm' && q[1] == 's') { + suffix = 1000; + microseconds /= 1000; + q += 2; + } else if (q[0] == 'u' && q[1] == 's') { + suffix = 1; + microseconds = 0; + q += 2; + } else if (*q == 's') + q++; } else { int is_utc = *q == 'Z' || *q == 'z'; int tzoffset = 0; @@ -724,7 +734,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) if (*q) return AVERROR(EINVAL); - t *= 1000000; + t *= suffix; t += microseconds; *timeval = negative ? -t : t; return 0; diff --git a/media/ffvpx/libavutil/pixdesc.c b/media/ffvpx/libavutil/pixdesc.c index 2cfab89c0..8ed52751c 100644 --- a/media/ffvpx/libavutil/pixdesc.c +++ b/media/ffvpx/libavutil/pixdesc.c @@ -257,7 +257,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .comp = { { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ }, - .flags = AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = FF_PSEUDOPAL, .alias = "gray8,y8", }, [AV_PIX_FMT_MONOWHITE] = { @@ -326,22 +326,10 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_PLANAR, }, -#if FF_API_XVMC - [AV_PIX_FMT_XVMC_MPEG2_MC] = { - .name = "xvmcmc", - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, - [AV_PIX_FMT_XVMC_MPEG2_IDCT] = { - .name = "xvmcidct", - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, -#endif /* FF_API_XVMC */ -#if !FF_API_XVMC [AV_PIX_FMT_XVMC] = { .name = "xvmc", .flags = AV_PIX_FMT_FLAG_HWACCEL, }, -#endif /* !FF_API_XVMC */ [AV_PIX_FMT_UYVY422] = { .name = "uyvy422", .nb_components = 3, @@ -374,7 +362,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { { 0, 1, 0, 3, 3, 0, 2, 1 }, /* G */ { 0, 1, 0, 6, 2, 0, 1, 1 }, /* B */ }, - .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, }, [AV_PIX_FMT_BGR4] = { .name = "bgr4", @@ -398,7 +386,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { { 0, 1, 0, 1, 2, 0, 1, 1 }, /* G */ { 0, 1, 0, 3, 1, 0, 0, 1 }, /* B */ }, - .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, }, [AV_PIX_FMT_RGB8] = { .name = "rgb8", @@ -410,7 +398,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { { 0, 1, 0, 3, 3, 0, 2, 1 }, /* G */ { 0, 1, 0, 0, 3, 0, 2, 1 }, /* B */ }, - .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, }, [AV_PIX_FMT_RGB4] = { .name = "rgb4", @@ -434,7 +422,7 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { { 0, 1, 0, 1, 2, 0, 1, 1 }, /* G */ { 0, 1, 0, 0, 1, 0, 0, 1 }, /* B */ }, - .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, }, [AV_PIX_FMT_NV12] = { .name = "nv12", @@ -989,44 +977,6 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, }, -#if FF_API_VDPAU - [AV_PIX_FMT_VDPAU_H264] = { - .name = "vdpau_h264", - .log2_chroma_w = 1, - .log2_chroma_h = 1, - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, - [AV_PIX_FMT_VDPAU_MPEG1] = { - .name = "vdpau_mpeg1", - .log2_chroma_w = 1, - .log2_chroma_h = 1, - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, - [AV_PIX_FMT_VDPAU_MPEG2] = { - .name = "vdpau_mpeg2", - .log2_chroma_w = 1, - .log2_chroma_h = 1, - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, - [AV_PIX_FMT_VDPAU_WMV3] = { - .name = "vdpau_wmv3", - .log2_chroma_w = 1, - .log2_chroma_h = 1, - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, - [AV_PIX_FMT_VDPAU_VC1] = { - .name = "vdpau_vc1", - .log2_chroma_w = 1, - .log2_chroma_h = 1, - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, - [AV_PIX_FMT_VDPAU_MPEG4] = { - .name = "vdpau_mpeg4", - .log2_chroma_w = 1, - .log2_chroma_h = 1, - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, -#endif [AV_PIX_FMT_RGB48BE] = { .name = "rgb48be", .nb_components = 3, @@ -1670,12 +1620,6 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .log2_chroma_h = 1, .flags = AV_PIX_FMT_FLAG_HWACCEL, }, - [AV_PIX_FMT_VDA_VLD] = { - .name = "vda_vld", - .log2_chroma_w = 1, - .log2_chroma_h = 1, - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, [AV_PIX_FMT_YA8] = { .name = "ya8", .nb_components = 2, @@ -2029,10 +1973,6 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, }, - [AV_PIX_FMT_VDA] = { - .name = "vda", - .flags = AV_PIX_FMT_FLAG_HWACCEL, - }, [AV_PIX_FMT_QSV] = { .name = "qsv", .flags = AV_PIX_FMT_FLAG_HWACCEL, @@ -2241,6 +2181,10 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .name = "drm_prime", .flags = AV_PIX_FMT_FLAG_HWACCEL, }, + [AV_PIX_FMT_OPENCL] = { + .name = "opencl", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, }; #if FF_API_PLUS1_MINUS1 FF_ENABLE_DEPRECATION_WARNINGS diff --git a/media/ffvpx/libavutil/pixdesc.h b/media/ffvpx/libavutil/pixdesc.h index fc3737c4a..1ab372782 100644 --- a/media/ffvpx/libavutil/pixdesc.h +++ b/media/ffvpx/libavutil/pixdesc.h @@ -154,6 +154,14 @@ typedef struct AVPixFmtDescriptor { * in some cases be simpler. Or the data can be interpreted purely based on * the pixel format without using the palette. * An example of a pseudo-paletted format is AV_PIX_FMT_GRAY8 + * + * @deprecated This flag is deprecated, and will be removed. When it is removed, + * the extra palette allocation in AVFrame.data[1] is removed as well. Only + * actual paletted formats (as indicated by AV_PIX_FMT_FLAG_PAL) will have a + * palette. Starting with FFmpeg versions which have this flag deprecated, the + * extra "pseudo" palette is already ignored, and API users are not required to + * allocate a palette for AV_PIX_FMT_FLAG_PSEUDOPAL formats (it was required + * before the deprecation, though). */ #define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6) @@ -225,11 +233,6 @@ enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc); * Utility function to access log2_chroma_w log2_chroma_h from * the pixel format AVPixFmtDescriptor. * - * See av_get_chroma_sub_sample() for a function that asserts a - * valid pixel format instead of returning an error code. - * Its recommended that you use avcodec_get_chroma_sub_sample unless - * you do check the return code! - * * @param[in] pix_fmt the pixel format * @param[out] h_shift store log2_chroma_w (horizontal/width shift) * @param[out] v_shift store log2_chroma_h (vertical/height shift) diff --git a/media/ffvpx/libavutil/pixfmt.h b/media/ffvpx/libavutil/pixfmt.h index 24889c8e5..e184a5667 100644 --- a/media/ffvpx/libavutil/pixfmt.h +++ b/media/ffvpx/libavutil/pixfmt.h @@ -74,11 +74,6 @@ enum AVPixelFormat { AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range -#if FF_API_XVMC - AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing - AV_PIX_FMT_XVMC_MPEG2_IDCT, - AV_PIX_FMT_XVMC = AV_PIX_FMT_XVMC_MPEG2_IDCT, -#endif /* FF_API_XVMC */ AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) @@ -100,13 +95,6 @@ enum AVPixelFormat { AV_PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) AV_PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range AV_PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) -#if FF_API_VDPAU - AV_PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - AV_PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - AV_PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - AV_PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - AV_PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers -#endif AV_PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian AV_PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian @@ -142,9 +130,6 @@ enum AVPixelFormat { AV_PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian AV_PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian AV_PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian -#if FF_API_VDPAU - AV_PIX_FMT_VDPAU_MPEG4, ///< MPEG-4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers -#endif AV_PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer AV_PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), little-endian, X=unused/undefined @@ -176,7 +161,6 @@ enum AVPixelFormat { AV_PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - AV_PIX_FMT_VDA_VLD, ///< hardware decoding through VDA AV_PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp AV_PIX_FMT_GBR24P = AV_PIX_FMT_GBRP, // alias for #AV_PIX_FMT_GBRP AV_PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big-endian @@ -221,8 +205,6 @@ enum AVPixelFormat { AV_PIX_FMT_YVYU422, ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb - AV_PIX_FMT_VDA, ///< HW acceleration through VDA, data[3] contains a CVPixelBufferRef - AV_PIX_FMT_YA16BE, ///< 16 bits gray, 16 bits alpha (big-endian) AV_PIX_FMT_YA16LE, ///< 16 bits gray, 16 bits alpha (little-endian) @@ -248,7 +230,7 @@ enum AVPixelFormat { */ AV_PIX_FMT_CUDA, - AV_PIX_FMT_0RGB=0x123+4,///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined + AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined AV_PIX_FMT_BGR0, ///< packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined @@ -283,9 +265,9 @@ enum AVPixelFormat { AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian */ AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian */ AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian */ -#if !FF_API_XVMC + AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing -#endif /* !FF_API_XVMC */ + AV_PIX_FMT_YUV440P10LE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian AV_PIX_FMT_YUV440P10BE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian AV_PIX_FMT_YUV440P12LE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian @@ -340,6 +322,13 @@ enum AVPixelFormat { * data[0] points to an AVDRMFrameDescriptor. */ AV_PIX_FMT_DRM_PRIME, + /** + * Hardware surfaces for OpenCL. + * + * data[i] contain 2D image objects (typed in C as cl_mem, used + * in OpenCL as image2d_t) for each plane of the surface. + */ + AV_PIX_FMT_OPENCL, AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; diff --git a/media/ffvpx/libavutil/slicethread.c b/media/ffvpx/libavutil/slicethread.c index c43f87a2a..dfbe551ef 100644 --- a/media/ffvpx/libavutil/slicethread.c +++ b/media/ffvpx/libavutil/slicethread.c @@ -99,10 +99,6 @@ int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, AVSliceThread *ctx; int nb_workers, i; -#if HAVE_W32THREADS - w32thread_init(); -#endif - av_assert0(nb_threads >= 0); if (!nb_threads) { int nb_cpus = av_cpu_count(); diff --git a/media/ffvpx/libavutil/thread.h b/media/ffvpx/libavutil/thread.h index f108e2005..cc5272d37 100644 --- a/media/ffvpx/libavutil/thread.h +++ b/media/ffvpx/libavutil/thread.h @@ -134,6 +134,7 @@ static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_ #endif #define AVMutex pthread_mutex_t +#define AV_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #define ff_mutex_init pthread_mutex_init #define ff_mutex_lock pthread_mutex_lock @@ -148,11 +149,12 @@ static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_ #else #define AVMutex char +#define AV_MUTEX_INITIALIZER 0 -#define ff_mutex_init(mutex, attr) (0) -#define ff_mutex_lock(mutex) (0) -#define ff_mutex_unlock(mutex) (0) -#define ff_mutex_destroy(mutex) (0) +static inline int ff_mutex_init(AVMutex *mutex, const void *attr){ return 0; } +static inline int ff_mutex_lock(AVMutex *mutex){ return 0; } +static inline int ff_mutex_unlock(AVMutex *mutex){ return 0; } +static inline int ff_mutex_destroy(AVMutex *mutex){ return 0; } #define AVOnce char #define AV_ONCE_INIT 0 diff --git a/media/ffvpx/libavutil/timecode.c b/media/ffvpx/libavutil/timecode.c index c0c67c847..60077ba0c 100644 --- a/media/ffvpx/libavutil/timecode.c +++ b/media/ffvpx/libavutil/timecode.c @@ -155,7 +155,7 @@ static int check_fps(int fps) static int check_timecode(void *log_ctx, AVTimecode *tc) { if ((int)tc->fps <= 0) { - av_log(log_ctx, AV_LOG_ERROR, "Timecode frame rate must be specified\n"); + av_log(log_ctx, AV_LOG_ERROR, "Valid timecode frame rate must be specified. Minimum value is 1\n"); return AVERROR(EINVAL); } if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps != 30 && tc->fps != 60) { @@ -214,7 +214,7 @@ int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *st tc->start = (hh*3600 + mm*60 + ss) * tc->fps + ff; if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */ int tmins = 60*hh + mm; - tc->start -= 2 * (tmins - tmins/10); + tc->start -= (tc->fps == 30 ? 2 : 4) * (tmins - tmins/10); } return 0; } diff --git a/media/ffvpx/libavutil/timer.h b/media/ffvpx/libavutil/timer.h index f7ab455df..0bb353cfc 100644 --- a/media/ffvpx/libavutil/timer.h +++ b/media/ffvpx/libavutil/timer.h @@ -42,7 +42,7 @@ #include <stdint.h> #include <inttypes.h> -#if HAVE_MACH_MACH_TIME_H +#if HAVE_MACH_ABSOLUTE_TIME #include <mach/mach_time.h> #endif diff --git a/media/ffvpx/libavutil/utils.c b/media/ffvpx/libavutil/utils.c index 2c170db2e..230081ea4 100644 --- a/media/ffvpx/libavutil/utils.c +++ b/media/ffvpx/libavutil/utils.c @@ -41,9 +41,6 @@ unsigned avutil_version(void) if (checks_done) return LIBAVUTIL_VERSION_INT; -#if FF_API_VDPAU - av_assert0(AV_PIX_FMT_VDA_VLD == 81); //check if the pix fmt enum has not had anything inserted or removed by mistake -#endif av_assert0(AV_SAMPLE_FMT_DBLP == 9); av_assert0(AVMEDIA_TYPE_ATTACHMENT == 4); av_assert0(AV_PICTURE_TYPE_BI == 7); diff --git a/media/ffvpx/libavutil/version.h b/media/ffvpx/libavutil/version.h index f594dc069..3a63e6355 100644 --- a/media/ffvpx/libavutil/version.h +++ b/media/ffvpx/libavutil/version.h @@ -78,9 +78,8 @@ * @{ */ - -#define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 78 +#define LIBAVUTIL_VERSION_MAJOR 56 +#define LIBAVUTIL_VERSION_MINOR 14 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ @@ -106,38 +105,29 @@ * @{ */ -#ifndef FF_API_VDPAU -#define FF_API_VDPAU (LIBAVUTIL_VERSION_MAJOR < 56) -#endif -#ifndef FF_API_XVMC -#define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 56) -#endif -#ifndef FF_API_OPT_TYPE_METADATA -#define FF_API_OPT_TYPE_METADATA (LIBAVUTIL_VERSION_MAJOR < 56) -#endif -#ifndef FF_API_DLOG -#define FF_API_DLOG (LIBAVUTIL_VERSION_MAJOR < 56) -#endif #ifndef FF_API_VAAPI -#define FF_API_VAAPI (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_VAAPI (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_FRAME_QP -#define FF_API_FRAME_QP (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_FRAME_QP (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_PLUS1_MINUS1 -#define FF_API_PLUS1_MINUS1 (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_PLUS1_MINUS1 (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_ERROR_FRAME -#define FF_API_ERROR_FRAME (LIBAVUTIL_VERSION_MAJOR < 56) -#endif -#ifndef FF_API_CRC_BIG_TABLE -#define FF_API_CRC_BIG_TABLE (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_ERROR_FRAME (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_PKT_PTS -#define FF_API_PKT_PTS (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_PKT_PTS (LIBAVUTIL_VERSION_MAJOR < 57) #endif #ifndef FF_API_CRYPTO_SIZE_T -#define FF_API_CRYPTO_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 56) +#define FF_API_CRYPTO_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_FRAME_GET_SET +#define FF_API_FRAME_GET_SET (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_PSEUDOPAL +#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) #endif diff --git a/media/ffvpx/libavutil/x86/cpu.c b/media/ffvpx/libavutil/x86/cpu.c index f33088c8c..aca893174 100644 --- a/media/ffvpx/libavutil/x86/cpu.c +++ b/media/ffvpx/libavutil/x86/cpu.c @@ -97,6 +97,7 @@ int ff_get_cpu_flags_x86(void) int max_std_level, max_ext_level, std_caps = 0, ext_caps = 0; int family = 0, model = 0; union { int i[3]; char c[12]; } vendor; + int xcr0_lo = 0, xcr0_hi = 0; if (!cpuid_test()) return 0; /* CPUID not supported */ @@ -132,8 +133,8 @@ int ff_get_cpu_flags_x86(void) /* Check OXSAVE and AVX bits */ if ((ecx & 0x18000000) == 0x18000000) { /* Check for OS support */ - xgetbv(0, eax, edx); - if ((eax & 0x6) == 0x6) { + xgetbv(0, xcr0_lo, xcr0_hi); + if ((xcr0_lo & 0x6) == 0x6) { rval |= AV_CPU_FLAG_AVX; if (ecx & 0x00001000) rval |= AV_CPU_FLAG_FMA3; @@ -147,6 +148,13 @@ int ff_get_cpu_flags_x86(void) #if HAVE_AVX2 if ((rval & AV_CPU_FLAG_AVX) && (ebx & 0x00000020)) rval |= AV_CPU_FLAG_AVX2; +#if HAVE_AVX512 /* F, CD, BW, DQ, VL */ + if ((xcr0_lo & 0xe0) == 0xe0) { /* OPMASK/ZMM state */ + if ((rval & AV_CPU_FLAG_AVX2) && (ebx & 0xd0030000) == 0xd0030000) + rval |= AV_CPU_FLAG_AVX512; + + } +#endif /* HAVE_AVX512 */ #endif /* HAVE_AVX2 */ /* BMI1/2 don't need OS support */ if (ebx & 0x00000008) { @@ -238,6 +246,8 @@ size_t ff_get_cpu_max_align_x86(void) { int flags = av_get_cpu_flags(); + if (flags & AV_CPU_FLAG_AVX512) + return 64; if (flags & (AV_CPU_FLAG_AVX2 | AV_CPU_FLAG_AVX | AV_CPU_FLAG_XOP | diff --git a/media/ffvpx/libavutil/x86/cpu.h b/media/ffvpx/libavutil/x86/cpu.h index 309b8e746..937c697fa 100644 --- a/media/ffvpx/libavutil/x86/cpu.h +++ b/media/ffvpx/libavutil/x86/cpu.h @@ -19,7 +19,6 @@ #ifndef AVUTIL_X86_CPU_H #define AVUTIL_X86_CPU_H -#include "config.h" #include "libavutil/cpu.h" #include "libavutil/cpu_internal.h" @@ -50,6 +49,7 @@ #define X86_FMA4(flags) CPUEXT(flags, FMA4) #define X86_AVX2(flags) CPUEXT(flags, AVX2) #define X86_AESNI(flags) CPUEXT(flags, AESNI) +#define X86_AVX512(flags) CPUEXT(flags, AVX512) #define EXTERNAL_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOW) #define EXTERNAL_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOWEXT) @@ -79,6 +79,7 @@ #define EXTERNAL_AVX2_FAST(flags) CPUEXT_SUFFIX_FAST2(flags, _EXTERNAL, AVX2, AVX) #define EXTERNAL_AVX2_SLOW(flags) CPUEXT_SUFFIX_SLOW2(flags, _EXTERNAL, AVX2, AVX) #define EXTERNAL_AESNI(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AESNI) +#define EXTERNAL_AVX512(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX512) #define INLINE_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOW) #define INLINE_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOWEXT) diff --git a/media/ffvpx/libavutil/x86/intmath.h b/media/ffvpx/libavutil/x86/intmath.h index e83971c08..40743fd13 100644 --- a/media/ffvpx/libavutil/x86/intmath.h +++ b/media/ffvpx/libavutil/x86/intmath.h @@ -47,7 +47,8 @@ static av_always_inline av_const int ff_log2_x86(unsigned int v) # endif # define ff_log2_16bit av_log2 -#if defined(__INTEL_COMPILER) || (defined(_MSC_VER) && (_MSC_VER >= 1700)) +#if defined(__INTEL_COMPILER) || (defined(_MSC_VER) && (_MSC_VER >= 1700) && \ + (defined(__BMI__) || !defined(__clang__))) # define ff_ctz(v) _tzcnt_u32(v) # if ARCH_X86_64 diff --git a/media/ffvpx/libavutil/x86/x86inc.asm b/media/ffvpx/libavutil/x86/x86inc.asm index 6a054a3e0..5044ee86f 100644 --- a/media/ffvpx/libavutil/x86/x86inc.asm +++ b/media/ffvpx/libavutil/x86/x86inc.asm @@ -1,12 +1,12 @@ ;***************************************************************************** ;* x86inc.asm: x264asm abstraction layer ;***************************************************************************** -;* Copyright (C) 2005-2017 x264 project +;* Copyright (C) 2005-2018 x264 project ;* ;* Authors: Loren Merritt <lorenm@u.washington.edu> +;* Henrik Gramner <henrik@gramner.com> ;* Anton Mitrofanov <BugMaster@narod.ru> ;* Fiona Glaser <fiona@x264.com> -;* Henrik Gramner <henrik@gramner.com> ;* ;* Permission to use, copy, modify, and/or distribute this software for any ;* purpose with or without fee is hereby granted, provided that the above @@ -90,6 +90,10 @@ SECTION .text %elifidn __OUTPUT_FORMAT__,coff SECTION .text + %elifidn __OUTPUT_FORMAT__,win32 + SECTION .rdata align=%1 + %elif WIN64 + SECTION .rdata align=%1 %else SECTION .rodata align=%1 %endif @@ -337,6 +341,8 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %endmacro %define required_stack_alignment ((mmsize + 15) & ~15) +%define vzeroupper_required (mmsize > 16 && (ARCH_X86_64 == 0 || xmm_regs_used > 16 || notcpuflag(avx512))) +%define high_mm_regs (16*cpuflag(avx512)) %macro ALLOC_STACK 1-2 0 ; stack_size, n_xmm_regs (for win64 only) %ifnum %1 @@ -450,15 +456,16 @@ DECLARE_REG 14, R13, 120 %macro WIN64_PUSH_XMM 0 ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated. - %if xmm_regs_used > 6 + %if xmm_regs_used > 6 + high_mm_regs movaps [rstk + stack_offset + 8], xmm6 %endif - %if xmm_regs_used > 7 + %if xmm_regs_used > 7 + high_mm_regs movaps [rstk + stack_offset + 24], xmm7 %endif - %if xmm_regs_used > 8 + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 %assign %%i 8 - %rep xmm_regs_used-8 + %rep %%xmm_regs_on_stack movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i %assign %%i %%i+1 %endrep @@ -467,10 +474,11 @@ DECLARE_REG 14, R13, 120 %macro WIN64_SPILL_XMM 1 %assign xmm_regs_used %1 - ASSERT xmm_regs_used <= 16 - %if xmm_regs_used > 8 + ASSERT xmm_regs_used <= 16 + high_mm_regs + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 ; Allocate stack space for callee-saved xmm registers plus shadow space and align the stack. - %assign %%pad (xmm_regs_used-8)*16 + 32 + %assign %%pad %%xmm_regs_on_stack*16 + 32 %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) SUB rsp, stack_size_padded %endif @@ -479,9 +487,10 @@ DECLARE_REG 14, R13, 120 %macro WIN64_RESTORE_XMM_INTERNAL 0 %assign %%pad_size 0 - %if xmm_regs_used > 8 - %assign %%i xmm_regs_used - %rep xmm_regs_used-8 + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + %assign %%i xmm_regs_used - high_mm_regs + %rep %%xmm_regs_on_stack %assign %%i %%i-1 movaps xmm %+ %%i, [rsp + (%%i-8)*16 + stack_size + 32] %endrep @@ -494,10 +503,10 @@ DECLARE_REG 14, R13, 120 %assign %%pad_size stack_size_padded %endif %endif - %if xmm_regs_used > 7 + %if xmm_regs_used > 7 + high_mm_regs movaps xmm7, [rsp + stack_offset - %%pad_size + 24] %endif - %if xmm_regs_used > 6 + %if xmm_regs_used > 6 + high_mm_regs movaps xmm6, [rsp + stack_offset - %%pad_size + 8] %endif %endmacro @@ -509,12 +518,12 @@ DECLARE_REG 14, R13, 120 %assign xmm_regs_used 0 %endmacro -%define has_epilogue regs_used > 7 || xmm_regs_used > 6 || mmsize == 32 || stack_size > 0 +%define has_epilogue regs_used > 7 || stack_size > 0 || vzeroupper_required || xmm_regs_used > 6+high_mm_regs %macro RET 0 WIN64_RESTORE_XMM_INTERNAL POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7 - %if mmsize == 32 + %if vzeroupper_required vzeroupper %endif AUTO_REP_RET @@ -538,9 +547,10 @@ DECLARE_REG 12, R15, 56 DECLARE_REG 13, R12, 64 DECLARE_REG 14, R13, 72 -%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, [stack_size,] arg_names... +%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %assign num_args %1 %assign regs_used %2 + %assign xmm_regs_used %3 ASSERT regs_used >= num_args SETUP_STACK_POINTER %4 ASSERT regs_used <= 15 @@ -550,7 +560,7 @@ DECLARE_REG 14, R13, 72 DEFINE_ARGS_INTERNAL %0, %4, %5 %endmacro -%define has_epilogue regs_used > 9 || mmsize == 32 || stack_size > 0 +%define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required %macro RET 0 %if stack_size_padded > 0 @@ -561,7 +571,7 @@ DECLARE_REG 14, R13, 72 %endif %endif POP_IF_USED 14, 13, 12, 11, 10, 9 - %if mmsize == 32 + %if vzeroupper_required vzeroupper %endif AUTO_REP_RET @@ -606,7 +616,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 DEFINE_ARGS_INTERNAL %0, %4, %5 %endmacro -%define has_epilogue regs_used > 3 || mmsize == 32 || stack_size > 0 +%define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required %macro RET 0 %if stack_size_padded > 0 @@ -617,7 +627,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 %endif %endif POP_IF_USED 6, 5, 4, 3 - %if mmsize == 32 + %if vzeroupper_required vzeroupper %endif AUTO_REP_RET @@ -727,12 +737,22 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %assign stack_offset 0 ; stack pointer offset relative to the return address %assign stack_size 0 ; amount of stack space that can be freely used inside a function %assign stack_size_padded 0 ; total amount of allocated stack space, including space for callee-saved xmm registers on WIN64 and alignment padding - %assign xmm_regs_used 0 ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64 + %assign xmm_regs_used 0 ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64 and vzeroupper %ifnidn %3, "" PROLOGUE %3 %endif %endmacro +; Create a global symbol from a local label with the correct name mangling and type +%macro cglobal_label 1 + %if FORMAT_ELF + global current_function %+ %1:function hidden + %else + global current_function %+ %1 + %endif + %1: +%endmacro + %macro cextern 1 %xdefine %1 mangle(private_prefix %+ _ %+ %1) CAT_XDEFINE cglobaled_, %1, 1 @@ -803,10 +823,10 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %assign cpuflags_bmi1 (1<<17)| cpuflags_avx|cpuflags_lzcnt %assign cpuflags_bmi2 (1<<18)| cpuflags_bmi1 %assign cpuflags_avx2 (1<<19)| cpuflags_fma3|cpuflags_bmi2 +%assign cpuflags_avx512 (1<<20)| cpuflags_avx2 ; F, CD, BW, DQ, VL -%assign cpuflags_cache32 (1<<20) -%assign cpuflags_cache64 (1<<21) -%assign cpuflags_slowctz (1<<22) +%assign cpuflags_cache32 (1<<21) +%assign cpuflags_cache64 (1<<22) %assign cpuflags_aligned (1<<23) ; not a cpu feature, but a function variant %assign cpuflags_atom (1<<24) @@ -856,11 +876,12 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %endif %endmacro -; Merge mmx and sse* +; Merge mmx, sse*, and avx* ; m# is a simd register of the currently selected size ; xm# is the corresponding xmm register if mmsize >= 16, otherwise the same as m# ; ym# is the corresponding ymm register if mmsize >= 32, otherwise the same as m# -; (All 3 remain in sync through SWAP.) +; zm# is the corresponding zmm register if mmsize >= 64, otherwise the same as m# +; (All 4 remain in sync through SWAP.) %macro CAT_XDEFINE 3 %xdefine %1%2 %3 @@ -870,69 +891,99 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, %undef %1%2 %endmacro +%macro DEFINE_MMREGS 1 ; mmtype + %assign %%prev_mmregs 0 + %ifdef num_mmregs + %assign %%prev_mmregs num_mmregs + %endif + + %assign num_mmregs 8 + %if ARCH_X86_64 && mmsize >= 16 + %assign num_mmregs 16 + %if cpuflag(avx512) || mmsize == 64 + %assign num_mmregs 32 + %endif + %endif + + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE m, %%i, %1 %+ %%i + CAT_XDEFINE nn%1, %%i, %%i + %assign %%i %%i+1 + %endrep + %if %%prev_mmregs > num_mmregs + %rep %%prev_mmregs - num_mmregs + CAT_UNDEF m, %%i + CAT_UNDEF nn %+ mmtype, %%i + %assign %%i %%i+1 + %endrep + %endif + %xdefine mmtype %1 +%endmacro + +; Prefer registers 16-31 over 0-15 to avoid having to use vzeroupper +%macro AVX512_MM_PERMUTATION 0-1 0 ; start_reg + %if ARCH_X86_64 && cpuflag(avx512) + %assign %%i %1 + %rep 16-%1 + %assign %%i_high %%i+16 + SWAP %%i, %%i_high + %assign %%i %%i+1 + %endrep + %endif +%endmacro + %macro INIT_MMX 0-1+ %assign avx_enabled 0 %define RESET_MM_PERMUTATION INIT_MMX %1 %define mmsize 8 - %define num_mmregs 8 %define mova movq %define movu movq %define movh movd %define movnta movntq - %assign %%i 0 - %rep 8 - CAT_XDEFINE m, %%i, mm %+ %%i - CAT_XDEFINE nnmm, %%i, %%i - %assign %%i %%i+1 - %endrep - %rep 8 - CAT_UNDEF m, %%i - CAT_UNDEF nnmm, %%i - %assign %%i %%i+1 - %endrep INIT_CPUFLAGS %1 + DEFINE_MMREGS mm %endmacro %macro INIT_XMM 0-1+ %assign avx_enabled 0 %define RESET_MM_PERMUTATION INIT_XMM %1 %define mmsize 16 - %define num_mmregs 8 - %if ARCH_X86_64 - %define num_mmregs 16 - %endif %define mova movdqa %define movu movdqu %define movh movq %define movnta movntdq - %assign %%i 0 - %rep num_mmregs - CAT_XDEFINE m, %%i, xmm %+ %%i - CAT_XDEFINE nnxmm, %%i, %%i - %assign %%i %%i+1 - %endrep INIT_CPUFLAGS %1 + DEFINE_MMREGS xmm + %if WIN64 + AVX512_MM_PERMUTATION 6 ; Swap callee-saved registers with volatile registers + %endif %endmacro %macro INIT_YMM 0-1+ %assign avx_enabled 1 %define RESET_MM_PERMUTATION INIT_YMM %1 %define mmsize 32 - %define num_mmregs 8 - %if ARCH_X86_64 - %define num_mmregs 16 - %endif %define mova movdqa %define movu movdqu %undef movh %define movnta movntdq - %assign %%i 0 - %rep num_mmregs - CAT_XDEFINE m, %%i, ymm %+ %%i - CAT_XDEFINE nnymm, %%i, %%i - %assign %%i %%i+1 - %endrep INIT_CPUFLAGS %1 + DEFINE_MMREGS ymm + AVX512_MM_PERMUTATION +%endmacro + +%macro INIT_ZMM 0-1+ + %assign avx_enabled 1 + %define RESET_MM_PERMUTATION INIT_ZMM %1 + %define mmsize 64 + %define mova movdqa + %define movu movdqu + %undef movh + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS zmm + AVX512_MM_PERMUTATION %endmacro INIT_XMM @@ -941,18 +992,26 @@ INIT_XMM %define mmmm%1 mm%1 %define mmxmm%1 mm%1 %define mmymm%1 mm%1 + %define mmzmm%1 mm%1 %define xmmmm%1 mm%1 %define xmmxmm%1 xmm%1 %define xmmymm%1 xmm%1 + %define xmmzmm%1 xmm%1 %define ymmmm%1 mm%1 %define ymmxmm%1 xmm%1 %define ymmymm%1 ymm%1 + %define ymmzmm%1 ymm%1 + %define zmmmm%1 mm%1 + %define zmmxmm%1 xmm%1 + %define zmmymm%1 ymm%1 + %define zmmzmm%1 zmm%1 %define xm%1 xmm %+ m%1 %define ym%1 ymm %+ m%1 + %define zm%1 zmm %+ m%1 %endmacro %assign i 0 -%rep 16 +%rep 32 DECLARE_MMCAST i %assign i i+1 %endrep @@ -1087,12 +1146,17 @@ INIT_XMM ;============================================================================= %assign i 0 -%rep 16 +%rep 32 %if i < 8 CAT_XDEFINE sizeofmm, i, 8 + CAT_XDEFINE regnumofmm, i, i %endif CAT_XDEFINE sizeofxmm, i, 16 CAT_XDEFINE sizeofymm, i, 32 + CAT_XDEFINE sizeofzmm, i, 64 + CAT_XDEFINE regnumofxmm, i, i + CAT_XDEFINE regnumofymm, i, i + CAT_XDEFINE regnumofzmm, i, i %assign i i+1 %endrep %undef i @@ -1209,7 +1273,7 @@ INIT_XMM %endmacro %endmacro -; Instructions with both VEX and non-VEX encodings +; Instructions with both VEX/EVEX and legacy encodings ; Non-destructive instructions are written without parameters AVX_INSTR addpd, sse2, 1, 0, 1 AVX_INSTR addps, sse, 1, 0, 1 @@ -1231,10 +1295,42 @@ AVX_INSTR blendpd, sse4, 1, 1, 0 AVX_INSTR blendps, sse4, 1, 1, 0 AVX_INSTR blendvpd, sse4 ; can't be emulated AVX_INSTR blendvps, sse4 ; can't be emulated +AVX_INSTR cmpeqpd, sse2, 1, 0, 1 +AVX_INSTR cmpeqps, sse, 1, 0, 1 +AVX_INSTR cmpeqsd, sse2, 1, 0, 0 +AVX_INSTR cmpeqss, sse, 1, 0, 0 +AVX_INSTR cmplepd, sse2, 1, 0, 0 +AVX_INSTR cmpleps, sse, 1, 0, 0 +AVX_INSTR cmplesd, sse2, 1, 0, 0 +AVX_INSTR cmpless, sse, 1, 0, 0 +AVX_INSTR cmpltpd, sse2, 1, 0, 0 +AVX_INSTR cmpltps, sse, 1, 0, 0 +AVX_INSTR cmpltsd, sse2, 1, 0, 0 +AVX_INSTR cmpltss, sse, 1, 0, 0 +AVX_INSTR cmpneqpd, sse2, 1, 0, 1 +AVX_INSTR cmpneqps, sse, 1, 0, 1 +AVX_INSTR cmpneqsd, sse2, 1, 0, 0 +AVX_INSTR cmpneqss, sse, 1, 0, 0 +AVX_INSTR cmpnlepd, sse2, 1, 0, 0 +AVX_INSTR cmpnleps, sse, 1, 0, 0 +AVX_INSTR cmpnlesd, sse2, 1, 0, 0 +AVX_INSTR cmpnless, sse, 1, 0, 0 +AVX_INSTR cmpnltpd, sse2, 1, 0, 0 +AVX_INSTR cmpnltps, sse, 1, 0, 0 +AVX_INSTR cmpnltsd, sse2, 1, 0, 0 +AVX_INSTR cmpnltss, sse, 1, 0, 0 +AVX_INSTR cmpordpd, sse2 1, 0, 1 +AVX_INSTR cmpordps, sse 1, 0, 1 +AVX_INSTR cmpordsd, sse2 1, 0, 0 +AVX_INSTR cmpordss, sse 1, 0, 0 AVX_INSTR cmppd, sse2, 1, 1, 0 AVX_INSTR cmpps, sse, 1, 1, 0 AVX_INSTR cmpsd, sse2, 1, 1, 0 AVX_INSTR cmpss, sse, 1, 1, 0 +AVX_INSTR cmpunordpd, sse2, 1, 0, 1 +AVX_INSTR cmpunordps, sse, 1, 0, 1 +AVX_INSTR cmpunordsd, sse2, 1, 0, 0 +AVX_INSTR cmpunordss, sse, 1, 0, 0 AVX_INSTR comisd, sse2 AVX_INSTR comiss, sse AVX_INSTR cvtdq2pd, sse2 @@ -1545,6 +1641,52 @@ FMA4_INSTR fmsubadd, pd, ps FMA4_INSTR fnmadd, pd, ps, sd, ss FMA4_INSTR fnmsub, pd, ps, sd, ss +; Macros for converting VEX instructions to equivalent EVEX ones. +%macro EVEX_INSTR 2-3 0 ; vex, evex, prefer_evex + %macro %1 2-7 fnord, fnord, %1, %2, %3 + %ifidn %3, fnord + %define %%args %1, %2 + %elifidn %4, fnord + %define %%args %1, %2, %3 + %else + %define %%args %1, %2, %3, %4 + %endif + %assign %%evex_required cpuflag(avx512) & %7 + %ifnum regnumof%1 + %if regnumof%1 >= 16 || sizeof%1 > 32 + %assign %%evex_required 1 + %endif + %endif + %ifnum regnumof%2 + %if regnumof%2 >= 16 || sizeof%2 > 32 + %assign %%evex_required 1 + %endif + %endif + %if %%evex_required + %6 %%args + %else + %5 %%args ; Prefer VEX over EVEX due to shorter instruction length + %endif + %endmacro +%endmacro + +EVEX_INSTR vbroadcastf128, vbroadcastf32x4 +EVEX_INSTR vbroadcasti128, vbroadcasti32x4 +EVEX_INSTR vextractf128, vextractf32x4 +EVEX_INSTR vextracti128, vextracti32x4 +EVEX_INSTR vinsertf128, vinsertf32x4 +EVEX_INSTR vinserti128, vinserti32x4 +EVEX_INSTR vmovdqa, vmovdqa32 +EVEX_INSTR vmovdqu, vmovdqu32 +EVEX_INSTR vpand, vpandd +EVEX_INSTR vpandn, vpandnd +EVEX_INSTR vpor, vpord +EVEX_INSTR vpxor, vpxord +EVEX_INSTR vrcpps, vrcp14ps, 1 ; EVEX versions have higher precision +EVEX_INSTR vrcpss, vrcp14ss, 1 +EVEX_INSTR vrsqrtps, vrsqrt14ps, 1 +EVEX_INSTR vrsqrtss, vrsqrt14ss, 1 + ; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug (fixed in 1.3.0) %ifdef __YASM_VER__ %if __YASM_VERSION_ID__ < 0x01030000 && ARCH_X86_64 == 0 diff --git a/media/ffvpx/libavutil/x86/x86util.asm b/media/ffvpx/libavutil/x86/x86util.asm index e1220dfc1..d7cd99684 100644 --- a/media/ffvpx/libavutil/x86/x86util.asm +++ b/media/ffvpx/libavutil/x86/x86util.asm @@ -357,7 +357,7 @@ %endif %endmacro -%macro ABSB 2 ; source mmreg, temp mmreg (unused for ssse3) +%macro ABSB 2 ; source mmreg, temp mmreg (unused for SSSE3) %if cpuflag(ssse3) pabsb %1, %1 %else @@ -381,7 +381,7 @@ %endif %endmacro -%macro ABSD2_MMX 4 +%macro ABSD2 4 pxor %3, %3 pxor %4, %4 pcmpgtd %3, %1 @@ -475,7 +475,7 @@ %else palignr %1, %2, %3 %endif -%elif cpuflag(mmx) ; [dst,] src1, src2, imm, tmp +%else ; [dst,] src1, src2, imm, tmp %define %%dst %1 %if %0==5 %ifnidn %1, %2 @@ -799,37 +799,47 @@ pminsw %1, %3 %endmacro -%macro PMINSD_MMX 3 ; dst, src, tmp +%macro PMINSD 3 ; dst, src, tmp/unused +%if cpuflag(sse4) + pminsd %1, %2 +%elif cpuflag(sse2) + cvtdq2ps %1, %1 + minps %1, %2 + cvtps2dq %1, %1 +%else mova %3, %2 pcmpgtd %3, %1 pxor %1, %2 pand %1, %3 pxor %1, %2 +%endif %endmacro -%macro PMAXSD_MMX 3 ; dst, src, tmp +%macro PMAXSD 3 ; dst, src, tmp/unused +%if cpuflag(sse4) + pmaxsd %1, %2 +%else mova %3, %1 pcmpgtd %3, %2 pand %1, %3 pandn %3, %2 por %1, %3 +%endif %endmacro -%macro CLIPD_MMX 3-4 ; src/dst, min, max, tmp - PMINSD_MMX %1, %3, %4 - PMAXSD_MMX %1, %2, %4 -%endmacro - -%macro CLIPD_SSE2 3-4 ; src/dst, min (float), max (float), unused +%macro CLIPD 3-4 +%if cpuflag(sse4); src/dst, min, max, unused + pminsd %1, %3 + pmaxsd %1, %2 +%elif cpuflag(sse2) ; src/dst, min (float), max (float), unused cvtdq2ps %1, %1 minps %1, %3 maxps %1, %2 cvtps2dq %1, %1 -%endmacro - -%macro CLIPD_SSE41 3-4 ; src/dst, min, max, unused - pminsd %1, %3 - pmaxsd %1, %2 +%else ; src/dst, min, max, tmp + PMINSD %1, %3, %4 + PMAXSD %1, %2, %4 +%endif %endmacro %macro VBROADCASTSS 2 ; dst xmm/ymm, src m32/xmm @@ -880,6 +890,14 @@ %endif %endmacro +%macro VBROADCASTI128 2 ; dst xmm/ymm, src : 128bits val +%if mmsize > 16 + vbroadcasti128 %1, %2 +%else + mova %1, %2 +%endif +%endmacro + %macro SHUFFLE_MASK_W 8 %rep 8 %if %1>=0x80 |