summaryrefslogtreecommitdiffstats
path: root/media/ffvpx/libavutil
diff options
context:
space:
mode:
Diffstat (limited to 'media/ffvpx/libavutil')
-rw-r--r--media/ffvpx/libavutil/aarch64/cpu.c30
-rw-r--r--media/ffvpx/libavutil/arm/float_dsp_init_vfp.c2
-rw-r--r--media/ffvpx/libavutil/avstring.c2
-rw-r--r--media/ffvpx/libavutil/avutil.h13
-rw-r--r--media/ffvpx/libavutil/avutil.symbols31
-rw-r--r--media/ffvpx/libavutil/bprint.h12
-rw-r--r--media/ffvpx/libavutil/channel_layout.c543
-rw-r--r--media/ffvpx/libavutil/channel_layout.h228
-rw-r--r--media/ffvpx/libavutil/color_utils.c234
-rw-r--r--media/ffvpx/libavutil/color_utils.h56
-rw-r--r--media/ffvpx/libavutil/common.h21
-rw-r--r--media/ffvpx/libavutil/cpu.c6
-rw-r--r--media/ffvpx/libavutil/csp.h150
-rw-r--r--media/ffvpx/libavutil/dict.c10
-rw-r--r--media/ffvpx/libavutil/eval.c3
-rw-r--r--media/ffvpx/libavutil/fftime.h1
-rw-r--r--media/ffvpx/libavutil/ffversion.h2
-rw-r--r--media/ffvpx/libavutil/fifo.c219
-rw-r--r--media/ffvpx/libavutil/fifo.h206
-rw-r--r--media/ffvpx/libavutil/film_grain_params.c68
-rw-r--r--media/ffvpx/libavutil/film_grain_params.h68
-rw-r--r--media/ffvpx/libavutil/fixed_dsp.c3
-rw-r--r--media/ffvpx/libavutil/fixed_dsp.h3
-rw-r--r--media/ffvpx/libavutil/float_dsp.c2
-rw-r--r--media/ffvpx/libavutil/float_dsp.h4
-rw-r--r--media/ffvpx/libavutil/frame.c400
-rw-r--r--media/ffvpx/libavutil/frame.h184
-rw-r--r--media/ffvpx/libavutil/hdr_dynamic_metadata.h4
-rw-r--r--media/ffvpx/libavutil/hwcontext.c290
-rw-r--r--media/ffvpx/libavutil/hwcontext.h25
-rw-r--r--media/ffvpx/libavutil/hwcontext_internal.h30
-rw-r--r--media/ffvpx/libavutil/hwcontext_vaapi.c52
-rw-r--r--media/ffvpx/libavutil/imgutils.c2
-rw-r--r--media/ffvpx/libavutil/imgutils_internal.h4
-rw-r--r--media/ffvpx/libavutil/internal.h16
-rw-r--r--media/ffvpx/libavutil/intreadwrite.h4
-rw-r--r--media/ffvpx/libavutil/mem.c6
-rw-r--r--media/ffvpx/libavutil/mem.h2
-rw-r--r--media/ffvpx/libavutil/mem_internal.h35
-rw-r--r--media/ffvpx/libavutil/moz.build8
-rw-r--r--media/ffvpx/libavutil/opt.c1059
-rw-r--r--media/ffvpx/libavutil/opt.h601
-rw-r--r--media/ffvpx/libavutil/pixdesc.c9
-rw-r--r--media/ffvpx/libavutil/pixfmt.h14
-rw-r--r--media/ffvpx/libavutil/rational.c2
-rw-r--r--media/ffvpx/libavutil/rational.h4
-rw-r--r--media/ffvpx/libavutil/thread.h20
-rw-r--r--media/ffvpx/libavutil/timecode.c2
-rw-r--r--media/ffvpx/libavutil/timestamp.h15
-rw-r--r--media/ffvpx/libavutil/tx.c22
-rw-r--r--media/ffvpx/libavutil/tx_template.c2
-rw-r--r--media/ffvpx/libavutil/version.h27
-rw-r--r--media/ffvpx/libavutil/x86/emms.h58
-rw-r--r--media/ffvpx/libavutil/x86/fixed_dsp_init.c4
-rw-r--r--media/ffvpx/libavutil/x86/float_dsp_init.c5
-rw-r--r--media/ffvpx/libavutil/x86/intreadwrite.h36
-rw-r--r--media/ffvpx/libavutil/x86/moz.build2
-rw-r--r--media/ffvpx/libavutil/x86/tx_float.asm8
-rw-r--r--media/ffvpx/libavutil/x86/tx_float_init.c19
-rw-r--r--media/ffvpx/libavutil/x86/x86inc.asm672
-rw-r--r--media/ffvpx/libavutil/x86/x86util.asm4
61 files changed, 2724 insertions, 2840 deletions
diff --git a/media/ffvpx/libavutil/aarch64/cpu.c b/media/ffvpx/libavutil/aarch64/cpu.c
index f27fef3992..7a05391343 100644
--- a/media/ffvpx/libavutil/aarch64/cpu.c
+++ b/media/ffvpx/libavutil/aarch64/cpu.c
@@ -24,34 +24,20 @@
#include <stdint.h>
#include <sys/auxv.h>
-#define get_cpu_feature_reg(reg, val) \
- __asm__("mrs %0, " #reg : "=r" (val))
+#define HWCAP_AARCH64_ASIMDDP (1 << 20)
+#define HWCAP2_AARCH64_I8MM (1 << 13)
static int detect_flags(void)
{
int flags = 0;
-#if defined(HWCAP_CPUID) && HAVE_INLINE_ASM
unsigned long hwcap = getauxval(AT_HWCAP);
- // We can check for DOTPROD and I8MM using HWCAP_ASIMDDP and
- // HWCAP2_I8MM too, avoiding to read the CPUID registers (which triggers
- // a trap, handled by the kernel). However the HWCAP_* defines for these
- // extensions are added much later than HWCAP_CPUID, so the userland
- // headers might lack support for them even if the binary later is run
- // on hardware that does support it (and where the kernel might support
- // HWCAP_CPUID).
- // See https://www.kernel.org/doc/html/latest/arm64/cpu-feature-registers.html
- if (hwcap & HWCAP_CPUID) {
- uint64_t tmp;
-
- get_cpu_feature_reg(ID_AA64ISAR0_EL1, tmp);
- if (((tmp >> 44) & 0xf) == 0x1)
- flags |= AV_CPU_FLAG_DOTPROD;
- get_cpu_feature_reg(ID_AA64ISAR1_EL1, tmp);
- if (((tmp >> 52) & 0xf) == 0x1)
- flags |= AV_CPU_FLAG_I8MM;
- }
-#endif
+ unsigned long hwcap2 = getauxval(AT_HWCAP2);
+
+ if (hwcap & HWCAP_AARCH64_ASIMDDP)
+ flags |= AV_CPU_FLAG_DOTPROD;
+ if (hwcap2 & HWCAP2_AARCH64_I8MM)
+ flags |= AV_CPU_FLAG_I8MM;
return flags;
}
diff --git a/media/ffvpx/libavutil/arm/float_dsp_init_vfp.c b/media/ffvpx/libavutil/arm/float_dsp_init_vfp.c
index 05873e7e37..6d6237aae8 100644
--- a/media/ffvpx/libavutil/arm/float_dsp_init_vfp.c
+++ b/media/ffvpx/libavutil/arm/float_dsp_init_vfp.c
@@ -32,7 +32,7 @@ void ff_vector_fmul_window_vfp(float *dst, const float *src0,
void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
const float *src1, int len);
-void ff_butterflies_float_vfp(float *av_restrict v1, float *av_restrict v2, int len);
+void ff_butterflies_float_vfp(float *restrict v1, float *restrict v2, int len);
av_cold void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags)
{
diff --git a/media/ffvpx/libavutil/avstring.c b/media/ffvpx/libavutil/avstring.c
index 8751ce5576..2071dd36a5 100644
--- a/media/ffvpx/libavutil/avstring.c
+++ b/media/ffvpx/libavutil/avstring.c
@@ -345,7 +345,7 @@ int av_escape(char **dst, const char *src, const char *special_chars,
int av_match_name(const char *name, const char *names)
{
const char *p;
- int len, namelen;
+ size_t len, namelen;
if (!name || !names)
return 0;
diff --git a/media/ffvpx/libavutil/avutil.h b/media/ffvpx/libavutil/avutil.h
index a362c8baa8..d2900dcb48 100644
--- a/media/ffvpx/libavutil/avutil.h
+++ b/media/ffvpx/libavutil/avutil.h
@@ -335,19 +335,6 @@ unsigned av_int_list_length_for_size(unsigned elsize,
#define av_int_list_length(list, term) \
av_int_list_length_for_size(sizeof(*(list)), list, term)
-#if FF_API_AV_FOPEN_UTF8
-/**
- * Open a file using a UTF-8 filename.
- * The API of this function matches POSIX fopen(), errors are returned through
- * errno.
- * @deprecated Avoid using it, as on Windows, the FILE* allocated by this
- * function may be allocated with a different CRT than the caller
- * who uses the FILE*. No replacement provided in public API.
- */
-attribute_deprecated
-FILE *av_fopen_utf8(const char *path, const char *mode);
-#endif
-
/**
* Return the fractional representation of the internal time base.
*/
diff --git a/media/ffvpx/libavutil/avutil.symbols b/media/ffvpx/libavutil/avutil.symbols
index 5ee7afb855..75f5625d98 100644
--- a/media/ffvpx/libavutil/avutil.symbols
+++ b/media/ffvpx/libavutil/avutil.symbols
@@ -8,7 +8,6 @@ av_base64_decode
av_base64_encode
#endif
av_bprint_append_data
-av_bprint_channel_layout
av_bprint_chars
av_bprint_clear
av_bprint_escape
@@ -39,7 +38,6 @@ av_channel_layout_compare
av_channel_layout_copy
av_channel_layout_default
av_channel_layout_describe
-av_channel_layout_extract_channel
av_channel_layout_from_mask
av_channel_layout_from_mask
av_channel_layout_uninit
@@ -52,9 +50,7 @@ av_color_space_name
av_color_transfer_name
av_compare_mod
av_compare_ts
-#ifndef MOZ_FFVPX_AUDIOONLY
av_content_light_metadata_create_side_data
-#endif
av_cpu_count
av_crc
av_crc_get_table
@@ -88,26 +84,13 @@ av_expr_parse_and_eval
av_fast_malloc
av_fast_mallocz
av_fast_realloc
-av_fifo_alloc
av_fifo_alloc2
-av_fifo_alloc_array
av_fifo_can_read
av_fifo_can_write
-av_fifo_drain
av_fifo_drain2
-av_fifo_free
-av_fifo_freep
av_fifo_freep2
-av_fifo_generic_peek
-av_fifo_generic_read
-av_fifo_generic_write
-av_fifo_grow
av_fifo_peek
-av_fifo_realloc2
av_fifo_read
-av_fifo_reset
-av_fifo_size
-av_fifo_space
av_fifo_write
av_find_best_pix_fmt_of_2
av_find_info_tag
@@ -122,6 +105,8 @@ av_frame_apply_cropping
av_frame_clone
av_frame_copy
av_frame_copy_props
+av_frame_side_data_free
+av_frame_side_data_get_c
av_frame_free
av_frame_get_buffer
av_frame_get_plane_buffer
@@ -142,14 +127,7 @@ av_gcd
av_get_alt_sample_fmt
av_get_bits_per_pixel
av_get_bytes_per_sample
-av_get_channel_description
-av_get_channel_layout
-av_get_channel_layout_channel_index
-av_get_channel_layout_nb_channels
-av_get_channel_layout_string
-av_get_channel_name
av_get_cpu_flags
-av_get_default_channel_layout
av_get_known_color_name
av_get_media_type_string
av_get_packed_sample_fmt
@@ -162,7 +140,6 @@ av_get_pix_fmt_string
av_get_planar_sample_fmt
av_get_sample_fmt
av_get_sample_fmt_string
-av_get_standard_channel_layout
av_get_time_base_q
av_get_token
av_gettime
@@ -201,9 +178,7 @@ av_log_set_flags
av_log_set_level
av_mallocz
av_malloc
-#ifndef MOZ_FFVPX_AUDIOONLY
av_mastering_display_metadata_create_side_data
-#endif
av_match_list
av_match_name
av_max_alloc
@@ -225,7 +200,6 @@ av_opt_flag_is_set
av_opt_free
av_opt_freep_ranges
av_opt_get
-av_opt_get_channel_layout
av_opt_get_dict_val
av_opt_get_double
av_opt_get_image_size
@@ -244,7 +218,6 @@ av_opt_query_ranges_default
av_opt_serialize
av_opt_set
av_opt_set_bin
-av_opt_set_channel_layout
av_opt_set_defaults
av_opt_set_defaults2
av_opt_set_dict
diff --git a/media/ffvpx/libavutil/bprint.h b/media/ffvpx/libavutil/bprint.h
index 8559745478..4ac8570561 100644
--- a/media/ffvpx/libavutil/bprint.h
+++ b/media/ffvpx/libavutil/bprint.h
@@ -172,9 +172,9 @@ void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
/**
* Append data to a print buffer.
*
- * param buf bprint buffer to use
- * param data pointer to data
- * param size size of data
+ * @param buf bprint buffer to use
+ * @param data pointer to data
+ * @param size size of data
*/
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size);
@@ -182,9 +182,9 @@ struct tm;
/**
* Append a formatted date and time to a print buffer.
*
- * param buf bprint buffer to use
- * param fmt date and time format string, see strftime()
- * param tm broken-down time structure to translate
+ * @param buf bprint buffer to use
+ * @param fmt date and time format string, see strftime()
+ * @param tm broken-down time structure to translate
*
* @note due to poor design of the standard strftime function, it may
* produce poor results if the format string expands to a very long text and
diff --git a/media/ffvpx/libavutil/channel_layout.c b/media/ffvpx/libavutil/channel_layout.c
index b59d798f29..fd6718e0e7 100644
--- a/media/ffvpx/libavutil/channel_layout.c
+++ b/media/ffvpx/libavutil/channel_layout.c
@@ -33,6 +33,7 @@
#include "common.h"
#include "error.h"
#include "macros.h"
+#include "mem.h"
#include "opt.h"
#define CHAN_IS_AMBI(x) ((x) >= AV_CHAN_AMBISONIC_BASE &&\
@@ -76,14 +77,6 @@ static const struct channel_name channel_names[] = {
[AV_CHAN_BOTTOM_FRONT_RIGHT ] = { "BFR", "bottom front right" },
};
-static const char *get_channel_name(enum AVChannel channel_id)
-{
- if ((unsigned) channel_id >= FF_ARRAY_ELEMS(channel_names) ||
- !channel_names[channel_id].name)
- return NULL;
- return channel_names[channel_id].name;
-}
-
void av_channel_name_bprint(AVBPrint *bp, enum AVChannel channel_id)
{
if (channel_id >= AV_CHAN_AMBISONIC_BASE &&
@@ -94,6 +87,10 @@ void av_channel_name_bprint(AVBPrint *bp, enum AVChannel channel_id)
av_bprintf(bp, "%s", channel_names[channel_id].name);
else if (channel_id == AV_CHAN_NONE)
av_bprintf(bp, "NONE");
+ else if (channel_id == AV_CHAN_UNKNOWN)
+ av_bprintf(bp, "UNK");
+ else if (channel_id == AV_CHAN_UNUSED)
+ av_bprintf(bp, "UNSD");
else
av_bprintf(bp, "USR%d", channel_id);
}
@@ -123,6 +120,10 @@ void av_channel_description_bprint(AVBPrint *bp, enum AVChannel channel_id)
av_bprintf(bp, "%s", channel_names[channel_id].description);
else if (channel_id == AV_CHAN_NONE)
av_bprintf(bp, "none");
+ else if (channel_id == AV_CHAN_UNKNOWN)
+ av_bprintf(bp, "unknown");
+ else if (channel_id == AV_CHAN_UNUSED)
+ av_bprintf(bp, "unused");
else
av_bprintf(bp, "user %d", channel_id);
}
@@ -159,6 +160,11 @@ enum AVChannel av_channel_from_string(const char *str)
if (channel_names[i].name && !strcmp(str, channel_names[i].name))
return i;
}
+ if (!strcmp(str, "UNK"))
+ return AV_CHAN_UNKNOWN;
+ if (!strcmp(str, "UNSD"))
+ return AV_CHAN_UNUSED;
+
if (!strncmp(str, "USR", 3)) {
const char *p = str + 3;
id = strtol(p, &endptr, 0);
@@ -214,199 +220,82 @@ static const struct channel_layout_name channel_layout_map[] = {
{ "22.2", AV_CHANNEL_LAYOUT_22POINT2, },
};
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
-static uint64_t get_channel_layout_single(const char *name, int name_len)
+int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
{
- int i;
- char *end;
- int64_t layout;
-
- for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
- if (strlen(channel_layout_map[i].name) == name_len &&
- !memcmp(channel_layout_map[i].name, name, name_len))
- return channel_layout_map[i].layout.u.mask;
- }
- for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
- if (channel_names[i].name &&
- strlen(channel_names[i].name) == name_len &&
- !memcmp(channel_names[i].name, name, name_len))
- return (int64_t)1 << i;
-
- errno = 0;
- i = strtol(name, &end, 10);
-
- if (!errno && (end + 1 - name == name_len && *end == 'c'))
- return av_get_default_channel_layout(i);
-
- errno = 0;
- layout = strtoll(name, &end, 0);
- if (!errno && end - name == name_len)
- return FFMAX(layout, 0);
- return 0;
-}
-
-uint64_t av_get_channel_layout(const char *name)
-{
- const char *n, *e;
- const char *name_end = name + strlen(name);
- int64_t layout = 0, layout_single;
-
- for (n = name; n < name_end; n = e + 1) {
- for (e = n; e < name_end && *e != '+' && *e != '|'; e++);
- layout_single = get_channel_layout_single(n, e - n);
- if (!layout_single)
- return 0;
- layout |= layout_single;
- }
- return layout;
-}
-
-int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels)
-{
- int nb = 0;
- char *end;
- uint64_t layout = av_get_channel_layout(name);
-
- if (layout) {
- *channel_layout = layout;
- *nb_channels = av_get_channel_layout_nb_channels(layout);
- return 0;
- }
-
- nb = strtol(name, &end, 10);
- if (!errno && *end == 'C' && *(end + 1) == '\0' && nb > 0 && nb < 64) {
- *channel_layout = 0;
- *nb_channels = nb;
- return 0;
- }
-
- return AVERROR(EINVAL);
-}
-
-void av_bprint_channel_layout(struct AVBPrint *bp,
- int nb_channels, uint64_t channel_layout)
-{
- int i;
+ AVChannelCustom *map;
if (nb_channels <= 0)
- nb_channels = av_get_channel_layout_nb_channels(channel_layout);
-
- for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
- if (nb_channels == channel_layout_map[i].layout.nb_channels &&
- channel_layout == channel_layout_map[i].layout.u.mask) {
- av_bprintf(bp, "%s", channel_layout_map[i].name);
- return;
- }
-
- av_bprintf(bp, "%d channels", nb_channels);
- if (channel_layout) {
- int i, ch;
- av_bprintf(bp, " (");
- for (i = 0, ch = 0; i < 64; i++) {
- if ((channel_layout & (UINT64_C(1) << i))) {
- const char *name = get_channel_name(i);
- if (name) {
- if (ch > 0)
- av_bprintf(bp, "+");
- av_bprintf(bp, "%s", name);
- }
- ch++;
- }
- }
- av_bprintf(bp, ")");
- }
-}
-
-void av_get_channel_layout_string(char *buf, int buf_size,
- int nb_channels, uint64_t channel_layout)
-{
- AVBPrint bp;
+ return AVERROR(EINVAL);
- av_bprint_init_for_buffer(&bp, buf, buf_size);
- av_bprint_channel_layout(&bp, nb_channels, channel_layout);
-}
+ map = av_calloc(nb_channels, sizeof(*channel_layout->u.map));
+ if (!map)
+ return AVERROR(ENOMEM);
+ for (int i = 0; i < nb_channels; i++)
+ map[i].id = AV_CHAN_UNKNOWN;
-int av_get_channel_layout_nb_channels(uint64_t channel_layout)
-{
- return av_popcount64(channel_layout);
-}
+ channel_layout->order = AV_CHANNEL_ORDER_CUSTOM;
+ channel_layout->nb_channels = nb_channels;
+ channel_layout->u.map = map;
-int64_t av_get_default_channel_layout(int nb_channels) {
- int i;
- for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
- if (nb_channels == channel_layout_map[i].layout.nb_channels)
- return channel_layout_map[i].layout.u.mask;
return 0;
}
-int av_get_channel_layout_channel_index(uint64_t channel_layout,
- uint64_t channel)
+int av_channel_layout_from_mask(AVChannelLayout *channel_layout,
+ uint64_t mask)
{
- if (!(channel_layout & channel) ||
- av_get_channel_layout_nb_channels(channel) != 1)
+ if (!mask)
return AVERROR(EINVAL);
- channel_layout &= channel - 1;
- return av_get_channel_layout_nb_channels(channel_layout);
-}
-const char *av_get_channel_name(uint64_t channel)
-{
- int i;
- if (av_get_channel_layout_nb_channels(channel) != 1)
- return NULL;
- for (i = 0; i < 64; i++)
- if ((1ULL<<i) & channel)
- return get_channel_name(i);
- return NULL;
-}
+ channel_layout->order = AV_CHANNEL_ORDER_NATIVE;
+ channel_layout->nb_channels = av_popcount64(mask);
+ channel_layout->u.mask = mask;
-const char *av_get_channel_description(uint64_t channel)
-{
- int i;
- if (av_get_channel_layout_nb_channels(channel) != 1)
- return NULL;
- for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
- if ((1ULL<<i) & channel)
- return channel_names[i].description;
- return NULL;
+ return 0;
}
-uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
+static int parse_channel_list(AVChannelLayout *ch_layout, const char *str)
{
- int i;
+ int ret;
+ int nb_channels = 0;
+ AVChannelCustom *map = NULL;
+ AVChannelCustom custom = {0};
- if (av_get_channel_layout_nb_channels(channel_layout) <= index)
- return 0;
+ while (*str) {
+ char *channel, *chname;
+ int ret = av_opt_get_key_value(&str, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname);
+ if (ret < 0) {
+ av_freep(&map);
+ return ret;
+ }
+ if (*str)
+ str++; // skip separator
+ if (!channel) {
+ channel = chname;
+ chname = NULL;
+ }
+ av_strlcpy(custom.name, chname ? chname : "", sizeof(custom.name));
+ custom.id = av_channel_from_string(channel);
+ av_free(channel);
+ av_free(chname);
+ if (custom.id == AV_CHAN_NONE) {
+ av_freep(&map);
+ return AVERROR(EINVAL);
+ }
- for (i = 0; i < 64; i++) {
- if ((1ULL << i) & channel_layout && !index--)
- return 1ULL << i;
+ av_dynarray2_add((void **)&map, &nb_channels, sizeof(custom), (void *)&custom);
+ if (!map)
+ return AVERROR(ENOMEM);
}
- return 0;
-}
-
-int av_get_standard_channel_layout(unsigned index, uint64_t *layout,
- const char **name)
-{
- if (index >= FF_ARRAY_ELEMS(channel_layout_map))
- return AVERROR_EOF;
- if (layout) *layout = channel_layout_map[index].layout.u.mask;
- if (name) *name = channel_layout_map[index].name;
- return 0;
-}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-int av_channel_layout_from_mask(AVChannelLayout *channel_layout,
- uint64_t mask)
-{
- if (!mask)
+ if (!nb_channels)
return AVERROR(EINVAL);
- channel_layout->order = AV_CHANNEL_ORDER_NATIVE;
- channel_layout->nb_channels = av_popcount64(mask);
- channel_layout->u.mask = mask;
+ ch_layout->order = AV_CHANNEL_ORDER_CUSTOM;
+ ch_layout->u.map = map;
+ ch_layout->nb_channels = nb_channels;
+
+ ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
+ av_assert0(ret == 0);
return 0;
}
@@ -414,10 +303,8 @@ int av_channel_layout_from_mask(AVChannelLayout *channel_layout,
int av_channel_layout_from_string(AVChannelLayout *channel_layout,
const char *str)
{
- int i;
- int channels = 0, nb_channels = 0, native = 1;
- enum AVChannel highest_channel = AV_CHAN_NONE;
- const char *dup;
+ int i, matches, ret;
+ int channels = 0, nb_channels = 0;
char *chlist, *end;
uint64_t mask = 0;
@@ -429,6 +316,10 @@ int av_channel_layout_from_string(AVChannelLayout *channel_layout,
}
}
+ /* This function is a channel layout initializer, so we have to
+ * zero-initialize before we start setting fields individually. */
+ memset(channel_layout, 0, sizeof(*channel_layout));
+
/* ambisonic */
if (!strncmp(str, "ambisonic ", 10)) {
const char *p = str + 10;
@@ -470,6 +361,7 @@ int av_channel_layout_from_string(AVChannelLayout *channel_layout,
for (i = 0; i < extra.nb_channels; i++) {
enum AVChannel ch = av_channel_layout_channel_from_index(&extra, i);
if (CHAN_IS_AMBI(ch)) {
+ av_channel_layout_uninit(channel_layout);
av_channel_layout_uninit(&extra);
return AVERROR(EINVAL);
}
@@ -493,121 +385,20 @@ int av_channel_layout_from_string(AVChannelLayout *channel_layout,
return AVERROR(ENOMEM);
/* channel names */
- av_sscanf(str, "%d channels (%[^)]", &nb_channels, chlist);
- end = strchr(str, ')');
-
- dup = chlist;
- while (*dup) {
- char *channel, *chname;
- int ret = av_opt_get_key_value(&dup, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname);
- if (ret < 0) {
- av_free(chlist);
- return ret;
- }
- if (*dup)
- dup++; // skip separator
- if (channel && !*channel)
- av_freep(&channel);
- for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
- if (channel_names[i].name && !strcmp(channel ? channel : chname, channel_names[i].name)) {
- if (channel || i < highest_channel || mask & (1ULL << i))
- native = 0; // Not a native layout, use a custom one
- highest_channel = i;
- mask |= 1ULL << i;
- break;
- }
- }
-
- if (!channel && i >= FF_ARRAY_ELEMS(channel_names)) {
- char *endptr = chname;
- enum AVChannel id = AV_CHAN_NONE;
-
- if (!strncmp(chname, "USR", 3)) {
- const char *p = chname + 3;
- id = strtol(p, &endptr, 0);
- }
- if (id < 0 || *endptr) {
- native = 0; // Unknown channel name
- channels = 0;
- mask = 0;
- av_free(chname);
- break;
- }
- if (id > 63)
- native = 0; // Not a native layout, use a custom one
- else {
- if (id < highest_channel || mask & (1ULL << id))
- native = 0; // Not a native layout, use a custom one
- highest_channel = id;
- mask |= 1ULL << id;
- }
- }
- channels++;
- av_free(channel);
- av_free(chname);
- }
-
- if (mask && native) {
- av_free(chlist);
- if (nb_channels && ((nb_channels != channels) || (!end || *++end)))
- return AVERROR(EINVAL);
- av_channel_layout_from_mask(channel_layout, mask);
- return 0;
- }
-
- /* custom layout of channel names */
- if (channels && !native) {
- int idx = 0;
+ matches = av_sscanf(str, "%d channels (%[^)]", &nb_channels, chlist);
+ ret = parse_channel_list(channel_layout, chlist);
+ av_freep(&chlist);
+ if (ret < 0 && ret != AVERROR(EINVAL))
+ return ret;
- if (nb_channels && ((nb_channels != channels) || (!end || *++end))) {
- av_free(chlist);
+ if (ret >= 0) {
+ end = strchr(str, ')');
+ if (matches == 2 && (nb_channels != channel_layout->nb_channels || !end || *++end)) {
+ av_channel_layout_uninit(channel_layout);
return AVERROR(EINVAL);
}
-
- channel_layout->u.map = av_calloc(channels, sizeof(*channel_layout->u.map));
- if (!channel_layout->u.map) {
- av_free(chlist);
- return AVERROR(ENOMEM);
- }
-
- channel_layout->order = AV_CHANNEL_ORDER_CUSTOM;
- channel_layout->nb_channels = channels;
-
- dup = chlist;
- while (*dup) {
- char *channel, *chname;
- int ret = av_opt_get_key_value(&dup, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname);
- if (ret < 0) {
- av_freep(&channel_layout->u.map);
- av_free(chlist);
- return ret;
- }
- if (*dup)
- dup++; // skip separator
- for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
- if (channel_names[i].name && !strcmp(channel ? channel : chname, channel_names[i].name)) {
- channel_layout->u.map[idx].id = i;
- if (channel)
- av_strlcpy(channel_layout->u.map[idx].name, chname, sizeof(channel_layout->u.map[idx].name));
- idx++;
- break;
- }
- }
- if (i >= FF_ARRAY_ELEMS(channel_names)) {
- const char *p = (channel ? channel : chname) + 3;
- channel_layout->u.map[idx].id = strtol(p, NULL, 0);
- if (channel)
- av_strlcpy(channel_layout->u.map[idx].name, chname, sizeof(channel_layout->u.map[idx].name));
- idx++;
- }
- av_free(channel);
- av_free(chname);
- }
- av_free(chlist);
-
return 0;
}
- av_freep(&chlist);
errno = 0;
mask = strtoull(str, &end, 0);
@@ -659,6 +450,29 @@ int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
return 0;
}
+static int64_t masked_description(const AVChannelLayout *channel_layout, int start_channel)
+{
+ uint64_t mask = 0;
+ for (int i = start_channel; i < channel_layout->nb_channels; i++) {
+ enum AVChannel ch = channel_layout->u.map[i].id;
+ if (ch >= 0 && ch < 63 && mask < (1ULL << ch))
+ mask |= (1ULL << ch);
+ else
+ return AVERROR(EINVAL);
+ }
+ return mask;
+}
+
+static int has_channel_names(const AVChannelLayout *channel_layout)
+{
+ if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM)
+ return 0;
+ for (int i = 0; i < channel_layout->nb_channels; i++)
+ if (channel_layout->u.map[i].name[0])
+ return 1;
+ return 0;
+}
+
/**
* If the layout is n-th order standard-order ambisonic, with optional
* extra non-diegetic channels at the end, return the order.
@@ -702,6 +516,33 @@ static int ambisonic_order(const AVChannelLayout *channel_layout)
return order;
}
+static enum AVChannelOrder canonical_order(AVChannelLayout *channel_layout)
+{
+ int has_known_channel = 0;
+ int order;
+
+ if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM)
+ return channel_layout->order;
+
+ if (has_channel_names(channel_layout))
+ return AV_CHANNEL_ORDER_CUSTOM;
+
+ for (int i = 0; i < channel_layout->nb_channels && !has_known_channel; i++)
+ if (channel_layout->u.map[i].id != AV_CHAN_UNKNOWN)
+ has_known_channel = 1;
+ if (!has_known_channel)
+ return AV_CHANNEL_ORDER_UNSPEC;
+
+ if (masked_description(channel_layout, 0) > 0)
+ return AV_CHANNEL_ORDER_NATIVE;
+
+ order = ambisonic_order(channel_layout);
+ if (order >= 0 && masked_description(channel_layout, (order + 1) * (order + 1)) >= 0)
+ return AV_CHANNEL_ORDER_AMBISONIC;
+
+ return AV_CHANNEL_ORDER_CUSTOM;
+}
+
/**
* If the custom layout is n-th order standard-order ambisonic, with optional
* extra non-diegetic channels at the end, write its string description in bp.
@@ -726,9 +567,17 @@ static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_l
extra.nb_channels = av_popcount64(channel_layout->u.mask);
extra.u.mask = channel_layout->u.mask;
} else {
- extra.order = AV_CHANNEL_ORDER_CUSTOM;
- extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels;
- extra.u.map = channel_layout->u.map + nb_ambi_channels;
+ int64_t mask;
+ if (!has_channel_names(channel_layout) &&
+ (mask = masked_description(channel_layout, nb_ambi_channels)) > 0) {
+ extra.order = AV_CHANNEL_ORDER_NATIVE;
+ extra.nb_channels = av_popcount64(mask);
+ extra.u.mask = mask;
+ } else {
+ extra.order = AV_CHANNEL_ORDER_CUSTOM;
+ extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels;
+ extra.u.map = channel_layout->u.map + nb_ambi_channels;
+ }
}
av_bprint_chars(bp, '+', 1);
@@ -754,9 +603,17 @@ int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout,
// fall-through
case AV_CHANNEL_ORDER_CUSTOM:
if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
+ int64_t mask;
int res = try_describe_ambisonic(bp, channel_layout);
if (res >= 0)
return 0;
+ if (!has_channel_names(channel_layout) &&
+ (mask = masked_description(channel_layout, 0)) > 0) {
+ AVChannelLayout native = { .order = AV_CHANNEL_ORDER_NATIVE,
+ .nb_channels = av_popcount64(mask),
+ .u.mask = mask };
+ return av_channel_layout_describe_bprint(&native, bp);
+ }
}
if (channel_layout->nb_channels)
av_bprintf(bp, "%d channels (", channel_layout->nb_channels);
@@ -1016,3 +873,97 @@ uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout,
return ret;
}
+
+int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
+{
+ int allow_lossy = !(flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS);
+ int lossy;
+
+ if (!av_channel_layout_check(channel_layout))
+ return AVERROR(EINVAL);
+
+ if (flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL)
+ order = canonical_order(channel_layout);
+
+ if (channel_layout->order == order)
+ return 0;
+
+ switch (order) {
+ case AV_CHANNEL_ORDER_UNSPEC: {
+ int nb_channels = channel_layout->nb_channels;
+ if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
+ lossy = 0;
+ for (int i = 0; i < nb_channels; i++) {
+ if (channel_layout->u.map[i].id != AV_CHAN_UNKNOWN || channel_layout->u.map[i].name[0]) {
+ lossy = 1;
+ break;
+ }
+ }
+ } else {
+ lossy = 1;
+ }
+ if (!lossy || allow_lossy) {
+ void *opaque = channel_layout->opaque;
+ av_channel_layout_uninit(channel_layout);
+ channel_layout->order = AV_CHANNEL_ORDER_UNSPEC;
+ channel_layout->nb_channels = nb_channels;
+ channel_layout->opaque = opaque;
+ return lossy;
+ }
+ return AVERROR(ENOSYS);
+ }
+ case AV_CHANNEL_ORDER_NATIVE:
+ if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
+ int64_t mask = masked_description(channel_layout, 0);
+ if (mask < 0)
+ return AVERROR(ENOSYS);
+ lossy = has_channel_names(channel_layout);
+ if (!lossy || allow_lossy) {
+ void *opaque = channel_layout->opaque;
+ av_channel_layout_uninit(channel_layout);
+ av_channel_layout_from_mask(channel_layout, mask);
+ channel_layout->opaque = opaque;
+ return lossy;
+ }
+ }
+ return AVERROR(ENOSYS);
+ case AV_CHANNEL_ORDER_CUSTOM: {
+ AVChannelLayout custom = { 0 };
+ int ret = av_channel_layout_custom_init(&custom, channel_layout->nb_channels);
+ void *opaque = channel_layout->opaque;
+ if (ret < 0)
+ return ret;
+ if (channel_layout->order != AV_CHANNEL_ORDER_UNSPEC)
+ for (int i = 0; i < channel_layout->nb_channels; i++)
+ custom.u.map[i].id = av_channel_layout_channel_from_index(channel_layout, i);
+ av_channel_layout_uninit(channel_layout);
+ *channel_layout = custom;
+ channel_layout->opaque = opaque;
+ return 0;
+ }
+ case AV_CHANNEL_ORDER_AMBISONIC:
+ if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
+ int64_t mask;
+ int nb_channels = channel_layout->nb_channels;
+ int order = ambisonic_order(channel_layout);
+ if (order < 0)
+ return AVERROR(ENOSYS);
+ mask = masked_description(channel_layout, (order + 1) * (order + 1));
+ if (mask < 0)
+ return AVERROR(ENOSYS);
+ lossy = has_channel_names(channel_layout);
+ if (!lossy || allow_lossy) {
+ void *opaque = channel_layout->opaque;
+ av_channel_layout_uninit(channel_layout);
+ channel_layout->order = AV_CHANNEL_ORDER_AMBISONIC;
+ channel_layout->nb_channels = nb_channels;
+ channel_layout->u.mask = mask;
+ channel_layout->opaque = opaque;
+ return lossy;
+ }
+ }
+ return AVERROR(ENOSYS);
+ default:
+ return AVERROR(EINVAL);
+ }
+}
diff --git a/media/ffvpx/libavutil/channel_layout.h b/media/ffvpx/libavutil/channel_layout.h
index 8dc1a91401..8a078d1601 100644
--- a/media/ffvpx/libavutil/channel_layout.h
+++ b/media/ffvpx/libavutil/channel_layout.h
@@ -119,7 +119,7 @@ enum AVChannelOrder {
/**
* The channel order does not correspond to any other predefined order and
* is stored as an explicit map. For example, this could be used to support
- * layouts with 64 or more channels, or with empty/skipped (AV_CHAN_SILENCE)
+ * layouts with 64 or more channels, or with empty/skipped (AV_CHAN_UNUSED)
* channels at arbitrary positions.
*/
AV_CHANNEL_ORDER_CUSTOM,
@@ -146,6 +146,10 @@ enum AVChannelOrder {
* as defined in AmbiX format $ 2.1.
*/
AV_CHANNEL_ORDER_AMBISONIC,
+ /**
+ * Number of channel orders, not part of ABI/API
+ */
+ FF_CHANNEL_ORDER_NB
};
@@ -192,16 +196,6 @@ enum AVChannelOrder {
#define AV_CH_BOTTOM_FRONT_LEFT (1ULL << AV_CHAN_BOTTOM_FRONT_LEFT )
#define AV_CH_BOTTOM_FRONT_RIGHT (1ULL << AV_CHAN_BOTTOM_FRONT_RIGHT )
-#if FF_API_OLD_CHANNEL_LAYOUT
-/** Channel mask value used for AVCodecContext.request_channel_layout
- to indicate that the user requests the channel order of the decoder output
- to be the native codec channel order.
- @deprecated channel order is now indicated in a special field in
- AVChannelLayout
- */
-#define AV_CH_LAYOUT_NATIVE 0x8000000000000000ULL
-#endif
-
/**
* @}
* @defgroup channel_mask_c Audio channel layouts
@@ -430,146 +424,6 @@ typedef struct AVChannelLayout {
struct AVBPrint;
-#if FF_API_OLD_CHANNEL_LAYOUT
-/**
- * @name Deprecated Functions
- * @{
- */
-
-/**
- * Return a channel layout id that matches name, or 0 if no match is found.
- *
- * name can be one or several of the following notations,
- * separated by '+' or '|':
- * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0,
- * 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix);
- * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC,
- * SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR);
- * - a number of channels, in decimal, followed by 'c', yielding
- * the default channel layout for that number of channels (@see
- * av_get_default_channel_layout);
- * - a channel layout mask, in hexadecimal starting with "0x" (see the
- * AV_CH_* macros).
- *
- * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7"
- *
- * @deprecated use av_channel_layout_from_string()
- */
-attribute_deprecated
-uint64_t av_get_channel_layout(const char *name);
-
-/**
- * Return a channel layout and the number of channels based on the specified name.
- *
- * This function is similar to (@see av_get_channel_layout), but can also parse
- * unknown channel layout specifications.
- *
- * @param[in] name channel layout specification string
- * @param[out] channel_layout parsed channel layout (0 if unknown)
- * @param[out] nb_channels number of channels
- *
- * @return 0 on success, AVERROR(EINVAL) if the parsing fails.
- * @deprecated use av_channel_layout_from_string()
- */
-attribute_deprecated
-int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels);
-
-/**
- * Return a description of a channel layout.
- * If nb_channels is <= 0, it is guessed from the channel_layout.
- *
- * @param buf put here the string containing the channel layout
- * @param buf_size size in bytes of the buffer
- * @param nb_channels number of channels
- * @param channel_layout channel layout bitset
- * @deprecated use av_channel_layout_describe()
- */
-attribute_deprecated
-void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout);
-
-/**
- * Append a description of a channel layout to a bprint buffer.
- * @deprecated use av_channel_layout_describe()
- */
-attribute_deprecated
-void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout);
-
-/**
- * Return the number of channels in the channel layout.
- * @deprecated use AVChannelLayout.nb_channels
- */
-attribute_deprecated
-int av_get_channel_layout_nb_channels(uint64_t channel_layout);
-
-/**
- * Return default channel layout for a given number of channels.
- *
- * @deprecated use av_channel_layout_default()
- */
-attribute_deprecated
-int64_t av_get_default_channel_layout(int nb_channels);
-
-/**
- * Get the index of a channel in channel_layout.
- *
- * @param channel_layout channel layout bitset
- * @param channel a channel layout describing exactly one channel which must be
- * present in channel_layout.
- *
- * @return index of channel in channel_layout on success, a negative AVERROR
- * on error.
- *
- * @deprecated use av_channel_layout_index_from_channel()
- */
-attribute_deprecated
-int av_get_channel_layout_channel_index(uint64_t channel_layout,
- uint64_t channel);
-
-/**
- * Get the channel with the given index in channel_layout.
- * @deprecated use av_channel_layout_channel_from_index()
- */
-attribute_deprecated
-uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index);
-
-/**
- * Get the name of a given channel.
- *
- * @return channel name on success, NULL on error.
- *
- * @deprecated use av_channel_name()
- */
-attribute_deprecated
-const char *av_get_channel_name(uint64_t channel);
-
-/**
- * Get the description of a given channel.
- *
- * @param channel a channel layout with a single channel
- * @return channel description on success, NULL on error
- * @deprecated use av_channel_description()
- */
-attribute_deprecated
-const char *av_get_channel_description(uint64_t channel);
-
-/**
- * Get the value and name of a standard channel layout.
- *
- * @param[in] index index in an internal list, starting at 0
- * @param[out] layout channel layout mask
- * @param[out] name name of the layout
- * @return 0 if the layout exists,
- * <0 if index is beyond the limits
- * @deprecated use av_channel_layout_standard()
- */
-attribute_deprecated
-int av_get_standard_channel_layout(unsigned index, uint64_t *layout,
- const char **name);
-/**
- * @}
- */
-#endif
-
/**
* Get a human readable string in an abbreviated form describing a given channel.
* This is the inverse function of @ref av_channel_from_string().
@@ -618,6 +472,23 @@ void av_channel_description_bprint(struct AVBPrint *bp, enum AVChannel channel_i
enum AVChannel av_channel_from_string(const char *name);
/**
+ * Initialize a custom channel layout with the specified number of channels.
+ * The channel map will be allocated and the designation of all channels will
+ * be set to AV_CHAN_UNKNOWN.
+ *
+ * This is only a convenience helper function, a custom channel layout can also
+ * be constructed without using this.
+ *
+ * @param channel_layout the layout structure to be initialized
+ * @param nb_channels the number of channels
+ *
+ * @return 0 on success
+ * AVERROR(EINVAL) if the number of channels <= 0
+ * AVERROR(ENOMEM) if the channel map could not be allocated
+ */
+int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels);
+
+/**
* Initialize a native channel layout from a bitmask indicating which channels
* are present.
*
@@ -641,10 +512,14 @@ int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask);
* - the number of unordered channels (eg. "4C" or "4 channels")
* - the ambisonic order followed by optional non-diegetic channels (eg.
* "ambisonic 2+stereo")
+ * On error, the channel layout will remain uninitialized, but not necessarily
+ * untouched.
*
- * @param channel_layout input channel layout
+ * @param channel_layout uninitialized channel layout for the result
* @param str string describing the channel layout
- * @return 0 channel layout was detected, AVERROR_INVALIDATATA otherwise
+ * @return 0 on success parsing the channel layout
+ * AVERROR(EINVAL) if an invalid channel layout string was provided
+ * AVERROR(ENOMEM) if there was not enough memory
*/
int av_channel_layout_from_string(AVChannelLayout *channel_layout,
const char *str);
@@ -805,6 +680,53 @@ int av_channel_layout_check(const AVChannelLayout *channel_layout);
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1);
/**
+ * The conversion must be lossless.
+ */
+#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS (1 << 0)
+
+/**
+ * The specified retype target order is ignored and the simplest possible
+ * (canonical) order is used for which the input layout can be losslessy
+ * represented.
+ */
+#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL (1 << 1)
+
+/**
+ * Change the AVChannelOrder of a channel layout.
+ *
+ * Change of AVChannelOrder can be either lossless or lossy. In case of a
+ * lossless conversion all the channel designations and the associated channel
+ * names (if any) are kept. On a lossy conversion the channel names and channel
+ * designations might be lost depending on the capabilities of the desired
+ * AVChannelOrder. Note that some conversions are simply not possible in which
+ * case this function returns AVERROR(ENOSYS).
+ *
+ * The following conversions are supported:
+ *
+ * Any -> Custom : Always possible, always lossless.
+ * Any -> Unspecified: Always possible, lossless if channel designations
+ * are all unknown and channel names are not used, lossy otherwise.
+ * Custom -> Ambisonic : Possible if it contains ambisonic channels with
+ * optional non-diegetic channels in the end. Lossy if the channels have
+ * custom names, lossless otherwise.
+ * Custom -> Native : Possible if it contains native channels in native
+ * order. Lossy if the channels have custom names, lossless otherwise.
+ *
+ * On error this function keeps the original channel layout untouched.
+ *
+ * @param channel_layout channel layout which will be changed
+ * @param order the desired channel layout order
+ * @param flags a combination of AV_CHANNEL_LAYOUT_RETYPE_FLAG_* constants
+ * @return 0 if the conversion was successful and lossless or if the channel
+ * layout was already in the desired order
+ * >0 if the conversion was successful but lossy
+ * AVERROR(ENOSYS) if the conversion was not possible (or would be
+ * lossy and AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS was specified)
+ * AVERROR(EINVAL), AVERROR(ENOMEM) on error
+ */
+int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags);
+
+/**
* @}
*/
diff --git a/media/ffvpx/libavutil/color_utils.c b/media/ffvpx/libavutil/color_utils.c
deleted file mode 100644
index 5e221fb798..0000000000
--- a/media/ffvpx/libavutil/color_utils.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@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 <stddef.h>
-#include <math.h>
-
-#include "libavutil/color_utils.h"
-#include "libavutil/pixfmt.h"
-
-double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
-{
- double gamma;
- switch (trc) {
- case AVCOL_TRC_BT709:
- case AVCOL_TRC_SMPTE170M:
- case AVCOL_TRC_SMPTE240M:
- case AVCOL_TRC_BT1361_ECG:
- case AVCOL_TRC_BT2020_10:
- case AVCOL_TRC_BT2020_12:
- /* these share a segmented TRC, but gamma 1.961 is a close
- approximation, and also more correct for decoding content */
- gamma = 1.961;
- break;
- case AVCOL_TRC_GAMMA22:
- case AVCOL_TRC_IEC61966_2_1:
- gamma = 2.2;
- break;
- case AVCOL_TRC_GAMMA28:
- gamma = 2.8;
- break;
- case AVCOL_TRC_LINEAR:
- gamma = 1.0;
- break;
- default:
- gamma = 0.0; // Unknown value representation
- }
- return gamma;
-}
-
-#define BT709_alpha 1.099296826809442
-#define BT709_beta 0.018053968510807
-
-static double avpriv_trc_bt709(double Lc)
-{
- const double a = BT709_alpha;
- const double b = BT709_beta;
-
- return (0.0 > Lc) ? 0.0
- : ( b > Lc) ? 4.500 * Lc
- : a * pow(Lc, 0.45) - (a - 1.0);
-}
-
-static double avpriv_trc_gamma22(double Lc)
-{
- return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
-}
-
-static double avpriv_trc_gamma28(double Lc)
-{
- return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
-}
-
-static double avpriv_trc_smpte240M(double Lc)
-{
- const double a = 1.1115;
- const double b = 0.0228;
-
- return (0.0 > Lc) ? 0.0
- : ( b > Lc) ? 4.000 * Lc
- : a * pow(Lc, 0.45) - (a - 1.0);
-}
-
-static double avpriv_trc_linear(double Lc)
-{
- return Lc;
-}
-
-static double avpriv_trc_log(double Lc)
-{
- return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
-}
-
-static double avpriv_trc_log_sqrt(double Lc)
-{
- // sqrt(10) / 1000
- return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
-}
-
-static double avpriv_trc_iec61966_2_4(double Lc)
-{
- const double a = BT709_alpha;
- const double b = BT709_beta;
-
- return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0)
- : ( b > Lc) ? 4.500 * Lc
- : a * pow( Lc, 0.45) - (a - 1.0);
-}
-
-static double avpriv_trc_bt1361(double Lc)
-{
- const double a = BT709_alpha;
- const double b = BT709_beta;
-
- return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0
- : ( b > Lc) ? 4.500 * Lc
- : a * pow( Lc, 0.45) - (a - 1.0);
-}
-
-static double avpriv_trc_iec61966_2_1(double Lc)
-{
- const double a = 1.055;
- const double b = 0.0031308;
-
- return (0.0 > Lc) ? 0.0
- : ( b > Lc) ? 12.92 * Lc
- : a * pow(Lc, 1.0 / 2.4) - (a - 1.0);
-}
-
-static double avpriv_trc_smpte_st2084(double Lc)
-{
- const double c1 = 3424.0 / 4096.0; // c3-c2 + 1
- const double c2 = 32.0 * 2413.0 / 4096.0;
- const double c3 = 32.0 * 2392.0 / 4096.0;
- const double m = 128.0 * 2523.0 / 4096.0;
- const double n = 0.25 * 2610.0 / 4096.0;
- const double L = Lc / 10000.0;
- const double Ln = pow(L, n);
-
- return (0.0 > Lc) ? 0.0
- : pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m);
-
-}
-
-static double avpriv_trc_smpte_st428_1(double Lc)
-{
- return (0.0 > Lc) ? 0.0
- : pow(48.0 * Lc / 52.37, 1.0 / 2.6);
-}
-
-
-static double avpriv_trc_arib_std_b67(double Lc) {
- // The function uses the definition from HEVC, which assumes that the peak
- // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
- // using the definition from the ARIB STD-B67 spec)
- const double a = 0.17883277;
- const double b = 0.28466892;
- const double c = 0.55991073;
- return (0.0 > Lc) ? 0.0 :
- (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
-}
-
-avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc)
-{
- avpriv_trc_function func = NULL;
- switch (trc) {
- case AVCOL_TRC_BT709:
- case AVCOL_TRC_SMPTE170M:
- case AVCOL_TRC_BT2020_10:
- case AVCOL_TRC_BT2020_12:
- func = avpriv_trc_bt709;
- break;
-
- case AVCOL_TRC_GAMMA22:
- func = avpriv_trc_gamma22;
- break;
- case AVCOL_TRC_GAMMA28:
- func = avpriv_trc_gamma28;
- break;
-
- case AVCOL_TRC_SMPTE240M:
- func = avpriv_trc_smpte240M;
- break;
-
- case AVCOL_TRC_LINEAR:
- func = avpriv_trc_linear;
- break;
-
- case AVCOL_TRC_LOG:
- func = avpriv_trc_log;
- break;
-
- case AVCOL_TRC_LOG_SQRT:
- func = avpriv_trc_log_sqrt;
- break;
-
- case AVCOL_TRC_IEC61966_2_4:
- func = avpriv_trc_iec61966_2_4;
- break;
-
- case AVCOL_TRC_BT1361_ECG:
- func = avpriv_trc_bt1361;
- break;
-
- case AVCOL_TRC_IEC61966_2_1:
- func = avpriv_trc_iec61966_2_1;
- break;
-
- case AVCOL_TRC_SMPTEST2084:
- func = avpriv_trc_smpte_st2084;
- break;
-
- case AVCOL_TRC_SMPTEST428_1:
- func = avpriv_trc_smpte_st428_1;
- break;
-
- case AVCOL_TRC_ARIB_STD_B67:
- func = avpriv_trc_arib_std_b67;
- break;
-
- case AVCOL_TRC_RESERVED0:
- case AVCOL_TRC_UNSPECIFIED:
- case AVCOL_TRC_RESERVED:
- default:
- break;
- }
- return func;
-}
diff --git a/media/ffvpx/libavutil/color_utils.h b/media/ffvpx/libavutil/color_utils.h
deleted file mode 100644
index 9529006452..0000000000
--- a/media/ffvpx/libavutil/color_utils.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@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_COLOR_UTILS_H
-#define AVUTIL_COLOR_UTILS_H
-
-
-#include "libavutil/pixfmt.h"
-
-/**
- * Determine a suitable 'gamma' value to match the supplied
- * AVColorTransferCharacteristic.
- *
- * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
- *
- * @return Will return an approximation to the simple gamma function matching
- * the supplied Transfer Characteristic, Will return 0.0 for any
- * we cannot reasonably match against.
- */
-double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc);
-
-
-typedef double (*avpriv_trc_function)(double);
-
-/**
- * Determine the function needed to apply the given
- * AVColorTransferCharacteristic to linear input.
- *
- * The function returned should expect a nominal domain and range of [0.0-1.0]
- * values outside of this range maybe valid depending on the chosen
- * characteristic function.
- *
- * @return Will return pointer to the function matching the
- * supplied Transfer Characteristic. If unspecified will
- * return NULL:
- */
-avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc);
-
-#endif
diff --git a/media/ffvpx/libavutil/common.h b/media/ffvpx/libavutil/common.h
index de2140a678..3e4c339893 100644
--- a/media/ffvpx/libavutil/common.h
+++ b/media/ffvpx/libavutil/common.h
@@ -43,6 +43,14 @@
#include "error.h"
#include "macros.h"
+#ifdef HAVE_AV_CONFIG_H
+# include "config.h"
+# include "intmath.h"
+# include "internal.h"
+#else
+# include "mem.h"
+#endif /* HAVE_AV_CONFIG_H */
+
//rounded division & shift
#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
/* assume b>0 */
@@ -84,11 +92,6 @@
/* misc math functions */
-#ifdef HAVE_AV_CONFIG_H
-# include "config.h"
-# include "intmath.h"
-#endif
-
#ifndef av_ceil_log2
# define av_ceil_log2 av_ceil_log2_c
#endif
@@ -568,12 +571,4 @@ static av_always_inline av_const int av_parity_c(uint32_t v)
}\
}\
-
-
-#include "mem.h"
-
-#ifdef HAVE_AV_CONFIG_H
-# include "internal.h"
-#endif /* HAVE_AV_CONFIG_H */
-
#endif /* AVUTIL_COMMON_H */
diff --git a/media/ffvpx/libavutil/cpu.c b/media/ffvpx/libavutil/cpu.c
index 48d195168c..d4f947360a 100644
--- a/media/ffvpx/libavutil/cpu.c
+++ b/media/ffvpx/libavutil/cpu.c
@@ -49,8 +49,8 @@
#include <unistd.h>
#endif
-static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1);
-static atomic_int cpu_count = ATOMIC_VAR_INIT(-1);
+static atomic_int cpu_flags = -1;
+static atomic_int cpu_count = -1;
static int get_cpu_flags(void)
{
@@ -208,7 +208,7 @@ int av_parse_cpu_caps(unsigned *flags, const char *s)
int av_cpu_count(void)
{
- static atomic_int printed = ATOMIC_VAR_INIT(0);
+ static atomic_int printed = 0;
int nb_cpus = 1;
int count = 0;
diff --git a/media/ffvpx/libavutil/csp.h b/media/ffvpx/libavutil/csp.h
new file mode 100644
index 0000000000..73bce52bc0
--- /dev/null
+++ b/media/ffvpx/libavutil/csp.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
+ * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
+ * Copyright (c) 2023 Leo Izen <leo.izen@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_CSP_H
+#define AVUTIL_CSP_H
+
+#include "pixfmt.h"
+#include "rational.h"
+
+/**
+ * @file
+ * Colorspace value utility functions for libavutil.
+ * @ingroup lavu_math_csp
+ * @author Ronald S. Bultje <rsbultje@gmail.com>
+ * @author Leo Izen <leo.izen@gmail.com>
+ * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
+ */
+
+/**
+ * @defgroup lavu_math_csp Colorspace Utility
+ * @ingroup lavu_math
+ * @{
+ */
+
+/**
+ * Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar
+ * calculations.
+ */
+typedef struct AVLumaCoefficients {
+ AVRational cr, cg, cb;
+} AVLumaCoefficients;
+
+/**
+ * Struct containing chromaticity x and y values for the standard CIE 1931
+ * chromaticity definition.
+ */
+typedef struct AVCIExy {
+ AVRational x, y;
+} AVCIExy;
+
+/**
+ * Struct defining the red, green, and blue primary locations in terms of CIE
+ * 1931 chromaticity x and y.
+ */
+typedef struct AVPrimaryCoefficients {
+ AVCIExy r, g, b;
+} AVPrimaryCoefficients;
+
+/**
+ * Struct defining white point location in terms of CIE 1931 chromaticity x
+ * and y.
+ */
+typedef AVCIExy AVWhitepointCoefficients;
+
+/**
+ * Struct that contains both white point location and primaries location, providing
+ * the complete description of a color gamut.
+ */
+typedef struct AVColorPrimariesDesc {
+ AVWhitepointCoefficients wp;
+ AVPrimaryCoefficients prim;
+} AVColorPrimariesDesc;
+
+/**
+ * Function pointer representing a double -> double transfer function that performs
+ * an EOTF transfer inversion. This function outputs linear light.
+ */
+typedef double (*av_csp_trc_function)(double);
+
+/**
+ * Retrieves the Luma coefficients necessary to construct a conversion matrix
+ * from an enum constant describing the colorspace.
+ * @param csp An enum constant indicating YUV or similar colorspace.
+ * @return The Luma coefficients associated with that colorspace, or NULL
+ * if the constant is unknown to libavutil.
+ */
+const AVLumaCoefficients *av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp);
+
+/**
+ * Retrieves a complete gamut description from an enum constant describing the
+ * color primaries.
+ * @param prm An enum constant indicating primaries
+ * @return A description of the colorspace gamut associated with that enum
+ * constant, or NULL if the constant is unknown to libavutil.
+ */
+const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries prm);
+
+/**
+ * Detects which enum AVColorPrimaries constant corresponds to the given complete
+ * gamut description.
+ * @see enum AVColorPrimaries
+ * @param prm A description of the colorspace gamut
+ * @return The enum constant associated with this gamut, or
+ * AVCOL_PRI_UNSPECIFIED if no clear match can be idenitified.
+ */
+enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm);
+
+/**
+ * Determine a suitable 'gamma' value to match the supplied
+ * AVColorTransferCharacteristic.
+ *
+ * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
+ *
+ * This function returns the gamma exponent for the OETF. For example, sRGB is approximated
+ * by gamma 2.2, not by gamma 0.45455.
+ *
+ * @return Will return an approximation to the simple gamma function matching
+ * the supplied Transfer Characteristic, Will return 0.0 for any
+ * we cannot reasonably match against.
+ */
+double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc);
+
+/**
+ * Determine the function needed to apply the given
+ * AVColorTransferCharacteristic to linear input.
+ *
+ * The function returned should expect a nominal domain and range of [0.0-1.0]
+ * values outside of this range maybe valid depending on the chosen
+ * characteristic function.
+ *
+ * @return Will return pointer to the function matching the
+ * supplied Transfer Characteristic. If unspecified will
+ * return NULL:
+ */
+av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_CSP_H */
diff --git a/media/ffvpx/libavutil/dict.c b/media/ffvpx/libavutil/dict.c
index 7f23d5336a..6fb09399ba 100644
--- a/media/ffvpx/libavutil/dict.c
+++ b/media/ffvpx/libavutil/dict.c
@@ -145,11 +145,8 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value,
m->elems[m->count].value = copy_value;
m->count++;
} else {
- if (!m->count) {
- av_freep(&m->elems);
- av_freep(pm);
- }
- av_freep(&copy_key);
+ err = 0;
+ goto end;
}
return 0;
@@ -157,12 +154,13 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value,
enomem:
err = AVERROR(ENOMEM);
err_out:
+ av_free(copy_value);
+end:
if (m && !m->count) {
av_freep(&m->elems);
av_freep(pm);
}
av_free(copy_key);
- av_free(copy_value);
return err;
}
diff --git a/media/ffvpx/libavutil/eval.c b/media/ffvpx/libavutil/eval.c
index 95adb51609..84ff929130 100644
--- a/media/ffvpx/libavutil/eval.c
+++ b/media/ffvpx/libavutil/eval.c
@@ -32,13 +32,12 @@
#include "common.h"
#include "eval.h"
#include "ffmath.h"
-#include "internal.h"
#include "log.h"
#include "mathematics.h"
+#include "mem.h"
#include "sfc64.h"
#include "fftime.h"
#include "avstring.h"
-#include "timer.h"
#include "reverse.h"
typedef struct Parser {
diff --git a/media/ffvpx/libavutil/fftime.h b/media/ffvpx/libavutil/fftime.h
index 8f3b320e38..dc169b064a 100644
--- a/media/ffvpx/libavutil/fftime.h
+++ b/media/ffvpx/libavutil/fftime.h
@@ -22,7 +22,6 @@
#define AVUTIL_TIME_H
#include <stdint.h>
-#include <time.h>
/**
* Get the current time in microseconds.
diff --git a/media/ffvpx/libavutil/ffversion.h b/media/ffvpx/libavutil/ffversion.h
index 392808d726..1aa567741f 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 "N-111736-gd9d5695390"
+#define FFMPEG_VERSION "N-114439-gf0ee4bbc6b"
#endif /* AVUTIL_FFVERSION_H */
diff --git a/media/ffvpx/libavutil/fifo.c b/media/ffvpx/libavutil/fifo.c
index b0807abbf7..8806c668d7 100644
--- a/media/ffvpx/libavutil/fifo.c
+++ b/media/ffvpx/libavutil/fifo.c
@@ -290,222 +290,3 @@ void av_fifo_freep2(AVFifo **f)
av_freep(f);
}
}
-
-
-#if FF_API_FIFO_OLD_API
-#include "internal.h"
-FF_DISABLE_DEPRECATION_WARNINGS
-#define OLD_FIFO_SIZE_MAX (size_t)FFMIN3(INT_MAX, UINT32_MAX, SIZE_MAX)
-
-AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size)
-{
- AVFifoBuffer *f;
- void *buffer;
-
- if (nmemb > OLD_FIFO_SIZE_MAX / size)
- return NULL;
-
- buffer = av_realloc_array(NULL, nmemb, size);
- if (!buffer)
- return NULL;
- f = av_mallocz(sizeof(AVFifoBuffer));
- if (!f) {
- av_free(buffer);
- return NULL;
- }
- f->buffer = buffer;
- f->end = f->buffer + nmemb * size;
- av_fifo_reset(f);
- return f;
-}
-
-AVFifoBuffer *av_fifo_alloc(unsigned int size)
-{
- return av_fifo_alloc_array(size, 1);
-}
-
-void av_fifo_free(AVFifoBuffer *f)
-{
- if (f) {
- av_freep(&f->buffer);
- av_free(f);
- }
-}
-
-void av_fifo_freep(AVFifoBuffer **f)
-{
- if (f) {
- av_fifo_free(*f);
- *f = NULL;
- }
-}
-
-void av_fifo_reset(AVFifoBuffer *f)
-{
- f->wptr = f->rptr = f->buffer;
- f->wndx = f->rndx = 0;
-}
-
-int av_fifo_size(const AVFifoBuffer *f)
-{
- return (uint32_t)(f->wndx - f->rndx);
-}
-
-int av_fifo_space(const AVFifoBuffer *f)
-{
- return f->end - f->buffer - av_fifo_size(f);
-}
-
-int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
-{
- unsigned int old_size = f->end - f->buffer;
-
- if (new_size > OLD_FIFO_SIZE_MAX)
- return AVERROR(EINVAL);
-
- if (old_size < new_size) {
- size_t offset_r = f->rptr - f->buffer;
- size_t offset_w = f->wptr - f->buffer;
- uint8_t *tmp;
-
- tmp = av_realloc(f->buffer, new_size);
- if (!tmp)
- return AVERROR(ENOMEM);
-
- // move the data from the beginning of the ring buffer
- // to the newly allocated space
- // the second condition distinguishes full vs empty fifo
- if (offset_w <= offset_r && av_fifo_size(f)) {
- const size_t copy = FFMIN(new_size - old_size, offset_w);
- memcpy(tmp + old_size, tmp, copy);
- if (copy < offset_w) {
- memmove(tmp, tmp + copy , offset_w - copy);
- offset_w -= copy;
- } else
- offset_w = old_size + copy;
- }
-
- f->buffer = tmp;
- f->end = f->buffer + new_size;
- f->rptr = f->buffer + offset_r;
- f->wptr = f->buffer + offset_w;
- }
- return 0;
-}
-
-int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
-{
- unsigned int old_size = f->end - f->buffer;
- if(size + (unsigned)av_fifo_size(f) < size)
- return AVERROR(EINVAL);
-
- size += av_fifo_size(f);
-
- if (old_size < size)
- return av_fifo_realloc2(f, FFMAX(size, 2*old_size));
- return 0;
-}
-
-/* src must NOT be const as it can be a context for func that may need
- * updating (like a pointer or byte counter) */
-int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size,
- int (*func)(void *, void *, int))
-{
- int total = size;
- uint32_t wndx= f->wndx;
- uint8_t *wptr= f->wptr;
-
- if (size > av_fifo_space(f))
- return AVERROR(ENOSPC);
-
- do {
- int len = FFMIN(f->end - wptr, size);
- if (func) {
- len = func(src, wptr, len);
- if (len <= 0)
- break;
- } else {
- memcpy(wptr, src, len);
- src = (uint8_t *)src + len;
- }
- wptr += len;
- if (wptr >= f->end)
- wptr = f->buffer;
- wndx += len;
- size -= len;
- } while (size > 0);
- f->wndx= wndx;
- f->wptr= wptr;
- return total - size;
-}
-
-int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int))
-{
- uint8_t *rptr = f->rptr;
-
- if (offset < 0 || buf_size > av_fifo_size(f) - offset)
- return AVERROR(EINVAL);
-
- if (offset >= f->end - rptr)
- rptr += offset - (f->end - f->buffer);
- else
- rptr += offset;
-
- while (buf_size > 0) {
- int len;
-
- if (rptr >= f->end)
- rptr -= f->end - f->buffer;
-
- len = FFMIN(f->end - rptr, buf_size);
- if (func)
- func(dest, rptr, len);
- else {
- memcpy(dest, rptr, len);
- dest = (uint8_t *)dest + len;
- }
-
- buf_size -= len;
- rptr += len;
- }
-
- return 0;
-}
-
-int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size,
- void (*func)(void *, void *, int))
-{
- return av_fifo_generic_peek_at(f, dest, 0, buf_size, func);
-}
-
-int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size,
- void (*func)(void *, void *, int))
-{
- if (buf_size > av_fifo_size(f))
- return AVERROR(EINVAL);
-
- do {
- int len = FFMIN(f->end - f->rptr, buf_size);
- if (func)
- func(dest, f->rptr, len);
- else {
- memcpy(dest, f->rptr, len);
- dest = (uint8_t *)dest + len;
- }
- av_fifo_drain(f, len);
- buf_size -= len;
- } while (buf_size > 0);
- return 0;
-}
-
-/** Discard data from the FIFO. */
-void av_fifo_drain(AVFifoBuffer *f, int size)
-{
- av_assert2(av_fifo_size(f) >= size);
- f->rptr += size;
- if (f->rptr >= f->end)
- f->rptr -= f->end - f->buffer;
- f->rndx += size;
-}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
diff --git a/media/ffvpx/libavutil/fifo.h b/media/ffvpx/libavutil/fifo.h
index ce3a2aed7c..f2206c35f5 100644
--- a/media/ffvpx/libavutil/fifo.h
+++ b/media/ffvpx/libavutil/fifo.h
@@ -26,10 +26,6 @@
#define AVUTIL_FIFO_H
#include <stddef.h>
-#include <stdint.h>
-
-#include "attributes.h"
-#include "version.h"
/**
* @defgroup lavu_fifo AVFifo
@@ -239,208 +235,6 @@ void av_fifo_reset2(AVFifo *f);
*/
void av_fifo_freep2(AVFifo **f);
-
-#if FF_API_FIFO_OLD_API
-typedef struct AVFifoBuffer {
- uint8_t *buffer;
- uint8_t *rptr, *wptr, *end;
- uint32_t rndx, wndx;
-} AVFifoBuffer;
-
-/**
- * Initialize an AVFifoBuffer.
- * @param size of FIFO
- * @return AVFifoBuffer or NULL in case of memory allocation failure
- * @deprecated use av_fifo_alloc2()
- */
-attribute_deprecated
-AVFifoBuffer *av_fifo_alloc(unsigned int size);
-
-/**
- * Initialize an AVFifoBuffer.
- * @param nmemb number of elements
- * @param size size of the single element
- * @return AVFifoBuffer or NULL in case of memory allocation failure
- * @deprecated use av_fifo_alloc2()
- */
-attribute_deprecated
-AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size);
-
-/**
- * Free an AVFifoBuffer.
- * @param f AVFifoBuffer to free
- * @deprecated use the AVFifo API with av_fifo_freep2()
- */
-attribute_deprecated
-void av_fifo_free(AVFifoBuffer *f);
-
-/**
- * Free an AVFifoBuffer and reset pointer to NULL.
- * @param f AVFifoBuffer to free
- * @deprecated use the AVFifo API with av_fifo_freep2()
- */
-attribute_deprecated
-void av_fifo_freep(AVFifoBuffer **f);
-
-/**
- * Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied.
- * @param f AVFifoBuffer to reset
- * @deprecated use av_fifo_reset2() with the new AVFifo-API
- */
-attribute_deprecated
-void av_fifo_reset(AVFifoBuffer *f);
-
-/**
- * Return the amount of data in bytes in the AVFifoBuffer, that is the
- * amount of data you can read from it.
- * @param f AVFifoBuffer to read from
- * @return size
- * @deprecated use av_fifo_can_read() with the new AVFifo-API
- */
-attribute_deprecated
-int av_fifo_size(const AVFifoBuffer *f);
-
-/**
- * Return the amount of space in bytes in the AVFifoBuffer, that is the
- * amount of data you can write into it.
- * @param f AVFifoBuffer to write into
- * @return size
- * @deprecated use av_fifo_can_write() with the new AVFifo-API
- */
-attribute_deprecated
-int av_fifo_space(const AVFifoBuffer *f);
-
-/**
- * Feed data at specific position from an AVFifoBuffer to a user-supplied callback.
- * Similar as av_fifo_gereric_read but without discarding data.
- * @param f AVFifoBuffer to read from
- * @param offset offset from current read position
- * @param buf_size number of bytes to read
- * @param func generic read function
- * @param dest data destination
- *
- * @return a non-negative number on success, a negative error code on failure
- *
- * @deprecated use the new AVFifo-API with av_fifo_peek() when func == NULL,
- * av_fifo_peek_to_cb() otherwise
- */
-attribute_deprecated
-int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int));
-
-/**
- * Feed data from an AVFifoBuffer to a user-supplied callback.
- * Similar as av_fifo_gereric_read but without discarding data.
- * @param f AVFifoBuffer to read from
- * @param buf_size number of bytes to read
- * @param func generic read function
- * @param dest data destination
- *
- * @return a non-negative number on success, a negative error code on failure
- *
- * @deprecated use the new AVFifo-API with av_fifo_peek() when func == NULL,
- * av_fifo_peek_to_cb() otherwise
- */
-attribute_deprecated
-int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int));
-
-/**
- * Feed data from an AVFifoBuffer to a user-supplied callback.
- * @param f AVFifoBuffer to read from
- * @param buf_size number of bytes to read
- * @param func generic read function
- * @param dest data destination
- *
- * @return a non-negative number on success, a negative error code on failure
- *
- * @deprecated use the new AVFifo-API with av_fifo_read() when func == NULL,
- * av_fifo_read_to_cb() otherwise
- */
-attribute_deprecated
-int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int));
-
-/**
- * Feed data from a user-supplied callback to an AVFifoBuffer.
- * @param f AVFifoBuffer to write to
- * @param src data source; non-const since it may be used as a
- * modifiable context by the function defined in func
- * @param size number of bytes to write
- * @param func generic write function; the first parameter is src,
- * the second is dest_buf, the third is dest_buf_size.
- * func must return the number of bytes written to dest_buf, or <= 0 to
- * indicate no more data available to write.
- * If func is NULL, src is interpreted as a simple byte array for source data.
- * @return the number of bytes written to the FIFO or a negative error code on failure
- *
- * @deprecated use the new AVFifo-API with av_fifo_write() when func == NULL,
- * av_fifo_write_from_cb() otherwise
- */
-attribute_deprecated
-int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int));
-
-/**
- * Resize an AVFifoBuffer.
- * In case of reallocation failure, the old FIFO is kept unchanged.
- *
- * @param f AVFifoBuffer to resize
- * @param size new AVFifoBuffer size in bytes
- * @return <0 for failure, >=0 otherwise
- *
- * @deprecated use the new AVFifo-API with av_fifo_grow2() to increase FIFO size,
- * decreasing FIFO size is not supported
- */
-attribute_deprecated
-int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size);
-
-/**
- * Enlarge an AVFifoBuffer.
- * In case of reallocation failure, the old FIFO is kept unchanged.
- * The new fifo size may be larger than the requested size.
- *
- * @param f AVFifoBuffer to resize
- * @param additional_space the amount of space in bytes to allocate in addition to av_fifo_size()
- * @return <0 for failure, >=0 otherwise
- *
- * @deprecated use the new AVFifo-API with av_fifo_grow2(); note that unlike
- * this function it adds to the allocated size, rather than to the used size
- */
-attribute_deprecated
-int av_fifo_grow(AVFifoBuffer *f, unsigned int additional_space);
-
-/**
- * Read and discard the specified amount of data from an AVFifoBuffer.
- * @param f AVFifoBuffer to read from
- * @param size amount of data to read in bytes
- *
- * @deprecated use the new AVFifo-API with av_fifo_drain2()
- */
-attribute_deprecated
-void av_fifo_drain(AVFifoBuffer *f, int size);
-
-#if FF_API_FIFO_PEEK2
-/**
- * Return a pointer to the data stored in a FIFO buffer at a certain offset.
- * The FIFO buffer is not modified.
- *
- * @param f AVFifoBuffer to peek at, f must be non-NULL
- * @param offs an offset in bytes, its absolute value must be less
- * than the used buffer size or the returned pointer will
- * point outside to the buffer data.
- * The used buffer size can be checked with av_fifo_size().
- * @deprecated use the new AVFifo-API with av_fifo_peek() or av_fifo_peek_to_cb()
- */
-attribute_deprecated
-static inline uint8_t *av_fifo_peek2(const AVFifoBuffer *f, int offs)
-{
- uint8_t *ptr = f->rptr + offs;
- if (ptr >= f->end)
- ptr = f->buffer + (ptr - f->end);
- else if (ptr < f->buffer)
- ptr = f->end - (f->buffer - ptr);
- return ptr;
-}
-#endif
-#endif
-
/**
* @}
*/
diff --git a/media/ffvpx/libavutil/film_grain_params.c b/media/ffvpx/libavutil/film_grain_params.c
index 930d23c7fe..0a6004b6b3 100644
--- a/media/ffvpx/libavutil/film_grain_params.c
+++ b/media/ffvpx/libavutil/film_grain_params.c
@@ -17,6 +17,8 @@
*/
#include "film_grain_params.h"
+#include "mem.h"
+#include "pixdesc.h"
AVFilmGrainParams *av_film_grain_params_alloc(size_t *size)
{
@@ -30,13 +32,75 @@ AVFilmGrainParams *av_film_grain_params_alloc(size_t *size)
AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame)
{
+ AVFilmGrainParams *fgp;
AVFrameSideData *side_data = av_frame_new_side_data(frame,
AV_FRAME_DATA_FILM_GRAIN_PARAMS,
sizeof(AVFilmGrainParams));
if (!side_data)
return NULL;
- memset(side_data->data, 0, sizeof(AVFilmGrainParams));
+ fgp = (AVFilmGrainParams *) side_data->data;
+ *fgp = (AVFilmGrainParams) {
+ .color_range = AVCOL_RANGE_UNSPECIFIED,
+ .color_primaries = AVCOL_PRI_UNSPECIFIED,
+ .color_trc = AVCOL_TRC_UNSPECIFIED,
+ .color_space = AVCOL_SPC_UNSPECIFIED,
+ };
- return (AVFilmGrainParams *)side_data->data;
+ return fgp;
+}
+
+const AVFilmGrainParams *av_film_grain_params_select(const AVFrame *frame)
+{
+ const AVFilmGrainParams *fgp, *best = NULL;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+ int bit_depth_luma, bit_depth_chroma;
+ if (!desc)
+ return NULL;
+
+ /* There are no YUV formats with different bit depth per component,
+ * so just check both against the first component for simplicity */
+ bit_depth_luma = bit_depth_chroma = desc->comp[0].depth;
+
+ for (int i = 0; i < frame->nb_side_data; i++) {
+ if (frame->side_data[i]->type != AV_FRAME_DATA_FILM_GRAIN_PARAMS)
+ continue;
+ fgp = (const AVFilmGrainParams*)frame->side_data[i]->data;
+ if (fgp->width && fgp->width > frame->width ||
+ fgp->height && fgp->height > frame->height)
+ continue;
+
+#define CHECK(a, b, unspec) \
+ if ((a) != (unspec) && (b) != (unspec) && (a) != (b)) \
+ continue
+
+ CHECK(fgp->bit_depth_luma, bit_depth_luma, 0);
+ CHECK(fgp->bit_depth_chroma, bit_depth_chroma, 0);
+ CHECK(fgp->color_range, frame->color_range, AVCOL_RANGE_UNSPECIFIED);
+ CHECK(fgp->color_primaries, frame->color_primaries, AVCOL_PRI_UNSPECIFIED);
+ CHECK(fgp->color_trc, frame->color_trc, AVCOL_TRC_UNSPECIFIED);
+ CHECK(fgp->color_space, frame->colorspace, AVCOL_SPC_UNSPECIFIED);
+
+ switch (fgp->type) {
+ case AV_FILM_GRAIN_PARAMS_NONE:
+ continue;
+ case AV_FILM_GRAIN_PARAMS_AV1:
+ /* AOM FGS needs an exact match for the chroma resolution */
+ if (fgp->subsampling_x != desc->log2_chroma_w ||
+ fgp->subsampling_y != desc->log2_chroma_h)
+ continue;
+ break;
+ case AV_FILM_GRAIN_PARAMS_H274:
+ /* H.274 FGS can be adapted to any lower chroma resolution */
+ if (fgp->subsampling_x > desc->log2_chroma_w ||
+ fgp->subsampling_y > desc->log2_chroma_h)
+ continue;
+ break;
+ }
+
+ if (!best || best->width < fgp->width || best->height < fgp->height)
+ best = fgp;
+ }
+
+ return best;
}
diff --git a/media/ffvpx/libavutil/film_grain_params.h b/media/ffvpx/libavutil/film_grain_params.h
index f3bd0a4a6a..ccacab88fe 100644
--- a/media/ffvpx/libavutil/film_grain_params.h
+++ b/media/ffvpx/libavutil/film_grain_params.h
@@ -136,20 +136,42 @@ typedef struct AVFilmGrainH274Params {
*/
int model_id;
- /**
- * Specifies the bit depth used for the luma component.
- */
+#if FF_API_H274_FILM_GRAIN_VCS
+ /**
+ * TODO: On this ABI bump, please also re-order the fields in
+ * AVFilmGrainParams (see below)
+ */
+
+ /**
+ * Specifies the bit depth used for the luma component.
+ *
+ * @deprecated use AVFilmGrainParams.bit_depth_luma.
+ */
+ attribute_deprecated
int bit_depth_luma;
/**
* Specifies the bit depth used for the chroma components.
+ *
+ * @deprecated use AVFilmGrainParams.bit_depth_chroma.
*/
+ attribute_deprecated
int bit_depth_chroma;
+ /**
+ * Specifies the video signal characteristics.
+ *
+ * @deprecated use AVFilmGrainParams.color_{range,primaries,trc,space}.
+ */
+ attribute_deprecated
enum AVColorRange color_range;
+ attribute_deprecated
enum AVColorPrimaries color_primaries;
+ attribute_deprecated
enum AVColorTransferCharacteristic color_trc;
+ attribute_deprecated
enum AVColorSpace color_space;
+#endif
/**
* Specifies the blending mode used to blend the simulated film grain
@@ -231,11 +253,40 @@ typedef struct AVFilmGrainParams {
* Additional fields may be added both here and in any structure included.
* If a codec's film grain structure differs slightly over another
* codec's, fields within may change meaning depending on the type.
+ *
+ * TODO: Move this to the end of the structure, at the next ABI bump.
*/
union {
AVFilmGrainAOMParams aom;
AVFilmGrainH274Params h274;
} codec;
+
+ /**
+ * Intended display resolution. May be 0 if the codec does not specify
+ * any restrictions.
+ */
+
+ int width, height;
+
+ /**
+ * Intended subsampling ratio, or 0 for luma-only streams.
+ */
+ int subsampling_x, subsampling_y;
+
+ /**
+ * Intended video signal characteristics.
+ */
+ enum AVColorRange color_range;
+ enum AVColorPrimaries color_primaries;
+ enum AVColorTransferCharacteristic color_trc;
+ enum AVColorSpace color_space;
+
+ /**
+ * Intended bit depth, or 0 for unknown/unspecified.
+ */
+ int bit_depth_luma;
+ int bit_depth_chroma;
+
} AVFilmGrainParams;
/**
@@ -257,4 +308,15 @@ AVFilmGrainParams *av_film_grain_params_alloc(size_t *size);
*/
AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame);
+/**
+ * Select the most appropriate film grain parameters set for the frame,
+ * taking into account the frame's format, resolution and video signal
+ * characteristics.
+ *
+ * @note, for H.274, this may select a film grain parameter set with
+ * greater chroma resolution than the frame. Users should take care to
+ * correctly adjust the chroma grain frequency to the frame.
+ */
+const AVFilmGrainParams *av_film_grain_params_select(const AVFrame *frame);
+
#endif /* AVUTIL_FILM_GRAIN_PARAMS_H */
diff --git a/media/ffvpx/libavutil/fixed_dsp.c b/media/ffvpx/libavutil/fixed_dsp.c
index 5ab47d55d0..95f0eb2595 100644
--- a/media/ffvpx/libavutil/fixed_dsp.c
+++ b/media/ffvpx/libavutil/fixed_dsp.c
@@ -47,6 +47,7 @@
#include "common.h"
#include "fixed_dsp.h"
+#include "mem.h"
static void vector_fmul_add_c(int *dst, const int *src0, const int *src1, const int *src2, int len){
int i;
@@ -135,7 +136,7 @@ static int scalarproduct_fixed_c(const int *v1, const int *v2, int len)
return (int)(p >> 31);
}
-static void butterflies_fixed_c(int *av_restrict v1s, int *av_restrict v2, int len)
+static void butterflies_fixed_c(int *restrict v1s, int *restrict v2, int len)
{
int i;
unsigned int *v1 = v1s;
diff --git a/media/ffvpx/libavutil/fixed_dsp.h b/media/ffvpx/libavutil/fixed_dsp.h
index 1217d3a53b..9b566af675 100644
--- a/media/ffvpx/libavutil/fixed_dsp.h
+++ b/media/ffvpx/libavutil/fixed_dsp.h
@@ -49,7 +49,6 @@
#define AVUTIL_FIXED_DSP_H
#include <stdint.h>
-#include "config.h"
#include "attributes.h"
#include "libavcodec/mathops.h"
@@ -150,7 +149,7 @@ typedef struct AVFixedDSPContext {
* @param v2 second input vector, difference output, 16-byte aligned
* @param len length of vectors, multiple of 4
*/
- void (*butterflies_fixed)(int *av_restrict v1, int *av_restrict v2, int len);
+ void (*butterflies_fixed)(int *restrict v1, int *restrict v2, int len);
} AVFixedDSPContext;
/**
diff --git a/media/ffvpx/libavutil/float_dsp.c b/media/ffvpx/libavutil/float_dsp.c
index 742dd679d2..e9fb023466 100644
--- a/media/ffvpx/libavutil/float_dsp.c
+++ b/media/ffvpx/libavutil/float_dsp.c
@@ -109,7 +109,7 @@ static void vector_fmul_reverse_c(float *dst, const float *src0,
dst[i] = src0[i] * src1[-i];
}
-static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2,
+static void butterflies_float_c(float *restrict v1, float *restrict v2,
int len)
{
int i;
diff --git a/media/ffvpx/libavutil/float_dsp.h b/media/ffvpx/libavutil/float_dsp.h
index 7cad9fc622..342a8715c5 100644
--- a/media/ffvpx/libavutil/float_dsp.h
+++ b/media/ffvpx/libavutil/float_dsp.h
@@ -19,8 +19,6 @@
#ifndef AVUTIL_FLOAT_DSP_H
#define AVUTIL_FLOAT_DSP_H
-#include "config.h"
-
typedef struct AVFloatDSPContext {
/**
* Calculate the entry wise product of two vectors of floats and store the result in
@@ -161,7 +159,7 @@ typedef struct AVFloatDSPContext {
* @param v2 second input vector, difference output, 16-byte aligned
* @param len length of vectors, multiple of 4
*/
- void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len);
+ void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);
/**
* Calculate the scalar product of two vectors of floats.
diff --git a/media/ffvpx/libavutil/frame.c b/media/ffvpx/libavutil/frame.c
index a3f07ca089..930f01dc19 100644
--- a/media/ffvpx/libavutil/frame.c
+++ b/media/ffvpx/libavutil/frame.c
@@ -28,12 +28,35 @@
#include "samplefmt.h"
#include "hwcontext.h"
-#if FF_API_OLD_CHANNEL_LAYOUT
-#define CHECK_CHANNELS_CONSISTENCY(frame) \
- av_assert2(!(frame)->channel_layout || \
- (frame)->channels == \
- av_get_channel_layout_nb_channels((frame)->channel_layout))
-#endif
+static const AVSideDataDescriptor sd_props[] = {
+ [AV_FRAME_DATA_PANSCAN] = { "AVPanScan" },
+ [AV_FRAME_DATA_A53_CC] = { "ATSC A53 Part 4 Closed Captions" },
+ [AV_FRAME_DATA_MATRIXENCODING] = { "AVMatrixEncoding" },
+ [AV_FRAME_DATA_DOWNMIX_INFO] = { "Metadata relevant to a downmix procedure" },
+ [AV_FRAME_DATA_AFD] = { "Active format description" },
+ [AV_FRAME_DATA_MOTION_VECTORS] = { "Motion vectors" },
+ [AV_FRAME_DATA_SKIP_SAMPLES] = { "Skip samples" },
+ [AV_FRAME_DATA_GOP_TIMECODE] = { "GOP timecode" },
+ [AV_FRAME_DATA_S12M_TIMECODE] = { "SMPTE 12-1 timecode" },
+ [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)" },
+ [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)" },
+ [AV_FRAME_DATA_REGIONS_OF_INTEREST] = { "Regions Of Interest" },
+ [AV_FRAME_DATA_VIDEO_ENC_PARAMS] = { "Video encoding parameters" },
+ [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { "Film grain parameters" },
+ [AV_FRAME_DATA_DETECTION_BBOXES] = { "Bounding boxes for object detection and classification" },
+ [AV_FRAME_DATA_DOVI_RPU_BUFFER] = { "Dolby Vision RPU Data" },
+ [AV_FRAME_DATA_DOVI_METADATA] = { "Dolby Vision Metadata" },
+ [AV_FRAME_DATA_STEREO3D] = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_REPLAYGAIN] = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_DISPLAYMATRIX] = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_AUDIO_SERVICE_TYPE] = { "Audio service type", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_SPHERICAL] = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_ICC_PROFILE] = { "ICC profile", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_SEI_UNREGISTERED] = { "H.26[45] User Data Unregistered SEI message", AV_SIDE_DATA_PROP_MULTI },
+};
static void get_frame_defaults(AVFrame *frame)
{
@@ -43,11 +66,6 @@ static void get_frame_defaults(AVFrame *frame)
frame->pkt_dts = AV_NOPTS_VALUE;
frame->best_effort_timestamp = AV_NOPTS_VALUE;
frame->duration = 0;
-#if FF_API_PKT_DURATION
-FF_DISABLE_DEPRECATION_WARNINGS
- frame->pkt_duration = 0;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
#if FF_API_FRAME_PKT
FF_DISABLE_DEPRECATION_WARNINGS
frame->pkt_pos = -1;
@@ -75,14 +93,56 @@ static void free_side_data(AVFrameSideData **ptr_sd)
av_freep(ptr_sd);
}
-static void wipe_side_data(AVFrame *frame)
+static void wipe_side_data(AVFrameSideData ***sd, int *nb_side_data)
{
- for (int i = 0; i < frame->nb_side_data; i++) {
- free_side_data(&frame->side_data[i]);
+ for (int i = 0; i < *nb_side_data; i++) {
+ free_side_data(&((*sd)[i]));
}
- frame->nb_side_data = 0;
+ *nb_side_data = 0;
+
+ av_freep(sd);
+}
- av_freep(&frame->side_data);
+static void frame_side_data_wipe(AVFrame *frame)
+{
+ wipe_side_data(&frame->side_data, &frame->nb_side_data);
+}
+
+void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
+{
+ wipe_side_data(sd, nb_sd);
+}
+
+static void remove_side_data(AVFrameSideData ***sd, int *nb_side_data,
+ const enum AVFrameSideDataType type)
+{
+ for (int i = *nb_side_data - 1; i >= 0; i--) {
+ AVFrameSideData *entry = ((*sd)[i]);
+ if (entry->type != type)
+ continue;
+
+ free_side_data(&entry);
+
+ ((*sd)[i]) = ((*sd)[*nb_side_data - 1]);
+ (*nb_side_data)--;
+ }
+}
+
+static void remove_side_data_by_entry(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *target)
+{
+ for (int i = *nb_sd - 1; i >= 0; i--) {
+ AVFrameSideData *entry = ((*sd)[i]);
+ if (entry != target)
+ continue;
+
+ free_side_data(&entry);
+
+ ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
+ (*nb_sd)--;
+
+ return;
+ }
}
AVFrame *av_frame_alloc(void)
@@ -181,21 +241,6 @@ static int get_audio_buffer(AVFrame *frame, int align)
int channels, planes;
int ret;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- if (!frame->ch_layout.nb_channels) {
- if (frame->channel_layout) {
- av_channel_layout_from_mask(&frame->ch_layout, frame->channel_layout);
- } else {
- frame->ch_layout.nb_channels = frame->channels;
- frame->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- }
- }
- frame->channels = frame->ch_layout.nb_channels;
- frame->channel_layout = frame->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
- frame->ch_layout.u.mask : 0;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
channels = frame->ch_layout.nb_channels;
planes = planar ? channels : 1;
if (!frame->linesize[0]) {
@@ -245,17 +290,11 @@ int av_frame_get_buffer(AVFrame *frame, int align)
if (frame->format < 0)
return AVERROR(EINVAL);
-FF_DISABLE_DEPRECATION_WARNINGS
if (frame->width > 0 && frame->height > 0)
return get_video_buffer(frame, align);
else if (frame->nb_samples > 0 &&
- (av_channel_layout_check(&frame->ch_layout)
-#if FF_API_OLD_CHANNEL_LAYOUT
- || frame->channel_layout || frame->channels > 0
-#endif
- ))
+ (av_channel_layout_check(&frame->ch_layout)))
return get_audio_buffer(frame, align);
-FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR(EINVAL);
}
@@ -298,25 +337,9 @@ FF_DISABLE_DEPRECATION_WARNINGS
dst->pkt_size = src->pkt_size;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
-#if FF_API_PKT_DURATION
-FF_DISABLE_DEPRECATION_WARNINGS
- dst->pkt_duration = src->pkt_duration;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
dst->time_base = src->time_base;
-#if FF_API_REORDERED_OPAQUE
-FF_DISABLE_DEPRECATION_WARNINGS
- dst->reordered_opaque = src->reordered_opaque;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
dst->quality = src->quality;
dst->best_effort_timestamp = src->best_effort_timestamp;
-#if FF_API_FRAME_PICTURE_NUMBER
-FF_DISABLE_DEPRECATION_WARNINGS
- dst->coded_picture_number = src->coded_picture_number;
- dst->display_picture_number = src->display_picture_number;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
dst->flags = src->flags;
dst->decode_error_flags = src->decode_error_flags;
dst->color_primaries = src->color_primaries;
@@ -337,7 +360,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
sd_dst = av_frame_new_side_data(dst, sd_src->type,
sd_src->size);
if (!sd_dst) {
- wipe_side_data(dst);
+ frame_side_data_wipe(dst);
return AVERROR(ENOMEM);
}
memcpy(sd_dst->data, sd_src->data, sd_src->size);
@@ -346,7 +369,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
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);
+ frame_side_data_wipe(dst);
return AVERROR(ENOMEM);
}
}
@@ -363,11 +386,6 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
int ret = 0;
av_assert1(dst->width == 0 && dst->height == 0);
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- av_assert1(dst->channels == 0);
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
av_assert1(dst->ch_layout.nb_channels == 0 &&
dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
@@ -375,31 +393,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
dst->width = src->width;
dst->height = src->height;
dst->nb_samples = src->nb_samples;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- dst->channels = src->channels;
- dst->channel_layout = src->channel_layout;
- if (!av_channel_layout_check(&src->ch_layout)) {
- if (src->channel_layout)
- av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout);
- else {
- dst->ch_layout.nb_channels = src->channels;
- dst->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- }
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
ret = frame_copy_props(dst, src, 0);
if (ret < 0)
goto fail;
- // this check is needed only until FF_API_OLD_CHANNEL_LAYOUT is out
- if (av_channel_layout_check(&src->ch_layout)) {
- ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
- if (ret < 0)
- goto fail;
- }
+ ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
+ if (ret < 0)
+ goto fail;
/* duplicate the frame data if it's not refcounted */
if (!src->buf[0]) {
@@ -503,29 +504,12 @@ int av_frame_replace(AVFrame *dst, const AVFrame *src)
dst->width = src->width;
dst->height = src->height;
dst->nb_samples = src->nb_samples;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- dst->channels = src->channels;
- dst->channel_layout = src->channel_layout;
- if (!av_channel_layout_check(&src->ch_layout)) {
- av_channel_layout_uninit(&dst->ch_layout);
- if (src->channel_layout)
- av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout);
- else {
- dst->ch_layout.nb_channels = src->channels;
- dst->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- }
- } else {
-#endif
+
ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
if (ret < 0)
goto fail;
-#if FF_API_OLD_CHANNEL_LAYOUT
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- wipe_side_data(dst);
+ frame_side_data_wipe(dst);
av_dict_free(&dst->metadata);
ret = frame_copy_props(dst, src, 0);
if (ret < 0)
@@ -624,7 +608,7 @@ void av_frame_unref(AVFrame *frame)
if (!frame)
return;
- wipe_side_data(frame);
+ frame_side_data_wipe(frame);
for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
av_buffer_unref(&frame->buf[i]);
@@ -649,11 +633,6 @@ void av_frame_unref(AVFrame *frame)
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
{
av_assert1(dst->width == 0 && dst->height == 0);
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- av_assert1(dst->channels == 0);
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
av_assert1(dst->ch_layout.nb_channels == 0 &&
dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
@@ -692,12 +671,6 @@ int av_frame_make_writable(AVFrame *frame)
tmp.format = frame->format;
tmp.width = frame->width;
tmp.height = frame->height;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- tmp.channels = frame->channels;
- tmp.channel_layout = frame->channel_layout;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
tmp.nb_samples = frame->nb_samples;
ret = av_channel_layout_copy(&tmp.ch_layout, &frame->ch_layout);
if (ret < 0) {
@@ -745,15 +718,6 @@ AVBufferRef *av_frame_get_plane_buffer(const AVFrame *frame, int plane)
if (frame->nb_samples) {
int channels = frame->ch_layout.nb_channels;
-
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- if (!channels) {
- channels = frame->channels;
- CHECK_CHANNELS_CONSISTENCY(frame);
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
if (!channels)
return NULL;
planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
@@ -777,38 +741,57 @@ FF_ENABLE_DEPRECATION_WARNINGS
return NULL;
}
-AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
- enum AVFrameSideDataType type,
- AVBufferRef *buf)
+static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
+ int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef *buf, uint8_t *data,
+ size_t size)
{
AVFrameSideData *ret, **tmp;
- if (!buf)
- return NULL;
-
- if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1)
+ // *nb_sd + 1 needs to fit into an int and a size_t.
+ if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX))
return NULL;
- tmp = av_realloc(frame->side_data,
- (frame->nb_side_data + 1) * sizeof(*frame->side_data));
+ tmp = av_realloc_array(*sd, sizeof(**sd), *nb_sd + 1);
if (!tmp)
return NULL;
- frame->side_data = tmp;
+ *sd = tmp;
ret = av_mallocz(sizeof(*ret));
if (!ret)
return NULL;
ret->buf = buf;
- ret->data = ret->buf->data;
- ret->size = buf->size;
+ ret->data = data;
+ ret->size = size;
ret->type = type;
- frame->side_data[frame->nb_side_data++] = ret;
+ (*sd)[(*nb_sd)++] = ret;
return ret;
}
+static AVFrameSideData *add_side_data_from_buf(AVFrameSideData ***sd,
+ int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef *buf)
+{
+ if (!buf)
+ return NULL;
+
+ return add_side_data_from_buf_ext(sd, nb_sd, type, buf, buf->data, buf->size);
+}
+
+AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
+ enum AVFrameSideDataType type,
+ AVBufferRef *buf)
+{
+ return
+ add_side_data_from_buf(
+ &frame->side_data, &frame->nb_side_data, type, buf);
+}
+
AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
enum AVFrameSideDataType type,
size_t size)
@@ -821,16 +804,76 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
return ret;
}
-AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
- enum AVFrameSideDataType type)
+AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ size_t size, unsigned int flags)
+{
+ AVBufferRef *buf = av_buffer_alloc(size);
+ AVFrameSideData *ret = NULL;
+
+ if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
+ remove_side_data(sd, nb_sd, type);
+
+ ret = add_side_data_from_buf(sd, nb_sd, type, buf);
+ if (!ret)
+ av_buffer_unref(&buf);
+
+ return ret;
+}
+
+int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *src, unsigned int flags)
+{
+ AVBufferRef *buf = NULL;
+ AVFrameSideData *sd_dst = NULL;
+ int ret = AVERROR_BUG;
+
+ if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
+ return AVERROR(EINVAL);
+
+ buf = av_buffer_ref(src->buf);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
+ remove_side_data(sd, nb_sd, src->type);
+
+ sd_dst = add_side_data_from_buf_ext(sd, nb_sd, src->type, buf,
+ src->data, src->size);
+ if (!sd_dst) {
+ av_buffer_unref(&buf);
+ return AVERROR(ENOMEM);
+ }
+
+ ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0);
+ if (ret < 0) {
+ remove_side_data_by_entry(sd, nb_sd, sd_dst);
+ return ret;
+ }
+
+ return 0;
+}
+
+const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *sd,
+ const int nb_sd,
+ enum AVFrameSideDataType type)
{
- for (int i = 0; i < frame->nb_side_data; i++) {
- if (frame->side_data[i]->type == type)
- return frame->side_data[i];
+ for (int i = 0; i < nb_sd; i++) {
+ if (sd[i]->type == type)
+ return sd[i];
}
return NULL;
}
+AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
+ enum AVFrameSideDataType type)
+{
+ return (AVFrameSideData *)av_frame_side_data_get(
+ frame->side_data, frame->nb_side_data,
+ type
+ );
+}
+
static int frame_copy_video(AVFrame *dst, const AVFrame *src)
{
int planes;
@@ -860,30 +903,8 @@ static int frame_copy_audio(AVFrame *dst, const AVFrame *src)
int channels = dst->ch_layout.nb_channels;
int planes = planar ? channels : 1;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- if (!channels || !src->ch_layout.nb_channels) {
- if (dst->channels != src->channels ||
- dst->channel_layout != src->channel_layout)
- return AVERROR(EINVAL);
- CHECK_CHANNELS_CONSISTENCY(src);
- }
- if (!channels) {
- channels = dst->channels;
- planes = planar ? channels : 1;
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
if (dst->nb_samples != src->nb_samples ||
-#if FF_API_OLD_CHANNEL_LAYOUT
- (av_channel_layout_check(&dst->ch_layout) &&
- av_channel_layout_check(&src->ch_layout) &&
-#endif
av_channel_layout_compare(&dst->ch_layout, &src->ch_layout))
-#if FF_API_OLD_CHANNEL_LAYOUT
- )
-#endif
return AVERROR(EINVAL);
for (int i = 0; i < planes; i++)
@@ -901,67 +922,34 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src)
if (dst->format != src->format || dst->format < 0)
return AVERROR(EINVAL);
-FF_DISABLE_DEPRECATION_WARNINGS
if (dst->width > 0 && dst->height > 0)
return frame_copy_video(dst, src);
else if (dst->nb_samples > 0 &&
- (av_channel_layout_check(&dst->ch_layout)
-#if FF_API_OLD_CHANNEL_LAYOUT
- || dst->channels > 0
-#endif
- ))
+ (av_channel_layout_check(&dst->ch_layout)))
return frame_copy_audio(dst, src);
-FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR(EINVAL);
}
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
{
- for (int i = frame->nb_side_data - 1; i >= 0; i--) {
- AVFrameSideData *sd = frame->side_data[i];
- if (sd->type == type) {
- free_side_data(&frame->side_data[i]);
- frame->side_data[i] = frame->side_data[frame->nb_side_data - 1];
- frame->nb_side_data--;
- }
- }
+ remove_side_data(&frame->side_data, &frame->nb_side_data, type);
}
-const char *av_frame_side_data_name(enum AVFrameSideDataType type)
+const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type)
{
- switch(type) {
- case AV_FRAME_DATA_PANSCAN: return "AVPanScan";
- case AV_FRAME_DATA_A53_CC: return "ATSC A53 Part 4 Closed Captions";
- case AV_FRAME_DATA_STEREO3D: return "Stereo 3D";
- case AV_FRAME_DATA_MATRIXENCODING: return "AVMatrixEncoding";
- case AV_FRAME_DATA_DOWNMIX_INFO: return "Metadata relevant to a downmix procedure";
- case AV_FRAME_DATA_REPLAYGAIN: return "AVReplayGain";
- case AV_FRAME_DATA_DISPLAYMATRIX: return "3x3 displaymatrix";
- case AV_FRAME_DATA_AFD: return "Active format description";
- case AV_FRAME_DATA_MOTION_VECTORS: return "Motion vectors";
- case AV_FRAME_DATA_SKIP_SAMPLES: return "Skip samples";
- case AV_FRAME_DATA_AUDIO_SERVICE_TYPE: return "Audio service type";
- case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata";
- 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_S12M_TIMECODE: return "SMPTE 12-1 timecode";
- case AV_FRAME_DATA_SPHERICAL: return "Spherical Mapping";
- case AV_FRAME_DATA_ICC_PROFILE: return "ICC profile";
- case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)";
- case AV_FRAME_DATA_DYNAMIC_HDR_VIVID: return "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)";
- case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest";
- case AV_FRAME_DATA_VIDEO_ENC_PARAMS: return "Video encoding parameters";
- case AV_FRAME_DATA_SEI_UNREGISTERED: return "H.26[45] User Data Unregistered SEI message";
- case AV_FRAME_DATA_FILM_GRAIN_PARAMS: return "Film grain parameters";
- case AV_FRAME_DATA_DETECTION_BBOXES: return "Bounding boxes for object detection and classification";
- case AV_FRAME_DATA_DOVI_RPU_BUFFER: return "Dolby Vision RPU Data";
- case AV_FRAME_DATA_DOVI_METADATA: return "Dolby Vision Metadata";
- case AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT: return "Ambient viewing environment";
- }
+ unsigned t = type;
+ if (t < FF_ARRAY_ELEMS(sd_props) && sd_props[t].name)
+ return &sd_props[t];
return NULL;
}
+const char *av_frame_side_data_name(enum AVFrameSideDataType type)
+{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
+ return desc ? desc->name : NULL;
+}
+
static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame,
const AVPixFmtDescriptor *desc)
{
diff --git a/media/ffvpx/libavutil/frame.h b/media/ffvpx/libavutil/frame.h
index c0c1b23db7..3b6d746a16 100644
--- a/media/ffvpx/libavutil/frame.h
+++ b/media/ffvpx/libavutil/frame.h
@@ -180,6 +180,10 @@ enum AVFrameSideDataType {
/**
* Film grain parameters for a frame, described by AVFilmGrainParams.
* Must be present for every frame which should have film grain applied.
+ *
+ * May be present multiple times, for example when there are multiple
+ * alternative parameter sets for different video signal characteristics.
+ * The user should select the most appropriate set for the application.
*/
AV_FRAME_DATA_FILM_GRAIN_PARAMS,
@@ -251,6 +255,37 @@ typedef struct AVFrameSideData {
AVBufferRef *buf;
} AVFrameSideData;
+enum AVSideDataProps {
+ /**
+ * The side data type can be used in stream-global structures.
+ * Side data types without this property are only meaningful on per-frame
+ * basis.
+ */
+ AV_SIDE_DATA_PROP_GLOBAL = (1 << 0),
+
+ /**
+ * Multiple instances of this side data type can be meaningfully present in
+ * a single side data array.
+ */
+ AV_SIDE_DATA_PROP_MULTI = (1 << 1),
+};
+
+/**
+ * This struct describes the properties of a side data type. Its instance
+ * corresponding to a given type can be obtained from av_frame_side_data_desc().
+ */
+typedef struct AVSideDataDescriptor {
+ /**
+ * Human-readable side data description.
+ */
+ const char *name;
+
+ /**
+ * Side data property flags, a combination of AVSideDataProps values.
+ */
+ unsigned props;
+} AVSideDataDescriptor;
+
/**
* Structure describing a single Region Of Interest.
*
@@ -466,19 +501,6 @@ typedef struct AVFrame {
*/
AVRational time_base;
-#if FF_API_FRAME_PICTURE_NUMBER
- /**
- * picture number in bitstream order
- */
- attribute_deprecated
- int coded_picture_number;
- /**
- * picture number in display order
- */
- attribute_deprecated
- int display_picture_number;
-#endif
-
/**
* quality (between 1 (good) and FF_LAMBDA_MAX (bad))
*/
@@ -546,35 +568,11 @@ typedef struct AVFrame {
int palette_has_changed;
#endif
-#if FF_API_REORDERED_OPAQUE
- /**
- * reordered opaque 64 bits (generally an integer or a double precision float
- * PTS but can be anything).
- * The user sets AVCodecContext.reordered_opaque to represent the input at
- * that time,
- * the decoder reorders values as needed and sets AVFrame.reordered_opaque
- * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
- *
- * @deprecated Use AV_CODEC_FLAG_COPY_OPAQUE instead
- */
- attribute_deprecated
- int64_t reordered_opaque;
-#endif
-
/**
* Sample rate of the audio data.
*/
int sample_rate;
-#if FF_API_OLD_CHANNEL_LAYOUT
- /**
- * Channel layout of the audio data.
- * @deprecated use ch_layout instead
- */
- attribute_deprecated
- uint64_t channel_layout;
-#endif
-
/**
* AVBuffer references backing the data for this frame. All the pointers in
* data and extended_data must point inside one of the buffers in buf or
@@ -687,19 +685,6 @@ typedef struct AVFrame {
int64_t pkt_pos;
#endif
-#if FF_API_PKT_DURATION
- /**
- * duration of the corresponding packet, expressed in
- * AVStream->time_base units, 0 if unknown.
- * - encoding: unused
- * - decoding: Read by user.
- *
- * @deprecated use duration instead
- */
- attribute_deprecated
- int64_t pkt_duration;
-#endif
-
/**
* metadata.
* - encoding: Set by user.
@@ -720,17 +705,6 @@ typedef struct AVFrame {
#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4
#define FF_DECODE_ERROR_DECODE_SLICES 8
-#if FF_API_OLD_CHANNEL_LAYOUT
- /**
- * number of audio channels, only used for audio.
- * - encoding: unused
- * - decoding: Read by user.
- * @deprecated use ch_layout instead
- */
- attribute_deprecated
- int channels;
-#endif
-
#if FF_API_FRAME_PKT
/**
* size of the corresponding packet containing the compressed
@@ -1050,6 +1024,94 @@ int av_frame_apply_cropping(AVFrame *frame, int flags);
const char *av_frame_side_data_name(enum AVFrameSideDataType type);
/**
+ * @return side data descriptor corresponding to a given side data type, NULL
+ * when not available.
+ */
+const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type);
+
+/**
+ * Free all side data entries and their contents, then zeroes out the
+ * values which the pointers are pointing to.
+ *
+ * @param sd pointer to array of side data to free. Will be set to NULL
+ * upon return.
+ * @param nb_sd pointer to an integer containing the number of entries in
+ * the array. Will be set to 0 upon return.
+ */
+void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd);
+
+#define AV_FRAME_SIDE_DATA_FLAG_UNIQUE (1 << 0)
+
+/**
+ * Add new side data entry to an array.
+ *
+ * @param sd pointer to array of side data to which to add another entry,
+ * or to NULL in order to start a new array.
+ * @param nb_sd pointer to an integer containing the number of entries in
+ * the array.
+ * @param type type of the added side data
+ * @param size size of the side data
+ * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
+ *
+ * @return newly added side data on success, NULL on error. In case of
+ * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
+ * AVFrameSideDataType will be removed before the addition is
+ * attempted.
+ */
+AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ size_t size, unsigned int flags);
+
+/**
+ * Add a new side data entry to an array based on existing side data, taking
+ * a reference towards the contained AVBufferRef.
+ *
+ * @param sd pointer to array of side data to which to add another entry,
+ * or to NULL in order to start a new array.
+ * @param nb_sd pointer to an integer containing the number of entries in
+ * the array.
+ * @param src side data to be cloned, with a new reference utilized
+ * for the buffer.
+ * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
+ *
+ * @return negative error code on failure, >=0 on success. In case of
+ * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
+ * AVFrameSideDataType will be removed before the addition is
+ * attempted.
+ */
+int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *src, unsigned int flags);
+
+/**
+ * Get a side data entry of a specific type from an array.
+ *
+ * @param sd array of side data.
+ * @param nb_sd integer containing the number of entries in the array.
+ * @param type type of side data to be queried
+ *
+ * @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 set.
+ */
+const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *sd,
+ const int nb_sd,
+ enum AVFrameSideDataType type);
+
+/**
+ * Wrapper around av_frame_side_data_get_c() to workaround the limitation
+ * that for any type T the conversion from T * const * to const T * const *
+ * is not performed automatically in C.
+ * @see av_frame_side_data_get_c()
+ */
+static inline
+const AVFrameSideData *av_frame_side_data_get(AVFrameSideData * const *sd,
+ const int nb_sd,
+ enum AVFrameSideDataType type)
+{
+ return av_frame_side_data_get_c((const AVFrameSideData * const *)sd,
+ nb_sd, type);
+}
+
+/**
* @}
*/
diff --git a/media/ffvpx/libavutil/hdr_dynamic_metadata.h b/media/ffvpx/libavutil/hdr_dynamic_metadata.h
index 09e9d8bbcc..5100ed6f41 100644
--- a/media/ffvpx/libavutil/hdr_dynamic_metadata.h
+++ b/media/ffvpx/libavutil/hdr_dynamic_metadata.h
@@ -359,13 +359,13 @@ int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *s, const uint8_t *data,
* Serialize dynamic HDR10+ metadata to a user data registered ITU-T T.35 buffer,
* excluding the first 48 bytes of the header, and beginning with the application mode.
* @param s A pointer containing the decoded AVDynamicHDRPlus structure.
- * @param data[in,out] A pointer to pointer to a byte buffer to be filled with the
+ * @param[in,out] data A pointer to pointer to a byte buffer to be filled with the
* serialized metadata.
* If *data is NULL, a buffer be will be allocated and a pointer to
* it stored in its place. The caller assumes ownership of the buffer.
* May be NULL, in which case the function will only store the
* required buffer size in *size.
- * @param size[in,out] A pointer to a size to be set to the returned buffer's size.
+ * @param[in,out] size A pointer to a size to be set to the returned buffer's size.
* If *data is not NULL, *size must contain the size of the input
* buffer. May be NULL only if *data is NULL.
*
diff --git a/media/ffvpx/libavutil/hwcontext.c b/media/ffvpx/libavutil/hwcontext.c
index e23bad230f..fa99a0d8a4 100644
--- a/media/ffvpx/libavutil/hwcontext.c
+++ b/media/ffvpx/libavutil/hwcontext.c
@@ -84,6 +84,21 @@ static const char *const hw_type_names[] = {
[AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
};
+typedef struct FFHWDeviceContext {
+ /**
+ * The public AVHWDeviceContext. See hwcontext.h for it.
+ */
+ AVHWDeviceContext p;
+
+ const HWContextType *hw_type;
+
+ /**
+ * For a derived device, a reference to the original device
+ * context it was derived from.
+ */
+ AVBufferRef *source_device;
+} FFHWDeviceContext;
+
enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
{
int type;
@@ -126,26 +141,26 @@ static const AVClass hwdevice_ctx_class = {
static void hwdevice_ctx_free(void *opaque, uint8_t *data)
{
- AVHWDeviceContext *ctx = (AVHWDeviceContext*)data;
+ FFHWDeviceContext *ctxi = (FFHWDeviceContext*)data;
+ AVHWDeviceContext *ctx = &ctxi->p;
/* 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 (ctxi->hw_type->device_uninit)
+ ctxi->hw_type->device_uninit(ctx);
if (ctx->free)
ctx->free(ctx);
- av_buffer_unref(&ctx->internal->source_device);
+ av_buffer_unref(&ctxi->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)
{
+ FFHWDeviceContext *ctxi;
AVHWDeviceContext *ctx;
AVBufferRef *buf;
const HWContextType *hw_type = NULL;
@@ -160,19 +175,10 @@ AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
if (!hw_type)
return NULL;
- ctx = av_mallocz(sizeof(*ctx));
- if (!ctx)
+ ctxi = av_mallocz(sizeof(*ctxi));
+ if (!ctxi)
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;
- }
+ ctx = &ctxi->p;
if (hw_type->device_hwctx_size) {
ctx->hwctx = av_mallocz(hw_type->device_hwctx_size);
@@ -189,14 +195,11 @@ AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
ctx->type = type;
ctx->av_class = &hwdevice_ctx_class;
- ctx->internal->hw_type = hw_type;
+ ctxi->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;
@@ -204,19 +207,13 @@ fail:
int av_hwdevice_ctx_init(AVBufferRef *ref)
{
- AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
- int ret;
+ FFHWDeviceContext *ctxi = (FFHWDeviceContext*)ref->data;
+ AVHWDeviceContext *ctx = &ctxi->p;
+ int ret = 0;
- if (ctx->internal->hw_type->device_init) {
- ret = ctx->internal->hw_type->device_init(ctx);
- if (ret < 0)
- goto fail;
- }
+ if (ctxi->hw_type->device_init)
+ ret = ctxi->hw_type->device_init(ctx);
- return 0;
-fail:
- if (ctx->internal->hw_type->device_uninit)
- ctx->internal->hw_type->device_uninit(ctx);
return ret;
}
@@ -228,47 +225,38 @@ static const AVClass hwframe_ctx_class = {
static void hwframe_ctx_free(void *opaque, uint8_t *data)
{
- AVHWFramesContext *ctx = (AVHWFramesContext*)data;
+ FFHWFramesContext *ctxi = (FFHWFramesContext*)data;
+ AVHWFramesContext *ctx = &ctxi->p;
- if (ctx->internal->pool_internal)
- av_buffer_pool_uninit(&ctx->internal->pool_internal);
+ if (ctxi->pool_internal)
+ av_buffer_pool_uninit(&ctxi->pool_internal);
- if (ctx->internal->hw_type->frames_uninit)
- ctx->internal->hw_type->frames_uninit(ctx);
+ if (ctxi->hw_type->frames_uninit)
+ ctxi->hw_type->frames_uninit(ctx);
if (ctx->free)
ctx->free(ctx);
- av_buffer_unref(&ctx->internal->source_frames);
+ av_buffer_unref(&ctxi->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;
+ FFHWDeviceContext *device_ctx = (FFHWDeviceContext*)device_ref_in->data;
+ const HWContextType *hw_type = device_ctx->hw_type;
+ FFHWFramesContext *ctxi;
AVHWFramesContext *ctx;
AVBufferRef *buf, *device_ref = NULL;
- ctx = av_mallocz(sizeof(*ctx));
- if (!ctx)
+ ctxi = av_mallocz(sizeof(*ctxi));
+ if (!ctxi)
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;
- }
+ ctx = &ctxi->p;
if (hw_type->frames_hwctx_size) {
ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size);
@@ -288,20 +276,16 @@ AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
ctx->av_class = &hwframe_ctx_class;
ctx->device_ref = device_ref;
- ctx->device_ctx = device_ctx;
+ ctx->device_ctx = &device_ctx->p;
ctx->format = AV_PIX_FMT_NONE;
ctx->sw_format = AV_PIX_FMT_NONE;
- ctx->internal->hw_type = hw_type;
+ ctxi->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_buffer_unref(&device_ref);
av_freep(&ctx->hwctx);
av_freep(&ctx);
return NULL;
@@ -337,24 +321,25 @@ fail:
int av_hwframe_ctx_init(AVBufferRef *ref)
{
- AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data;
+ FFHWFramesContext *ctxi = (FFHWFramesContext*)ref->data;
+ AVHWFramesContext *ctx = &ctxi->p;
const enum AVPixelFormat *pix_fmt;
int ret;
- if (ctx->internal->source_frames) {
+ if (ctxi->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++) {
+ for (pix_fmt = ctxi->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);
+ av_get_pix_fmt_name(ctx->format), ctxi->hw_type->name);
return AVERROR(ENOSYS);
}
@@ -364,39 +349,35 @@ int av_hwframe_ctx_init(AVBufferRef *ref)
return ret;
/* format-specific init */
- if (ctx->internal->hw_type->frames_init) {
- ret = ctx->internal->hw_type->frames_init(ctx);
+ if (ctxi->hw_type->frames_init) {
+ ret = ctxi->hw_type->frames_init(ctx);
if (ret < 0)
- goto fail;
+ return ret;
}
- if (ctx->internal->pool_internal && !ctx->pool)
- ctx->pool = ctx->internal->pool_internal;
+ if (ctxi->pool_internal && !ctx->pool)
+ ctx->pool = ctxi->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 ret;
}
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;
+ FFHWFramesContext *ctxi = (FFHWFramesContext*)hwframe_ref->data;
- if (!ctx->internal->hw_type->transfer_get_formats)
+ if (!ctxi->hw_type->transfer_get_formats)
return AVERROR(ENOSYS);
- return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats);
+ return ctxi->hw_type->transfer_get_formats(&ctxi->p, dir, formats);
}
static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
@@ -451,7 +432,6 @@ fail:
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
{
- AVHWFramesContext *ctx;
int ret;
if (!dst->buf[0])
@@ -464,41 +444,41 @@ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
* the specific combination of hardware.
*/
if (src->hw_frames_ctx && dst->hw_frames_ctx) {
- AVHWFramesContext *src_ctx =
- (AVHWFramesContext*)src->hw_frames_ctx->data;
- AVHWFramesContext *dst_ctx =
- (AVHWFramesContext*)dst->hw_frames_ctx->data;
+ FFHWFramesContext *src_ctx =
+ (FFHWFramesContext*)src->hw_frames_ctx->data;
+ FFHWFramesContext *dst_ctx =
+ (FFHWFramesContext*)dst->hw_frames_ctx->data;
- if (src_ctx->internal->source_frames) {
+ if (src_ctx->source_frames) {
av_log(src_ctx, AV_LOG_ERROR,
"A device with a derived frame context cannot be used as "
"the source of a HW -> HW transfer.");
return AVERROR(ENOSYS);
}
- if (dst_ctx->internal->source_frames) {
+ if (dst_ctx->source_frames) {
av_log(src_ctx, AV_LOG_ERROR,
"A device with a derived frame context cannot be used as "
"the destination of a HW -> HW transfer.");
return AVERROR(ENOSYS);
}
- ret = src_ctx->internal->hw_type->transfer_data_from(src_ctx, dst, src);
+ ret = src_ctx->hw_type->transfer_data_from(&src_ctx->p, dst, src);
if (ret == AVERROR(ENOSYS))
- ret = dst_ctx->internal->hw_type->transfer_data_to(dst_ctx, dst, src);
+ ret = dst_ctx->hw_type->transfer_data_to(&dst_ctx->p, dst, src);
if (ret < 0)
return ret;
} else {
if (src->hw_frames_ctx) {
- ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
+ FFHWFramesContext *ctx = (FFHWFramesContext*)src->hw_frames_ctx->data;
- ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
+ ret = ctx->hw_type->transfer_data_from(&ctx->p, dst, src);
if (ret < 0)
return ret;
} else if (dst->hw_frames_ctx) {
- ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
+ FFHWFramesContext *ctx = (FFHWFramesContext*)dst->hw_frames_ctx->data;
- ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
+ ret = ctx->hw_type->transfer_data_to(&ctx->p, dst, src);
if (ret < 0)
return ret;
} else {
@@ -510,10 +490,11 @@ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
{
- AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
+ FFHWFramesContext *ctxi = (FFHWFramesContext*)hwframe_ref->data;
+ AVHWFramesContext *ctx = &ctxi->p;
int ret;
- if (ctx->internal->source_frames) {
+ if (ctxi->source_frames) {
// This is a derived frame context, so we allocate in the source
// and map the frame immediately.
AVFrame *src_frame;
@@ -527,7 +508,7 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
if (!src_frame)
return AVERROR(ENOMEM);
- ret = av_hwframe_get_buffer(ctx->internal->source_frames,
+ ret = av_hwframe_get_buffer(ctxi->source_frames,
src_frame, 0);
if (ret < 0) {
av_frame_free(&src_frame);
@@ -535,7 +516,7 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
}
ret = av_hwframe_map(frame, src_frame,
- ctx->internal->source_allocation_map_flags);
+ ctxi->source_allocation_map_flags);
if (ret) {
av_log(ctx, AV_LOG_ERROR, "Failed to map frame into derived "
"frame context: %d.\n", ret);
@@ -550,7 +531,7 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
return 0;
}
- if (!ctx->internal->hw_type->frames_get_buffer)
+ if (!ctxi->hw_type->frames_get_buffer)
return AVERROR(ENOSYS);
if (!ctx->pool)
@@ -560,7 +541,7 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
if (!frame->hw_frames_ctx)
return AVERROR(ENOMEM);
- ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame);
+ ret = ctxi->hw_type->frames_get_buffer(ctx, frame);
if (ret < 0) {
av_buffer_unref(&frame->hw_frames_ctx);
return ret;
@@ -573,8 +554,8 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
{
- AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
- const HWContextType *hw_type = ctx->internal->hw_type;
+ FFHWDeviceContext *ctx = (FFHWDeviceContext*)ref->data;
+ const HWContextType *hw_type = ctx->hw_type;
if (hw_type->device_hwconfig_size == 0)
return NULL;
@@ -585,8 +566,8 @@ void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref,
const void *hwconfig)
{
- AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
- const HWContextType *hw_type = ctx->internal->hw_type;
+ FFHWDeviceContext *ctx = (FFHWDeviceContext*)ref->data;
+ const HWContextType *hw_type = ctx->hw_type;
AVHWFramesConstraints *constraints;
if (!hw_type->frames_get_constraints)
@@ -599,7 +580,7 @@ AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref,
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) {
+ if (hw_type->frames_get_constraints(&ctx->p, hwconfig, constraints) >= 0) {
return constraints;
} else {
av_hwframe_constraints_free(&constraints);
@@ -620,7 +601,7 @@ 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;
+ FFHWDeviceContext *device_ctx;
int ret = 0;
device_ref = av_hwdevice_ctx_alloc(type);
@@ -628,15 +609,15 @@ int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type,
ret = AVERROR(ENOMEM);
goto fail;
}
- device_ctx = (AVHWDeviceContext*)device_ref->data;
+ device_ctx = (FFHWDeviceContext*)device_ref->data;
- if (!device_ctx->internal->hw_type->device_create) {
+ if (!device_ctx->hw_type->device_create) {
ret = AVERROR(ENOSYS);
goto fail;
}
- ret = device_ctx->internal->hw_type->device_create(device_ctx, device,
- opts, flags);
+ ret = device_ctx->hw_type->device_create(&device_ctx->p, device,
+ opts, flags);
if (ret < 0)
goto fail;
@@ -658,13 +639,13 @@ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
AVDictionary *options, int flags)
{
AVBufferRef *dst_ref = NULL, *tmp_ref;
- AVHWDeviceContext *dst_ctx, *tmp_ctx;
+ FFHWDeviceContext *dst_ctx;
int ret = 0;
tmp_ref = src_ref;
while (tmp_ref) {
- tmp_ctx = (AVHWDeviceContext*)tmp_ref->data;
- if (tmp_ctx->type == type) {
+ FFHWDeviceContext *tmp_ctx = (FFHWDeviceContext*)tmp_ref->data;
+ if (tmp_ctx->p.type == type) {
dst_ref = av_buffer_ref(tmp_ref);
if (!dst_ref) {
ret = AVERROR(ENOMEM);
@@ -672,7 +653,7 @@ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
}
goto done;
}
- tmp_ref = tmp_ctx->internal->source_device;
+ tmp_ref = tmp_ctx->source_device;
}
dst_ref = av_hwdevice_ctx_alloc(type);
@@ -680,19 +661,18 @@ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
ret = AVERROR(ENOMEM);
goto fail;
}
- dst_ctx = (AVHWDeviceContext*)dst_ref->data;
+ dst_ctx = (FFHWDeviceContext*)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,
- options,
- flags);
+ FFHWDeviceContext *tmp_ctx = (FFHWDeviceContext*)tmp_ref->data;
+ if (dst_ctx->hw_type->device_derive) {
+ ret = dst_ctx->hw_type->device_derive(&dst_ctx->p,
+ &tmp_ctx->p,
+ options, flags);
if (ret == 0) {
- dst_ctx->internal->source_device = av_buffer_ref(src_ref);
- if (!dst_ctx->internal->source_device) {
+ dst_ctx->source_device = av_buffer_ref(src_ref);
+ if (!dst_ctx->source_device) {
ret = AVERROR(ENOMEM);
goto fail;
}
@@ -704,7 +684,7 @@ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
if (ret != AVERROR(ENOSYS))
goto fail;
}
- tmp_ref = tmp_ctx->internal->source_device;
+ tmp_ref = tmp_ctx->source_device;
}
ret = AVERROR(ENOSYS);
@@ -799,19 +779,18 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
{
AVBufferRef *orig_dst_frames = dst->hw_frames_ctx;
enum AVPixelFormat orig_dst_fmt = dst->format;
- 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;
+ FFHWFramesContext *src_frames = (FFHWFramesContext*)src->hw_frames_ctx->data;
+ FFHWFramesContext *dst_frames = (FFHWFramesContext*)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 ==
+ src->format == dst_frames->p.sw_format &&
+ dst->format == dst_frames->p.format) ||
+ (src_frames->source_frames &&
+ src_frames->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,
@@ -828,12 +807,12 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
}
if (src->hw_frames_ctx) {
- src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data;
+ FFHWFramesContext *src_frames = (FFHWFramesContext*)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 (src_frames->p.format == src->format &&
+ src_frames->hw_type->map_from) {
+ ret = src_frames->hw_type->map_from(&src_frames->p,
+ dst, src, flags);
if (ret >= 0)
return ret;
else if (ret != AVERROR(ENOSYS))
@@ -842,12 +821,12 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
}
if (dst->hw_frames_ctx) {
- dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data;
+ FFHWFramesContext *dst_frames = (FFHWFramesContext*)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 (dst_frames->p.format == dst->format &&
+ dst_frames->hw_type->map_to) {
+ ret = dst_frames->hw_type->map_to(&dst_frames->p,
+ dst, src, flags);
if (ret >= 0)
return ret;
else if (ret != AVERROR(ENOSYS))
@@ -881,21 +860,21 @@ int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
int flags)
{
AVBufferRef *dst_ref = NULL;
- AVHWFramesContext *dst = NULL;
- AVHWFramesContext *src = (AVHWFramesContext*)source_frame_ctx->data;
+ FFHWFramesContext *dsti = NULL;
+ FFHWFramesContext *srci = (FFHWFramesContext*)source_frame_ctx->data;
+ AVHWFramesContext *dst, *src = &srci->p;
int ret;
- if (src->internal->source_frames) {
+ if (srci->source_frames) {
AVHWFramesContext *src_src =
- (AVHWFramesContext*)src->internal->source_frames->data;
+ (AVHWFramesContext*)srci->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);
+ *derived_frame_ctx = av_buffer_ref(srci->source_frames);
if (!*derived_frame_ctx) {
ret = AVERROR(ENOMEM);
goto fail;
@@ -910,31 +889,32 @@ int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
goto fail;
}
- dst = (AVHWFramesContext*)dst_ref->data;
+ dsti = (FFHWFramesContext*)dst_ref->data;
+ dst = &dsti->p;
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) {
+ dsti->source_frames = av_buffer_ref(source_frame_ctx);
+ if (!dsti->source_frames) {
ret = AVERROR(ENOMEM);
goto fail;
}
- dst->internal->source_allocation_map_flags =
+ dsti->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 (srci->hw_type->frames_derive_from)
+ ret = srci->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);
+ dsti->hw_type->frames_derive_to)
+ ret = dsti->hw_type->frames_derive_to(dst, src, flags);
if (ret == AVERROR(ENOSYS))
ret = 0;
if (ret)
@@ -944,8 +924,8 @@ int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
return 0;
fail:
- if (dst)
- av_buffer_unref(&dst->internal->source_frames);
+ if (dsti)
+ av_buffer_unref(&dsti->source_frames);
av_buffer_unref(&dst_ref);
return ret;
}
diff --git a/media/ffvpx/libavutil/hwcontext.h b/media/ffvpx/libavutil/hwcontext.h
index 2b33721a97..bac30debae 100644
--- a/media/ffvpx/libavutil/hwcontext.h
+++ b/media/ffvpx/libavutil/hwcontext.h
@@ -40,8 +40,6 @@ enum AVHWDeviceType {
AV_HWDEVICE_TYPE_D3D12VA,
};
-typedef struct AVHWDeviceInternal AVHWDeviceInternal;
-
/**
* This struct aggregates all the (hardware/vendor-specific) "high-level" state,
* i.e. state that is not tied to a concrete processing configuration.
@@ -66,12 +64,6 @@ typedef struct AVHWDeviceContext {
const AVClass *av_class;
/**
- * Private data used internally by libavutil. Must not be accessed in any
- * way by the caller.
- */
- AVHWDeviceInternal *internal;
-
- /**
* This field identifies the underlying API used for hardware access.
*
* This field is set when this struct is allocated and never changed
@@ -110,8 +102,6 @@ typedef struct AVHWDeviceContext {
void *user_opaque;
} AVHWDeviceContext;
-typedef struct AVHWFramesInternal AVHWFramesInternal;
-
/**
* This struct describes a set or pool of "hardware" frames (i.e. those with
* data not located in normal system memory). All the frames in the pool are
@@ -129,12 +119,6 @@ typedef struct AVHWFramesContext {
const AVClass *av_class;
/**
- * Private data used internally by libavutil. Must not be accessed in any
- * way by the caller.
- */
- AVHWFramesInternal *internal;
-
- /**
* A reference to the parent AVHWDeviceContext. This reference is owned and
* managed by the enclosing AVHWFramesContext, but the caller may derive
* additional references from it.
@@ -153,9 +137,12 @@ typedef struct AVHWFramesContext {
* The format-specific data, allocated and freed automatically along with
* this context.
*
- * Should be cast by the user to the format-specific context defined in the
- * corresponding header (hwframe_*.h) and filled as described in the
- * documentation before calling av_hwframe_ctx_init().
+ * The user shall ignore this field if the corresponding format-specific
+ * header (hwcontext_*.h) does not define a context to be used as
+ * AVHWFramesContext.hwctx.
+ *
+ * Otherwise, it should be cast by the user to said context and filled
+ * as described in the documentation before calling av_hwframe_ctx_init().
*
* After any frames using this context are created, the contents of this
* struct should not be modified by the caller.
diff --git a/media/ffvpx/libavutil/hwcontext_internal.h b/media/ffvpx/libavutil/hwcontext_internal.h
index 4df516ee6a..e32b786238 100644
--- a/media/ffvpx/libavutil/hwcontext_internal.h
+++ b/media/ffvpx/libavutil/hwcontext_internal.h
@@ -41,11 +41,6 @@ typedef struct HWContextType {
* 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.
@@ -58,11 +53,6 @@ typedef struct HWContextType {
* 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);
@@ -100,20 +90,13 @@ typedef struct HWContextType {
AVHWFramesContext *src_ctx, int flags);
} HWContextType;
-struct AVHWDeviceInternal {
- const HWContextType *hw_type;
- void *priv;
-
+typedef struct FFHWFramesContext {
/**
- * For a derived device, a reference to the original device
- * context it was derived from.
+ * The public AVHWFramesContext. See hwcontext.h for it.
*/
- AVBufferRef *source_device;
-};
+ AVHWFramesContext p;
-struct AVHWFramesInternal {
const HWContextType *hw_type;
- void *priv;
AVBufferPool *pool_internal;
@@ -127,7 +110,12 @@ struct AVHWFramesInternal {
* frame context when trying to allocate in the derived context.
*/
int source_allocation_map_flags;
-};
+} FFHWFramesContext;
+
+static inline FFHWFramesContext *ffhwframesctx(AVHWFramesContext *ctx)
+{
+ return (FFHWFramesContext*)ctx;
+}
typedef struct HWMapDescriptor {
/**
diff --git a/media/ffvpx/libavutil/hwcontext_vaapi.c b/media/ffvpx/libavutil/hwcontext_vaapi.c
index 29fc8bd648..56d03aa4cd 100644
--- a/media/ffvpx/libavutil/hwcontext_vaapi.c
+++ b/media/ffvpx/libavutil/hwcontext_vaapi.c
@@ -75,12 +75,22 @@ typedef struct VAAPISurfaceFormat {
} VAAPISurfaceFormat;
typedef struct VAAPIDeviceContext {
+ /**
+ * The public AVVAAPIDeviceContext. See hwcontext_vaapi.h for it.
+ */
+ AVVAAPIDeviceContext p;
+
// Surface formats which can be used with this device.
VAAPISurfaceFormat *formats;
int nb_formats;
} VAAPIDeviceContext;
typedef struct VAAPIFramesContext {
+ /**
+ * The public AVVAAPIFramesContext. See hwcontext_vaapi.h for it.
+ */
+ AVVAAPIFramesContext p;
+
// Surface attributes set at create time.
VASurfaceAttrib *attributes;
int nb_attributes;
@@ -207,7 +217,7 @@ static int vaapi_get_image_format(AVHWDeviceContext *hwdev,
enum AVPixelFormat pix_fmt,
VAImageFormat **image_format)
{
- VAAPIDeviceContext *ctx = hwdev->internal->priv;
+ VAAPIDeviceContext *ctx = hwdev->hwctx;
int i;
for (i = 0; i < ctx->nb_formats; i++) {
@@ -224,9 +234,9 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
const void *hwconfig,
AVHWFramesConstraints *constraints)
{
- AVVAAPIDeviceContext *hwctx = hwdev->hwctx;
+ VAAPIDeviceContext *ctx = hwdev->hwctx;
+ AVVAAPIDeviceContext *hwctx = &ctx->p;
const AVVAAPIHWConfig *config = hwconfig;
- VAAPIDeviceContext *ctx = hwdev->internal->priv;
VASurfaceAttrib *attr_list = NULL;
VAStatus vas;
enum AVPixelFormat pix_fmt;
@@ -384,8 +394,8 @@ static const struct {
static int vaapi_device_init(AVHWDeviceContext *hwdev)
{
- VAAPIDeviceContext *ctx = hwdev->internal->priv;
- AVVAAPIDeviceContext *hwctx = hwdev->hwctx;
+ VAAPIDeviceContext *ctx = hwdev->hwctx;
+ AVVAAPIDeviceContext *hwctx = &ctx->p;
VAImageFormat *image_list = NULL;
VAStatus vas;
const char *vendor_string;
@@ -474,7 +484,7 @@ fail:
static void vaapi_device_uninit(AVHWDeviceContext *hwdev)
{
- VAAPIDeviceContext *ctx = hwdev->internal->priv;
+ VAAPIDeviceContext *ctx = hwdev->hwctx;
av_freep(&ctx->formats);
}
@@ -498,9 +508,9 @@ static void vaapi_buffer_free(void *opaque, uint8_t *data)
static AVBufferRef *vaapi_pool_alloc(void *opaque, size_t size)
{
AVHWFramesContext *hwfc = opaque;
- VAAPIFramesContext *ctx = hwfc->internal->priv;
+ VAAPIFramesContext *ctx = hwfc->hwctx;
+ AVVAAPIFramesContext *avfc = &ctx->p;
AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
- AVVAAPIFramesContext *avfc = hwfc->hwctx;
VASurfaceID surface_id;
VAStatus vas;
AVBufferRef *ref;
@@ -541,8 +551,8 @@ static AVBufferRef *vaapi_pool_alloc(void *opaque, size_t size)
static int vaapi_frames_init(AVHWFramesContext *hwfc)
{
- AVVAAPIFramesContext *avfc = hwfc->hwctx;
- VAAPIFramesContext *ctx = hwfc->internal->priv;
+ VAAPIFramesContext *ctx = hwfc->hwctx;
+ AVVAAPIFramesContext *avfc = &ctx->p;
AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
const VAAPIFormatDescriptor *desc;
VAImageFormat *expected_format;
@@ -623,10 +633,10 @@ static int vaapi_frames_init(AVHWFramesContext *hwfc)
avfc->surface_ids = NULL;
}
- hwfc->internal->pool_internal =
+ ffhwframesctx(hwfc)->pool_internal =
av_buffer_pool_init2(sizeof(VASurfaceID), hwfc,
&vaapi_pool_alloc, NULL);
- if (!hwfc->internal->pool_internal) {
+ if (!ffhwframesctx(hwfc)->pool_internal) {
av_log(hwfc, AV_LOG_ERROR, "Failed to create VAAPI surface pool.\n");
err = AVERROR(ENOMEM);
goto fail;
@@ -644,7 +654,7 @@ static int vaapi_frames_init(AVHWFramesContext *hwfc)
goto fail;
}
} else {
- test_surface = av_buffer_pool_get(hwfc->internal->pool_internal);
+ test_surface = av_buffer_pool_get(ffhwframesctx(hwfc)->pool_internal);
if (!test_surface) {
av_log(hwfc, AV_LOG_ERROR, "Unable to allocate a surface from "
"internal buffer pool.\n");
@@ -693,8 +703,8 @@ fail:
static void vaapi_frames_uninit(AVHWFramesContext *hwfc)
{
- AVVAAPIFramesContext *avfc = hwfc->hwctx;
- VAAPIFramesContext *ctx = hwfc->internal->priv;
+ VAAPIFramesContext *ctx = hwfc->hwctx;
+ AVVAAPIFramesContext *avfc = &ctx->p;
av_freep(&avfc->surface_ids);
av_freep(&ctx->attributes);
@@ -718,7 +728,7 @@ static int vaapi_transfer_get_formats(AVHWFramesContext *hwfc,
enum AVHWFrameTransferDirection dir,
enum AVPixelFormat **formats)
{
- VAAPIDeviceContext *ctx = hwfc->device_ctx->internal->priv;
+ VAAPIDeviceContext *ctx = hwfc->device_ctx->hwctx;
enum AVPixelFormat *pix_fmts;
int i, k, sw_format_available;
@@ -791,7 +801,7 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
AVFrame *dst, const AVFrame *src, int flags)
{
AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
- VAAPIFramesContext *ctx = hwfc->internal->priv;
+ VAAPIFramesContext *ctx = hwfc->hwctx;
VASurfaceID surface_id;
const VAAPIFormatDescriptor *desc;
VAImageFormat *image_format;
@@ -1070,7 +1080,7 @@ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
const AVFrame *src, int flags)
{
#if VA_CHECK_VERSION(1, 1, 0)
- VAAPIFramesContext *src_vafc = src_fc->internal->priv;
+ VAAPIFramesContext *src_vafc = src_fc->hwctx;
int use_prime2;
#else
int k;
@@ -2007,11 +2017,9 @@ const HWContextType ff_hwcontext_type_vaapi = {
.type = AV_HWDEVICE_TYPE_VAAPI,
.name = "VAAPI",
- .device_hwctx_size = sizeof(AVVAAPIDeviceContext),
- .device_priv_size = sizeof(VAAPIDeviceContext),
+ .device_hwctx_size = sizeof(VAAPIDeviceContext),
.device_hwconfig_size = sizeof(AVVAAPIHWConfig),
- .frames_hwctx_size = sizeof(AVVAAPIFramesContext),
- .frames_priv_size = sizeof(VAAPIFramesContext),
+ .frames_hwctx_size = sizeof(VAAPIFramesContext),
.device_create = &vaapi_device_create,
.device_derive = &vaapi_device_derive,
diff --git a/media/ffvpx/libavutil/imgutils.c b/media/ffvpx/libavutil/imgutils.c
index 1e15f7c920..d246381563 100644
--- a/media/ffvpx/libavutil/imgutils.c
+++ b/media/ffvpx/libavutil/imgutils.c
@@ -25,10 +25,10 @@
#include "common.h"
#include "imgutils.h"
#include "imgutils_internal.h"
-#include "internal.h"
#include "intreadwrite.h"
#include "log.h"
#include "mathematics.h"
+#include "mem.h"
#include "pixdesc.h"
#include "rational.h"
diff --git a/media/ffvpx/libavutil/imgutils_internal.h b/media/ffvpx/libavutil/imgutils_internal.h
index d515858413..3e47731a50 100644
--- a/media/ffvpx/libavutil/imgutils_internal.h
+++ b/media/ffvpx/libavutil/imgutils_internal.h
@@ -22,6 +22,10 @@
#include <stddef.h>
#include <stdint.h>
+#include "pixfmt.h"
+
+int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
+
int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize,
const uint8_t *src, ptrdiff_t src_linesize,
ptrdiff_t bytewidth, int height);
diff --git a/media/ffvpx/libavutil/internal.h b/media/ffvpx/libavutil/internal.h
index 461c0df9ad..ac1af367e9 100644
--- a/media/ffvpx/libavutil/internal.h
+++ b/media/ffvpx/libavutil/internal.h
@@ -40,8 +40,8 @@
#include <stdio.h>
#include "config.h"
#include "attributes.h"
+#include "libm.h"
#include "macros.h"
-#include "pixfmt.h"
#ifndef attribute_align_arg
#if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
@@ -74,16 +74,6 @@
#endif
-#define FF_MEMORY_POISON 0x2a
-
-/* Check if the hard coded offset of a struct member still matches reality.
- * Induce a compilation failure if not.
- */
-#define AV_CHECK_OFFSET(s, m, o) struct check_##o { \
- int x_##o[offsetof(s, m) == o? 1: -1]; \
- }
-
-
#define FF_ALLOC_TYPED_ARRAY(p, nelem) (p = av_malloc_array(nelem, sizeof(*p)))
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem) (p = av_calloc(nelem, sizeof(*p)))
@@ -94,8 +84,6 @@
*/
#define FF_FIELD_AT(type, off, obj) (*(type *)((char *)&(obj) + (off)))
-#include "libm.h"
-
/**
* Return NULL if CONFIG_SMALL is true, otherwise the argument
* without modification. Used to disable the definition of strings.
@@ -163,8 +151,6 @@ void avpriv_request_sample(void *avc,
#define SUINT32 uint32_t
#endif
-int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
-
static av_always_inline av_const int avpriv_mirror(int x, int w)
{
if (!w)
diff --git a/media/ffvpx/libavutil/intreadwrite.h b/media/ffvpx/libavutil/intreadwrite.h
index 21df7887f3..d0a5773b54 100644
--- a/media/ffvpx/libavutil/intreadwrite.h
+++ b/media/ffvpx/libavutil/intreadwrite.h
@@ -583,9 +583,7 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
#endif
/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be
- * naturally aligned. They may be implemented using MMX,
- * so emms_c() must be called before using any float code
- * afterwards.
+ * naturally aligned.
*/
#define AV_COPY(n, d, s) \
diff --git a/media/ffvpx/libavutil/mem.c b/media/ffvpx/libavutil/mem.c
index 36b8940a0c..b205d3fb25 100644
--- a/media/ffvpx/libavutil/mem.c
+++ b/media/ffvpx/libavutil/mem.c
@@ -62,14 +62,16 @@ void free(void *ptr);
#endif /* MALLOC_PREFIX */
-#define ALIGN (HAVE_AVX512 ? 64 : (HAVE_AVX ? 32 : 16))
+#define ALIGN (HAVE_SIMD_ALIGN_64 ? 64 : (HAVE_SIMD_ALIGN_32 ? 32 : 16))
+
+#define FF_MEMORY_POISON 0x2a
/* NOTE: if you want to override these functions with your own
* implementations (not recommended) you have to link libav* as
* dynamic libraries and remove -Wl,-Bsymbolic from the linker flags.
* Note that this will cost performance. */
-static atomic_size_t max_alloc_size = ATOMIC_VAR_INIT(INT_MAX);
+static atomic_size_t max_alloc_size = INT_MAX;
void av_max_alloc(size_t max){
atomic_store_explicit(&max_alloc_size, max, memory_order_relaxed);
diff --git a/media/ffvpx/libavutil/mem.h b/media/ffvpx/libavutil/mem.h
index be697408a2..ab7648ac57 100644
--- a/media/ffvpx/libavutil/mem.h
+++ b/media/ffvpx/libavutil/mem.h
@@ -116,7 +116,7 @@
* be allocated
* @see av_mallocz()
*/
-void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1) __attribute__((visibility("default")));
+void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1);
/**
* Allocate a memory block with alignment suitable for all memory accesses
diff --git a/media/ffvpx/libavutil/mem_internal.h b/media/ffvpx/libavutil/mem_internal.h
index 2448c606f1..20f9b3e3f2 100644
--- a/media/ffvpx/libavutil/mem_internal.h
+++ b/media/ffvpx/libavutil/mem_internal.h
@@ -27,8 +27,6 @@
#include "attributes.h"
#include "macros.h"
-#include "mem.h"
-#include "version.h"
/**
* @def DECLARE_ALIGNED(n,t,v)
@@ -76,27 +74,50 @@
*/
#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C)
- #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
+ #define DECLARE_ALIGNED_T(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(__DJGPP__)
- #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v
+ #define DECLARE_ALIGNED_T(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_ALIGNED_T(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_ALIGNED_T(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_ALIGNED_T(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
+#if HAVE_SIMD_ALIGN_64
+ #define ALIGN_64 64
+ #define ALIGN_32 32
+#elif HAVE_SIMD_ALIGN_32
+ #define ALIGN_64 32
+ #define ALIGN_32 32
+#else
+ #define ALIGN_64 16
+ #define ALIGN_32 16
+#endif
+
+#define DECLARE_ALIGNED(n,t,v) DECLARE_ALIGNED_V(n,t,v)
+
+// Macro needs to be double-wrapped in order to expand
+// possible other macros being passed for n.
+#define DECLARE_ALIGNED_V(n,t,v) DECLARE_ALIGNED_##n(t,v)
+
+#define DECLARE_ALIGNED_4(t,v) DECLARE_ALIGNED_T( 4, t, v)
+#define DECLARE_ALIGNED_8(t,v) DECLARE_ALIGNED_T( 8, t, v)
+#define DECLARE_ALIGNED_16(t,v) DECLARE_ALIGNED_T( 16, t, v)
+#define DECLARE_ALIGNED_32(t,v) DECLARE_ALIGNED_T(ALIGN_32, t, v)
+#define DECLARE_ALIGNED_64(t,v) DECLARE_ALIGNED_T(ALIGN_64, t, v)
+
// Some broken preprocessors need a second expansion
// to be forced to tokenize __VA_ARGS__
#define E1(x) x
diff --git a/media/ffvpx/libavutil/moz.build b/media/ffvpx/libavutil/moz.build
index 4839375c10..c3b3a21fbe 100644
--- a/media/ffvpx/libavutil/moz.build
+++ b/media/ffvpx/libavutil/moz.build
@@ -35,6 +35,7 @@ SOURCES += [
'imgutils.c',
'log.c',
'log2_tab.c',
+ 'mastering_display_metadata.c',
'mathematics.c',
'mem.c',
'opt.c',
@@ -56,13 +57,11 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
SOURCES += [
'adler32.c',
'base64.c',
- 'color_utils.c',
'film_grain_params.c',
'hdr_dynamic_metadata.c',
'integer.c',
'intmath.c',
'lls.c',
- 'mastering_display_metadata.c',
'pixelutils.c',
'threadmessage.c',
'timecode.c',
@@ -79,6 +78,11 @@ EXPORTS.ffvpx = [
"tx.h"
]
+c11_flags = ["-std=gnu11"]
+if CONFIG["CC_TYPE"] == "clang-cl":
+ c11_flags.insert(0, "-Xclang")
+CFLAGS += c11_flags
+
SYMBOLS_FILE = 'avutil.symbols'
NoVisibilityFlags()
diff --git a/media/ffvpx/libavutil/opt.c b/media/ffvpx/libavutil/opt.c
index 0908751752..d11e9d2ac5 100644
--- a/media/ffvpx/libavutil/opt.c
+++ b/media/ffvpx/libavutil/opt.c
@@ -29,10 +29,10 @@
#include "avassert.h"
#include "avstring.h"
#include "channel_layout.h"
-#include "common.h"
#include "dict.h"
#include "eval.h"
#include "log.h"
+#include "mem.h"
#include "parseutils.h"
#include "pixdesc.h"
#include "mathematics.h"
@@ -43,6 +43,8 @@
#include <float.h>
+#define TYPE_BASE(type) ((type) & ~AV_OPT_TYPE_FLAG_ARRAY)
+
const AVOption *av_opt_next(const void *obj, const AVOption *last)
{
const AVClass *class;
@@ -56,6 +58,98 @@ const AVOption *av_opt_next(const void *obj, const AVOption *last)
return NULL;
}
+static const size_t opt_elem_size[] = {
+ [AV_OPT_TYPE_FLAGS] = sizeof(unsigned),
+ [AV_OPT_TYPE_INT] = sizeof(int),
+ [AV_OPT_TYPE_INT64] = sizeof(int64_t),
+ [AV_OPT_TYPE_UINT64] = sizeof(uint64_t),
+ [AV_OPT_TYPE_DOUBLE] = sizeof(double),
+ [AV_OPT_TYPE_FLOAT] = sizeof(float),
+ [AV_OPT_TYPE_STRING] = sizeof(char *),
+ [AV_OPT_TYPE_RATIONAL] = sizeof(AVRational),
+ [AV_OPT_TYPE_BINARY] = sizeof(uint8_t *),
+ [AV_OPT_TYPE_DICT] = sizeof(AVDictionary *),
+ [AV_OPT_TYPE_IMAGE_SIZE] = sizeof(int[2]),
+ [AV_OPT_TYPE_VIDEO_RATE] = sizeof(AVRational),
+ [AV_OPT_TYPE_PIXEL_FMT] = sizeof(int),
+ [AV_OPT_TYPE_SAMPLE_FMT] = sizeof(int),
+ [AV_OPT_TYPE_DURATION] = sizeof(int64_t),
+ [AV_OPT_TYPE_COLOR] = sizeof(uint8_t[4]),
+ [AV_OPT_TYPE_CHLAYOUT] = sizeof(AVChannelLayout),
+ [AV_OPT_TYPE_BOOL] = sizeof(int),
+};
+
+// option is plain old data
+static int opt_is_pod(enum AVOptionType type)
+{
+ switch (type) {
+ case AV_OPT_TYPE_FLAGS:
+ case AV_OPT_TYPE_INT:
+ case AV_OPT_TYPE_INT64:
+ case AV_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_FLOAT:
+ case AV_OPT_TYPE_RATIONAL:
+ case AV_OPT_TYPE_UINT64:
+ case AV_OPT_TYPE_IMAGE_SIZE:
+ case AV_OPT_TYPE_PIXEL_FMT:
+ case AV_OPT_TYPE_SAMPLE_FMT:
+ case AV_OPT_TYPE_VIDEO_RATE:
+ case AV_OPT_TYPE_DURATION:
+ case AV_OPT_TYPE_COLOR:
+ case AV_OPT_TYPE_BOOL:
+ return 1;
+ }
+ return 0;
+}
+
+static uint8_t opt_array_sep(const AVOption *o)
+{
+ const AVOptionArrayDef *d = o->default_val.arr;
+ av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY);
+ return (d && d->sep) ? d->sep : ',';
+}
+
+static void *opt_array_pelem(const AVOption *o, void *array, unsigned idx)
+{
+ av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY);
+ return (uint8_t *)array + idx * opt_elem_size[TYPE_BASE(o->type)];
+}
+
+static unsigned *opt_array_pcount(const void *parray)
+{
+ return (unsigned *)((const void * const *)parray + 1);
+}
+
+static void opt_free_elem(const AVOption *o, void *ptr)
+{
+ switch (TYPE_BASE(o->type)) {
+ case AV_OPT_TYPE_STRING:
+ case AV_OPT_TYPE_BINARY:
+ av_freep(ptr);
+ break;
+
+ case AV_OPT_TYPE_DICT:
+ av_dict_free((AVDictionary **)ptr);
+ break;
+
+ case AV_OPT_TYPE_CHLAYOUT:
+ av_channel_layout_uninit((AVChannelLayout *)ptr);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void opt_free_array(const AVOption *o, void *parray, unsigned *count)
+{
+ for (unsigned i = 0; i < *count; i++)
+ opt_free_elem(o, opt_array_pelem(o, *(void **)parray, i));
+
+ av_freep(parray);
+ *count = 0;
+}
+
static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
{
switch (o->type) {
@@ -72,11 +166,6 @@ static int read_number(const AVOption *o, const void *dst, double *num, int *den
case AV_OPT_TYPE_INT:
*intnum = *(int *)dst;
return 0;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_UINT64:
@@ -93,7 +182,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
*den = ((AVRational *)dst)->den;
return 0;
case AV_OPT_TYPE_CONST:
- *num = o->default_val.dbl;
+ *intnum = o->default_val.i64;
return 0;
}
return AVERROR(EINVAL);
@@ -101,14 +190,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
{
- if (o->type != AV_OPT_TYPE_FLAGS &&
+ const enum AVOptionType type = TYPE_BASE(o->type);
+
+ if (type != AV_OPT_TYPE_FLAGS &&
(!den || o->max * den < num * intnum || o->min * den > num * intnum)) {
num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN);
av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
num, o->name, o->min, o->max);
return AVERROR(ERANGE);
}
- if (o->type == AV_OPT_TYPE_FLAGS) {
+ if (type == AV_OPT_TYPE_FLAGS) {
double d = num*intnum/den;
if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
av_log(obj, AV_LOG_ERROR,
@@ -118,7 +209,7 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int
}
}
- switch (o->type) {
+ switch (type) {
case AV_OPT_TYPE_PIXEL_FMT:
*(enum AVPixelFormat *)dst = llrint(num / den) * intnum;
break;
@@ -131,11 +222,6 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int
*(int *)dst = llrint(num / den) * intnum;
break;
case AV_OPT_TYPE_DURATION:
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
case AV_OPT_TYPE_INT64:{
double d = num / den;
if (intnum == 1 && d == (double)INT64_MAX) {
@@ -223,6 +309,8 @@ static int set_string_binary(void *obj, const AVOption *o, const char *val, uint
static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
{
av_freep(dst);
+ if (!val)
+ return 0;
*dst = av_strdup(val);
return *dst ? 0 : AVERROR(ENOMEM);
}
@@ -237,9 +325,10 @@ static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **d
static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
{
+ const enum AVOptionType type = TYPE_BASE(o->type);
int ret = 0;
- if (o->type == AV_OPT_TYPE_RATIONAL || o->type == AV_OPT_TYPE_VIDEO_RATE) {
+ if (type == AV_OPT_TYPE_RATIONAL || type == AV_OPT_TYPE_VIDEO_RATE) {
int num, den;
char c;
if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
@@ -256,7 +345,7 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
double d;
int64_t intnum = 1;
- if (o->type == AV_OPT_TYPE_FLAGS) {
+ if (type == AV_OPT_TYPE_FLAGS) {
if (*val == '+' || *val == '-')
cmd = *(val++);
for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
@@ -312,8 +401,8 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
}
}
}
- if (o->type == AV_OPT_TYPE_FLAGS) {
- read_number(o, dst, NULL, NULL, &intnum);
+ if (type == AV_OPT_TYPE_FLAGS) {
+ intnum = *(unsigned int*)dst;
if (cmd == '+')
d = intnum | (int64_t)d;
else if (cmd == '-')
@@ -444,16 +533,26 @@ static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t
return 0;
}
+static int get_pix_fmt(const char *name)
+{
+ return av_get_pix_fmt(name);
+}
+
static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
{
return set_string_fmt(obj, o, val, dst,
- AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format");
+ AV_PIX_FMT_NB, get_pix_fmt, "pixel format");
+}
+
+static int get_sample_fmt(const char *name)
+{
+ return av_get_sample_fmt(name);
}
static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
{
return set_string_fmt(obj, o, val, dst,
- AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format");
+ AV_SAMPLE_FMT_NB, get_sample_fmt, "sample format");
}
static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst)
@@ -484,33 +583,20 @@ static int set_string_channel_layout(void *obj, const AVOption *o,
return av_channel_layout_from_string(channel_layout, val);
}
-int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
+static int opt_set_elem(void *obj, void *target_obj, const AVOption *o,
+ const char *val, void *dst)
{
- int ret = 0;
- void *dst, *target_obj;
- const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
- if (!o || !target_obj)
- return AVERROR_OPTION_NOT_FOUND;
-FF_DISABLE_DEPRECATION_WARNINGS
- if (!val && (o->type != AV_OPT_TYPE_STRING &&
- o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
- o->type != AV_OPT_TYPE_IMAGE_SIZE &&
- o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
-#if FF_API_OLD_CHANNEL_LAYOUT
- o->type != AV_OPT_TYPE_CHANNEL_LAYOUT &&
-#endif
- o->type != AV_OPT_TYPE_BOOL))
- return AVERROR(EINVAL);
-FF_ENABLE_DEPRECATION_WARNINGS
+ const enum AVOptionType type = TYPE_BASE(o->type);
+ int ret;
- if (o->flags & AV_OPT_FLAG_READONLY)
+ if (!val && (type != AV_OPT_TYPE_STRING &&
+ type != AV_OPT_TYPE_PIXEL_FMT && type != AV_OPT_TYPE_SAMPLE_FMT &&
+ type != AV_OPT_TYPE_IMAGE_SIZE &&
+ type != AV_OPT_TYPE_DURATION && type != AV_OPT_TYPE_COLOR &&
+ type != AV_OPT_TYPE_BOOL))
return AVERROR(EINVAL);
- if (o->flags & AV_OPT_FLAG_DEPRECATED)
- av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
-
- dst = ((uint8_t *)target_obj) + o->offset;
- switch (o->type) {
+ switch (type) {
case AV_OPT_TYPE_BOOL:
return set_string_bool(obj, o, val, dst);
case AV_OPT_TYPE_STRING:
@@ -557,23 +643,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
case AV_OPT_TYPE_COLOR:
return set_string_color(obj, o, val, dst);
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
- if (!val || !strcmp(val, "none")) {
- *(int64_t *)dst = 0;
- } else {
- int64_t cl = av_get_channel_layout(val);
- if (!cl) {
- av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
- ret = AVERROR(EINVAL);
- }
- *(int64_t *)dst = cl;
- return ret;
- }
- break;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
case AV_OPT_TYPE_CHLAYOUT:
ret = set_string_channel_layout(obj, o, val, dst);
if (ret < 0) {
@@ -589,6 +658,104 @@ FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR(EINVAL);
}
+static int opt_set_array(void *obj, void *target_obj, const AVOption *o,
+ const char *val, void *dst)
+{
+ const AVOptionArrayDef *arr = o->default_val.arr;
+ const size_t elem_size = opt_elem_size[TYPE_BASE(o->type)];
+ const uint8_t sep = opt_array_sep(o);
+ uint8_t *str = NULL;
+
+ void *elems = NULL;
+ unsigned nb_elems = 0;
+ int ret;
+
+ if (val && *val) {
+ str = av_malloc(strlen(val) + 1);
+ if (!str)
+ return AVERROR(ENOMEM);
+ }
+
+ // split and unescape the string
+ while (val && *val) {
+ uint8_t *p = str;
+ void *tmp;
+
+ if (arr && arr->size_max && nb_elems >= arr->size_max) {
+ av_log(obj, AV_LOG_ERROR,
+ "Cannot assign more than %u elements to array option %s\n",
+ arr->size_max, o->name);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ for (; *val; val++, p++) {
+ if (*val == '\\' && val[1])
+ val++;
+ else if (*val == sep) {
+ val++;
+ break;
+ }
+ *p = *val;
+ }
+ *p = 0;
+
+ tmp = av_realloc_array(elems, nb_elems + 1, elem_size);
+ if (!tmp) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ elems = tmp;
+
+ tmp = opt_array_pelem(o, elems, nb_elems);
+ memset(tmp, 0, elem_size);
+
+ ret = opt_set_elem(obj, target_obj, o, str, tmp);
+ if (ret < 0)
+ goto fail;
+ nb_elems++;
+ }
+ av_freep(&str);
+
+ opt_free_array(o, dst, opt_array_pcount(dst));
+
+ if (arr && nb_elems < arr->size_min) {
+ av_log(obj, AV_LOG_ERROR,
+ "Cannot assign fewer than %u elements to array option %s\n",
+ arr->size_min, o->name);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ *((void **)dst) = elems;
+ *opt_array_pcount(dst) = nb_elems;
+
+ return 0;
+fail:
+ av_freep(&str);
+ opt_free_array(o, &elems, &nb_elems);
+ return ret;
+}
+
+int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
+{
+ void *dst, *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ if (!o || !target_obj)
+ return AVERROR_OPTION_NOT_FOUND;
+
+ if (o->flags & AV_OPT_FLAG_READONLY)
+ return AVERROR(EINVAL);
+
+ if (o->flags & AV_OPT_FLAG_DEPRECATED)
+ av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
+
+ dst = ((uint8_t *)target_obj) + o->offset;
+
+ return ((o->type & AV_OPT_TYPE_FLAG_ARRAY) ?
+ opt_set_array : opt_set_elem)(obj, target_obj, o, val, dst);
+}
+
#define OPT_EVAL_NUMBER(name, opttype, vartype) \
int av_opt_eval_ ## name(void *obj, const AVOption *o, \
const char *val, vartype *name ## _out) \
@@ -614,7 +781,7 @@ static int set_number(void *obj, const char *name, double num, int den, int64_t
if (!o || !target_obj)
return AVERROR_OPTION_NOT_FOUND;
- if (o->flags & AV_OPT_FLAG_READONLY)
+ if ((o->flags & AV_OPT_FLAG_READONLY) || (o->type & AV_OPT_TYPE_FLAG_ARRAY))
return AVERROR(EINVAL);
dst = ((uint8_t *)target_obj) + o->offset;
@@ -697,7 +864,8 @@ int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int searc
return AVERROR_OPTION_NOT_FOUND;
if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
av_log(obj, AV_LOG_ERROR,
- "The value set by option '%s' is not a video rate.\n", o->name);
+ "The value set by option '%s' is not a video rate.\n",
+ o->name);
return AVERROR(EINVAL);
}
if (val.num <= 0 || val.den <= 0)
@@ -744,26 +912,6 @@ int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt,
return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
}
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
-int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
-{
- void *target_obj;
- const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-
- if (!o || !target_obj)
- return AVERROR_OPTION_NOT_FOUND;
- if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
- av_log(obj, AV_LOG_ERROR,
- "The value set by option '%s' is not a channel layout.\n", o->name);
- return AVERROR(EINVAL);
- }
- *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl;
- return 0;
-}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val,
int search_flags)
{
@@ -834,145 +982,224 @@ static void format_duration(char *buf, size_t size, int64_t d)
*(--e) = 0;
}
-int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
+static int opt_get_elem(const AVOption *o, uint8_t **pbuf, size_t buf_len,
+ void *dst, int search_flags)
{
- void *dst, *target_obj;
- const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
- uint8_t *bin, buf[128];
- int len, i, ret;
- int64_t i64;
-
- if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
- return AVERROR_OPTION_NOT_FOUND;
-
- if (o->flags & AV_OPT_FLAG_DEPRECATED)
- av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
-
- dst = (uint8_t *)target_obj + o->offset;
+ int ret;
- buf[0] = 0;
- switch (o->type) {
+ switch (TYPE_BASE(o->type)) {
case AV_OPT_TYPE_BOOL:
- ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid"));
+ ret = snprintf(*pbuf, buf_len, "%s", get_bool_name(*(int *)dst));
break;
case AV_OPT_TYPE_FLAGS:
- ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);
+ ret = snprintf(*pbuf, buf_len, "0x%08X", *(int *)dst);
break;
case AV_OPT_TYPE_INT:
- ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst);
+ ret = snprintf(*pbuf, buf_len, "%d", *(int *)dst);
break;
case AV_OPT_TYPE_INT64:
- ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst);
+ ret = snprintf(*pbuf, buf_len, "%"PRId64, *(int64_t *)dst);
break;
case AV_OPT_TYPE_UINT64:
- ret = snprintf(buf, sizeof(buf), "%"PRIu64, *(uint64_t *)dst);
+ ret = snprintf(*pbuf, buf_len, "%"PRIu64, *(uint64_t *)dst);
break;
case AV_OPT_TYPE_FLOAT:
- ret = snprintf(buf, sizeof(buf), "%f", *(float *)dst);
+ ret = snprintf(*pbuf, buf_len, "%f", *(float *)dst);
break;
case AV_OPT_TYPE_DOUBLE:
- ret = snprintf(buf, sizeof(buf), "%f", *(double *)dst);
+ ret = snprintf(*pbuf, buf_len, "%f", *(double *)dst);
break;
case AV_OPT_TYPE_VIDEO_RATE:
case AV_OPT_TYPE_RATIONAL:
- ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den);
+ ret = snprintf(*pbuf, buf_len, "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den);
break;
case AV_OPT_TYPE_CONST:
- ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl);
+ ret = snprintf(*pbuf, buf_len, "%"PRId64, o->default_val.i64);
break;
case AV_OPT_TYPE_STRING:
if (*(uint8_t **)dst) {
- *out_val = av_strdup(*(uint8_t **)dst);
+ *pbuf = av_strdup(*(uint8_t **)dst);
} else if (search_flags & AV_OPT_ALLOW_NULL) {
- *out_val = NULL;
+ *pbuf = NULL;
return 0;
} else {
- *out_val = av_strdup("");
+ *pbuf = av_strdup("");
}
- return *out_val ? 0 : AVERROR(ENOMEM);
- case AV_OPT_TYPE_BINARY:
+ return *pbuf ? 0 : AVERROR(ENOMEM);
+ case AV_OPT_TYPE_BINARY: {
+ const uint8_t *bin;
+ int len;
+
if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
- *out_val = NULL;
+ *pbuf = NULL;
return 0;
}
len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *));
if ((uint64_t)len * 2 + 1 > INT_MAX)
return AVERROR(EINVAL);
- if (!(*out_val = av_malloc(len * 2 + 1)))
+ if (!(*pbuf = av_malloc(len * 2 + 1)))
return AVERROR(ENOMEM);
if (!len) {
- *out_val[0] = '\0';
+ *pbuf[0] = '\0';
return 0;
}
bin = *(uint8_t **)dst;
- for (i = 0; i < len; i++)
- snprintf(*out_val + i * 2, 3, "%02X", bin[i]);
+ for (int i = 0; i < len; i++)
+ snprintf(*pbuf + i * 2, 3, "%02X", bin[i]);
return 0;
+ }
case AV_OPT_TYPE_IMAGE_SIZE:
- ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
+ ret = snprintf(*pbuf, buf_len, "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
break;
case AV_OPT_TYPE_PIXEL_FMT:
- ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
+ ret = snprintf(*pbuf, buf_len, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
break;
case AV_OPT_TYPE_SAMPLE_FMT:
- ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
+ ret = snprintf(*pbuf, buf_len, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
break;
- case AV_OPT_TYPE_DURATION:
- i64 = *(int64_t *)dst;
- format_duration(buf, sizeof(buf), i64);
- ret = strlen(buf); // no overflow possible, checked by an assert
+ case AV_OPT_TYPE_DURATION: {
+ int64_t i64 = *(int64_t *)dst;
+ format_duration(*pbuf, buf_len, i64);
+ ret = strlen(*pbuf); // no overflow possible, checked by an assert
break;
+ }
case AV_OPT_TYPE_COLOR:
- ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x",
+ ret = snprintf(*pbuf, buf_len, "0x%02x%02x%02x%02x",
(int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
(int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
break;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
-
- i64 = *(int64_t *)dst;
- ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
- break;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
case AV_OPT_TYPE_CHLAYOUT:
- ret = av_channel_layout_describe(dst, buf, sizeof(buf));
+ ret = av_channel_layout_describe(dst, *pbuf, buf_len);
break;
case AV_OPT_TYPE_DICT:
if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
- *out_val = NULL;
+ *pbuf = NULL;
return 0;
}
- return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, '=', ':');
+ return av_dict_get_string(*(AVDictionary **)dst, (char **)pbuf, '=', ':');
default:
return AVERROR(EINVAL);
}
+ return ret;
+}
+
+static int opt_get_array(const AVOption *o, void *dst, uint8_t **out_val)
+{
+ const unsigned count = *opt_array_pcount(dst);
+ const uint8_t sep = opt_array_sep(o);
+
+ uint8_t *str = NULL;
+ size_t str_len = 0;
+ int ret;
+
+ *out_val = NULL;
+
+ for (unsigned i = 0; i < count; i++) {
+ uint8_t buf[128], *out = buf;
+ size_t out_len;
+
+ ret = opt_get_elem(o, &out, sizeof(buf),
+ opt_array_pelem(o, *(void **)dst, i), 0);
+ if (ret < 0)
+ goto fail;
+
+ out_len = strlen(out);
+ if (out_len > SIZE_MAX / 2 - !!i ||
+ !!i + out_len * 2 > SIZE_MAX - str_len - 1) {
+ ret = AVERROR(ERANGE);
+ goto fail;
+ }
+
+ // terminator escaping separator
+ // ↓ ↓ ↓
+ ret = av_reallocp(&str, str_len + 1 + out_len * 2 + !!i);
+ if (ret < 0)
+ goto fail;
+
+ // add separator if needed
+ if (i)
+ str[str_len++] = sep;
+
+ // escape the element
+ for (unsigned j = 0; j < out_len; j++) {
+ uint8_t val = out[j];
+ if (val == sep || val == '\\')
+ str[str_len++] = '\\';
+ str[str_len++] = val;
+ }
+ str[str_len] = 0;
+
+fail:
+ if (out != buf)
+ av_freep(&out);
+ if (ret < 0) {
+ av_freep(&str);
+ return ret;
+ }
+ }
+
+ *out_val = str;
+
+ return 0;
+}
+
+int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
+{
+ void *dst, *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ uint8_t *out, buf[128];
+ int ret;
+
+ if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
+ return AVERROR_OPTION_NOT_FOUND;
+
+ if (o->flags & AV_OPT_FLAG_DEPRECATED)
+ av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
+
+ dst = (uint8_t *)target_obj + o->offset;
+
+ if (o->type & AV_OPT_TYPE_FLAG_ARRAY) {
+ ret = opt_get_array(o, dst, out_val);
+ if (ret < 0)
+ return ret;
+ if (!*out_val && !(search_flags & AV_OPT_ALLOW_NULL)) {
+ *out_val = av_strdup("");
+ if (!*out_val)
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+ }
+
+ buf[0] = 0;
+ out = buf;
+ ret = opt_get_elem(o, &out, sizeof(buf), dst, search_flags);
+ if (ret < 0)
+ return ret;
+ if (out != buf) {
+ *out_val = out;
+ return 0;
+ }
+
if (ret >= sizeof(buf))
return AVERROR(EINVAL);
- *out_val = av_strdup(buf);
+ *out_val = av_strdup(out);
return *out_val ? 0 : AVERROR(ENOMEM);
}
-static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
+static int get_number(void *obj, const char *name, double *num, int *den, int64_t *intnum,
int search_flags)
{
void *dst, *target_obj;
const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
if (!o || !target_obj)
- goto error;
+ return AVERROR_OPTION_NOT_FOUND;
+ if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
+ return AVERROR(EINVAL);
dst = ((uint8_t *)target_obj) + o->offset;
- if (o_out) *o_out= o;
-
return read_number(o, dst, num, den, intnum);
-
-error:
- *den =
- *intnum = 0;
- return -1;
}
int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
@@ -981,7 +1208,7 @@ int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_v
double num = 1;
int ret, den = 1;
- if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+ if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
return ret;
if (num == den)
*out_val = intnum;
@@ -996,7 +1223,7 @@ int av_opt_get_double(void *obj, const char *name, int search_flags, double *out
double num = 1;
int ret, den = 1;
- if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+ if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
return ret;
*out_val = num * intnum / den;
return 0;
@@ -1008,7 +1235,7 @@ int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_
double num = 1;
int ret, den = 1;
- if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+ if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
return ret;
if (num == 1.0 && (int)intnum == intnum)
@@ -1026,7 +1253,7 @@ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_
return AVERROR_OPTION_NOT_FOUND;
if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
av_log(obj, AV_LOG_ERROR,
- "The value for option '%s' is not an image size.\n", name);
+ "The value for option '%s' is not a image size.\n", name);
return AVERROR(EINVAL);
}
@@ -1042,7 +1269,7 @@ int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRatio
double num = 1;
int ret, den = 1;
- if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+ if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
return ret;
if (num == 1.0 && (int)intnum == intnum)
@@ -1080,27 +1307,6 @@ int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AV
return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
}
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
-int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
-{
- void *dst, *target_obj;
- const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
- if (!o || !target_obj)
- return AVERROR_OPTION_NOT_FOUND;
- if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
- av_log(obj, AV_LOG_ERROR,
- "The value for option '%s' is not a channel layout.\n", name);
- return AVERROR(EINVAL);
- }
-
- dst = ((uint8_t*)target_obj) + o->offset;
- *cl = *(int64_t *)dst;
- return 0;
-}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *cl)
{
void *dst, *target_obj;
@@ -1231,6 +1437,120 @@ static char *get_opt_flags_string(void *obj, const char *unit, int64_t value)
return NULL;
}
+static void log_type(void *av_log_obj, const AVOption *o,
+ enum AVOptionType parent_type)
+{
+ const char *desc[] = {
+ [AV_OPT_TYPE_FLAGS] = "<flags>",
+ [AV_OPT_TYPE_INT] = "<int>",
+ [AV_OPT_TYPE_INT64] = "<int64>",
+ [AV_OPT_TYPE_UINT64] = "<uint64>",
+ [AV_OPT_TYPE_DOUBLE] = "<double>",
+ [AV_OPT_TYPE_FLOAT] = "<float>",
+ [AV_OPT_TYPE_STRING] = "<string>",
+ [AV_OPT_TYPE_RATIONAL] = "<rational>",
+ [AV_OPT_TYPE_BINARY] = "<binary>",
+ [AV_OPT_TYPE_DICT] = "<dictionary>",
+ [AV_OPT_TYPE_IMAGE_SIZE] = "<image_size>",
+ [AV_OPT_TYPE_VIDEO_RATE] = "<video_rate>",
+ [AV_OPT_TYPE_PIXEL_FMT] = "<pix_fmt>",
+ [AV_OPT_TYPE_SAMPLE_FMT] = "<sample_fmt>",
+ [AV_OPT_TYPE_DURATION] = "<duration>",
+ [AV_OPT_TYPE_COLOR] = "<color>",
+ [AV_OPT_TYPE_CHLAYOUT] = "<channel_layout>",
+ [AV_OPT_TYPE_BOOL] = "<boolean>",
+ };
+ const enum AVOptionType type = TYPE_BASE(o->type);
+
+ if (o->type == AV_OPT_TYPE_CONST && TYPE_BASE(parent_type) == AV_OPT_TYPE_INT)
+ av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", o->default_val.i64);
+ else if (type < FF_ARRAY_ELEMS(desc) && desc[type]) {
+ if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
+ av_log(av_log_obj, AV_LOG_INFO, "[%-10s]", desc[type]);
+ else
+ av_log(av_log_obj, AV_LOG_INFO, "%-12s ", desc[type]);
+ }
+ else
+ av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
+}
+
+static void log_default(void *obj, void *av_log_obj, const AVOption *opt)
+{
+ if (opt->type == AV_OPT_TYPE_CONST || opt->type == AV_OPT_TYPE_BINARY)
+ return;
+ if ((opt->type == AV_OPT_TYPE_COLOR ||
+ opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
+ opt->type == AV_OPT_TYPE_STRING ||
+ opt->type == AV_OPT_TYPE_DICT ||
+ opt->type == AV_OPT_TYPE_CHLAYOUT ||
+ opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
+ !opt->default_val.str)
+ return;
+
+ if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) {
+ const AVOptionArrayDef *arr = opt->default_val.arr;
+ if (arr && arr->def)
+ av_log(av_log_obj, AV_LOG_INFO, " (default %s)", arr->def);
+ return;
+ }
+
+ av_log(av_log_obj, AV_LOG_INFO, " (default ");
+ switch (opt->type) {
+ case AV_OPT_TYPE_BOOL:
+ av_log(av_log_obj, AV_LOG_INFO, "%s", get_bool_name(opt->default_val.i64));
+ break;
+ case AV_OPT_TYPE_FLAGS: {
+ char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64);
+ if (def_flags) {
+ av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags);
+ av_freep(&def_flags);
+ } else {
+ av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
+ }
+ break;
+ }
+ case AV_OPT_TYPE_DURATION: {
+ char buf[25];
+ format_duration(buf, sizeof(buf), opt->default_val.i64);
+ av_log(av_log_obj, AV_LOG_INFO, "%s", buf);
+ break;
+ }
+ case AV_OPT_TYPE_INT:
+ case AV_OPT_TYPE_UINT64:
+ case AV_OPT_TYPE_INT64: {
+ const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64);
+ if (def_const)
+ av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
+ else
+ log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
+ break;
+ }
+ case AV_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_FLOAT:
+ log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
+ break;
+ case AV_OPT_TYPE_RATIONAL: {
+ AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
+ av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
+ break;
+ case AV_OPT_TYPE_PIXEL_FMT:
+ av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
+ break;
+ case AV_OPT_TYPE_SAMPLE_FMT:
+ av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
+ break;
+ case AV_OPT_TYPE_COLOR:
+ case AV_OPT_TYPE_IMAGE_SIZE:
+ case AV_OPT_TYPE_STRING:
+ case AV_OPT_TYPE_DICT:
+ case AV_OPT_TYPE_VIDEO_RATE:
+ case AV_OPT_TYPE_CHLAYOUT:
+ av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
+ break;
+ }
+ av_log(av_log_obj, AV_LOG_INFO, ")");
+}
+
static void opt_list(void *obj, void *av_log_obj, const char *unit,
int req_flags, int rej_flags, enum AVOptionType parent_type)
{
@@ -1259,76 +1579,8 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
(opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? " " : "-",
opt->name);
- switch (opt->type) {
- case AV_OPT_TYPE_FLAGS:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
- break;
- case AV_OPT_TYPE_INT:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
- break;
- case AV_OPT_TYPE_INT64:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
- break;
- case AV_OPT_TYPE_UINT64:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<uint64>");
- break;
- case AV_OPT_TYPE_DOUBLE:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
- break;
- case AV_OPT_TYPE_FLOAT:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
- break;
- case AV_OPT_TYPE_STRING:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
- break;
- case AV_OPT_TYPE_RATIONAL:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
- break;
- case AV_OPT_TYPE_BINARY:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
- break;
- case AV_OPT_TYPE_DICT:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<dictionary>");
- break;
- case AV_OPT_TYPE_IMAGE_SIZE:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
- break;
- case AV_OPT_TYPE_VIDEO_RATE:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
- break;
- case AV_OPT_TYPE_PIXEL_FMT:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
- break;
- case AV_OPT_TYPE_SAMPLE_FMT:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
- break;
- case AV_OPT_TYPE_DURATION:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
- break;
- case AV_OPT_TYPE_COLOR:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
- break;
- case AV_OPT_TYPE_CHLAYOUT:
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
- break;
- case AV_OPT_TYPE_BOOL:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>");
- break;
- case AV_OPT_TYPE_CONST:
- if (parent_type == AV_OPT_TYPE_INT)
- av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", opt->default_val.i64);
- else
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
- break;
- default:
- av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
- break;
- }
+ log_type(av_log_obj, opt, parent_type);
+
av_log(av_log_obj, AV_LOG_INFO, "%c%c%c%c%c%c%c%c%c%c%c",
(opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.',
(opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.',
@@ -1365,78 +1617,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
av_opt_freep_ranges(&r);
}
- if (opt->type != AV_OPT_TYPE_CONST &&
- opt->type != AV_OPT_TYPE_BINARY &&
- !((opt->type == AV_OPT_TYPE_COLOR ||
- opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
- opt->type == AV_OPT_TYPE_STRING ||
- opt->type == AV_OPT_TYPE_DICT ||
- opt->type == AV_OPT_TYPE_CHLAYOUT ||
- opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
- !opt->default_val.str)) {
- av_log(av_log_obj, AV_LOG_INFO, " (default ");
- switch (opt->type) {
- case AV_OPT_TYPE_BOOL:
- av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(get_bool_name(opt->default_val.i64), "invalid"));
- break;
- case AV_OPT_TYPE_FLAGS: {
- char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64);
- if (def_flags) {
- av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags);
- av_freep(&def_flags);
- } else {
- av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
- }
- break;
- }
- case AV_OPT_TYPE_DURATION: {
- char buf[25];
- format_duration(buf, sizeof(buf), opt->default_val.i64);
- av_log(av_log_obj, AV_LOG_INFO, "%s", buf);
- break;
- }
- case AV_OPT_TYPE_INT:
- case AV_OPT_TYPE_UINT64:
- case AV_OPT_TYPE_INT64: {
- const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64);
- if (def_const)
- av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
- else
- log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
- break;
- }
- case AV_OPT_TYPE_DOUBLE:
- case AV_OPT_TYPE_FLOAT:
- log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
- break;
- case AV_OPT_TYPE_RATIONAL: {
- AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
- av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
- break;
- case AV_OPT_TYPE_PIXEL_FMT:
- av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
- break;
- case AV_OPT_TYPE_SAMPLE_FMT:
- av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
- break;
- case AV_OPT_TYPE_COLOR:
- case AV_OPT_TYPE_IMAGE_SIZE:
- case AV_OPT_TYPE_STRING:
- case AV_OPT_TYPE_DICT:
- case AV_OPT_TYPE_VIDEO_RATE:
- case AV_OPT_TYPE_CHLAYOUT:
- av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
- break;
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
- av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
- break;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- }
- av_log(av_log_obj, AV_LOG_INFO, ")");
- }
+ log_default(obj, av_log_obj, opt);
av_log(av_log_obj, AV_LOG_INFO, "\n");
if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
@@ -1473,6 +1654,21 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
if (opt->flags & AV_OPT_FLAG_READONLY)
continue;
+ if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) {
+ const AVOptionArrayDef *arr = opt->default_val.arr;
+ const char sep = opt_array_sep(opt);
+
+ av_assert0(sep && sep != '\\' &&
+ (sep < 'a' || sep > 'z') &&
+ (sep < 'A' || sep > 'Z') &&
+ (sep < '0' || sep > '9'));
+
+ if (arr && arr->def)
+ opt_set_array(s, s, opt, arr->def, dst);
+
+ continue;
+ }
+
switch (opt->type) {
case AV_OPT_TYPE_CONST:
/* Nothing to be done here */
@@ -1483,11 +1679,6 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_UINT64:
case AV_OPT_TYPE_DURATION:
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
case AV_OPT_TYPE_PIXEL_FMT:
case AV_OPT_TYPE_SAMPLE_FMT:
write_number(s, opt, dst, 1, 1, opt->default_val.i64);
@@ -1670,7 +1861,6 @@ int av_opt_set_from_string(void *ctx, const char *opts,
{
int ret, count = 0;
const char *dummy_shorthand = NULL;
- char *av_uninit(parsed_key), *av_uninit(value);
const char *key;
if (!opts)
@@ -1679,6 +1869,7 @@ int av_opt_set_from_string(void *ctx, const char *opts,
shorthand = &dummy_shorthand;
while (*opts) {
+ char *parsed_key, *value;
ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
*shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
&parsed_key, &value);
@@ -1720,23 +1911,12 @@ void av_opt_free(void *obj)
{
const AVOption *o = NULL;
while ((o = av_opt_next(obj, o))) {
- switch (o->type) {
- case AV_OPT_TYPE_STRING:
- case AV_OPT_TYPE_BINARY:
- av_freep((uint8_t *)obj + o->offset);
- break;
-
- case AV_OPT_TYPE_DICT:
- av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset));
- break;
+ void *pitem = (uint8_t *)obj + o->offset;
- case AV_OPT_TYPE_CHLAYOUT:
- av_channel_layout_uninit((AVChannelLayout *)(((uint8_t *)obj) + o->offset));
- break;
-
- default:
- break;
- }
+ if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
+ opt_free_array(o, pitem, opt_array_pcount(pitem));
+ else
+ opt_free_elem(o, pitem);
}
}
@@ -1838,48 +2018,93 @@ const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter)
void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
{
const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
- if(!opt)
+
+ // no direct access to array-type options
+ if (!opt || (opt->type & AV_OPT_TYPE_FLAG_ARRAY))
return NULL;
return (uint8_t*)obj + opt->offset;
}
-static int opt_size(enum AVOptionType type)
+static int opt_copy_elem(void *logctx, enum AVOptionType type,
+ void *dst, const void *src)
{
- switch(type) {
- case AV_OPT_TYPE_BOOL:
- case AV_OPT_TYPE_INT:
- case AV_OPT_TYPE_FLAGS:
- return sizeof(int);
- case AV_OPT_TYPE_DURATION:
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- case AV_OPT_TYPE_INT64:
- case AV_OPT_TYPE_UINT64:
- return sizeof(int64_t);
- case AV_OPT_TYPE_DOUBLE:
- return sizeof(double);
- case AV_OPT_TYPE_FLOAT:
- return sizeof(float);
- case AV_OPT_TYPE_STRING:
- return sizeof(uint8_t*);
- case AV_OPT_TYPE_VIDEO_RATE:
- case AV_OPT_TYPE_RATIONAL:
- return sizeof(AVRational);
- case AV_OPT_TYPE_BINARY:
- return sizeof(uint8_t*) + sizeof(int);
- case AV_OPT_TYPE_IMAGE_SIZE:
- return sizeof(int[2]);
- case AV_OPT_TYPE_PIXEL_FMT:
- return sizeof(enum AVPixelFormat);
- case AV_OPT_TYPE_SAMPLE_FMT:
- return sizeof(enum AVSampleFormat);
- case AV_OPT_TYPE_COLOR:
- return 4;
+ if (type == AV_OPT_TYPE_STRING) {
+ const char *src_str = *(const char *const *)src;
+ char **dstp = (char **)dst;
+ if (*dstp != src_str)
+ av_freep(dstp);
+ if (src_str) {
+ *dstp = av_strdup(src_str);
+ if (!*dstp)
+ return AVERROR(ENOMEM);
+ }
+ } else if (type == AV_OPT_TYPE_BINARY) {
+ const uint8_t *const *src8 = (const uint8_t *const *)src;
+ uint8_t **dst8 = (uint8_t **)dst;
+ int len = *(const int *)(src8 + 1);
+ if (*dst8 != *src8)
+ av_freep(dst8);
+ *dst8 = av_memdup(*src8, len);
+ if (len && !*dst8) {
+ *(int *)(dst8 + 1) = 0;
+ return AVERROR(ENOMEM);
+ }
+ *(int *)(dst8 + 1) = len;
+ } else if (type == AV_OPT_TYPE_CONST) {
+ // do nothing
+ } else if (type == AV_OPT_TYPE_DICT) {
+ const AVDictionary *sdict = *(const AVDictionary * const *)src;
+ AVDictionary **ddictp = (AVDictionary **)dst;
+ if (sdict != *ddictp)
+ av_dict_free(ddictp);
+ *ddictp = NULL;
+ return av_dict_copy(ddictp, sdict, 0);
+ } else if (type == AV_OPT_TYPE_CHLAYOUT) {
+ if (dst != src)
+ return av_channel_layout_copy(dst, src);
+ } else if (opt_is_pod(type)) {
+ size_t size = opt_elem_size[type];
+ memcpy(dst, src, size);
+ } else {
+ av_log(logctx, AV_LOG_ERROR, "Unhandled option type: %d\n", type);
+ return AVERROR(EINVAL);
}
- return AVERROR(EINVAL);
+
+ return 0;
+}
+
+static int opt_copy_array(void *logctx, const AVOption *o,
+ void **pdst, const void * const *psrc)
+{
+ unsigned nb_elems = *opt_array_pcount(psrc);
+ void *dst = NULL;
+ int ret;
+
+ if (*pdst == *psrc) {
+ *pdst = NULL;
+ *opt_array_pcount(pdst) = 0;
+ }
+
+ opt_free_array(o, pdst, opt_array_pcount(pdst));
+
+ dst = av_calloc(nb_elems, opt_elem_size[TYPE_BASE(o->type)]);
+ if (!dst)
+ return AVERROR(ENOMEM);
+
+ for (unsigned i = 0; i < nb_elems; i++) {
+ ret = opt_copy_elem(logctx, TYPE_BASE(o->type),
+ opt_array_pelem(o, dst, i),
+ opt_array_pelem(o, *(void**)psrc, i));
+ if (ret < 0) {
+ opt_free_array(o, &dst, &nb_elems);
+ return ret;
+ }
+ }
+
+ *pdst = dst;
+ *opt_array_pcount(pdst) = nb_elems;
+
+ return 0;
}
int av_opt_copy(void *dst, const void *src)
@@ -1898,47 +2123,12 @@ int av_opt_copy(void *dst, const void *src)
while ((o = av_opt_next(src, o))) {
void *field_dst = (uint8_t *)dst + o->offset;
void *field_src = (uint8_t *)src + o->offset;
- uint8_t **field_dst8 = (uint8_t **)field_dst;
- uint8_t **field_src8 = (uint8_t **)field_src;
-
- if (o->type == AV_OPT_TYPE_STRING) {
- if (*field_dst8 != *field_src8)
- av_freep(field_dst8);
- *field_dst8 = av_strdup(*field_src8);
- if (*field_src8 && !*field_dst8)
- ret = AVERROR(ENOMEM);
- } else if (o->type == AV_OPT_TYPE_BINARY) {
- int len = *(int *)(field_src8 + 1);
- if (*field_dst8 != *field_src8)
- av_freep(field_dst8);
- *field_dst8 = av_memdup(*field_src8, len);
- if (len && !*field_dst8) {
- ret = AVERROR(ENOMEM);
- len = 0;
- }
- *(int *)(field_dst8 + 1) = len;
- } else if (o->type == AV_OPT_TYPE_CONST) {
- // do nothing
- } else if (o->type == AV_OPT_TYPE_DICT) {
- AVDictionary **sdict = (AVDictionary **) field_src;
- AVDictionary **ddict = (AVDictionary **) field_dst;
- int ret2;
- if (*sdict != *ddict)
- av_dict_free(ddict);
- *ddict = NULL;
- ret2 = av_dict_copy(ddict, *sdict, 0);
- if (ret2 < 0)
- ret = ret2;
- } else if (o->type == AV_OPT_TYPE_CHLAYOUT) {
- if (field_dst != field_src)
- ret = av_channel_layout_copy(field_dst, field_src);
- } else {
- int size = opt_size(o->type);
- if (size < 0)
- ret = size;
- else
- memcpy(field_dst, field_src, size);
- }
+
+ int err = (o->type & AV_OPT_TYPE_FLAG_ARRAY) ?
+ opt_copy_array(dst, o, field_dst, field_src) :
+ opt_copy_elem (dst, o->type, field_dst, field_src);
+ if (err < 0)
+ ret = err;
}
return ret;
}
@@ -1995,11 +2185,6 @@ int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const ch
case AV_OPT_TYPE_DOUBLE:
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_COLOR:
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
break;
case AV_OPT_TYPE_STRING:
range->component_min = 0;
@@ -2059,8 +2244,7 @@ void av_opt_freep_ranges(AVOptionRanges **rangesp)
int av_opt_is_set_to_default(void *obj, const AVOption *o)
{
int64_t i64;
- double d, d2;
- float f;
+ double d;
AVRational q;
int ret, w, h;
char *str;
@@ -2071,6 +2255,24 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o)
dst = ((uint8_t*)obj) + o->offset;
+ if (o->type & AV_OPT_TYPE_FLAG_ARRAY) {
+ const char *def = o->default_val.arr ? o->default_val.arr->def : NULL;
+ uint8_t *val;
+
+ ret = opt_get_array(o, dst, &val);
+ if (ret < 0)
+ return ret;
+
+ if (!!val != !!def)
+ ret = 0;
+ else if (val)
+ ret = !strcmp(val, def);
+
+ av_freep(&val);
+
+ return ret;
+ }
+
switch (o->type) {
case AV_OPT_TYPE_CONST:
return 1;
@@ -2079,11 +2281,6 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o)
case AV_OPT_TYPE_PIXEL_FMT:
case AV_OPT_TYPE_SAMPLE_FMT:
case AV_OPT_TYPE_INT:
-#if FF_API_OLD_CHANNEL_LAYOUT
-FF_DISABLE_DEPRECATION_WARNINGS
- case AV_OPT_TYPE_CHANNEL_LAYOUT:
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_UINT64:
@@ -2105,13 +2302,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
return 0;
return !strcmp(str, o->default_val.str);
case AV_OPT_TYPE_DOUBLE:
- read_number(o, dst, &d, NULL, NULL);
+ d = *(double *)dst;
return o->default_val.dbl == d;
case AV_OPT_TYPE_FLOAT:
- read_number(o, dst, &d, NULL, NULL);
- f = o->default_val.dbl;
- d2 = f;
- return d2 == d;
+ d = *(float *)dst;
+ return (float)o->default_val.dbl == d;
case AV_OPT_TYPE_RATIONAL:
q = av_d2q(o->default_val.dbl, INT_MAX);
return !av_cmp_q(*(AVRational*)dst, q);
diff --git a/media/ffvpx/libavutil/opt.h b/media/ffvpx/libavutil/opt.h
index 461b5d3b6b..e6013662f6 100644
--- a/media/ffvpx/libavutil/opt.h
+++ b/media/ffvpx/libavutil/opt.h
@@ -43,6 +43,16 @@
* ("objects"). An option can have a help text, a type and a range of possible
* values. Options may then be enumerated, read and written to.
*
+ * There are two modes of access to members of AVOption and its child structs.
+ * One is called 'native access', and refers to access from the code that
+ * declares the AVOption in question. The other is 'foreign access', and refers
+ * to access from other code.
+ *
+ * Certain struct members in this header are documented as 'native access only'
+ * or similar - it means that only the code that declared the AVOption in
+ * question is allowed to access the field. This allows us to extend the
+ * semantics of those fields without breaking API compatibility.
+ *
* @section avoptions_implement Implementing AVOptions
* This section describes how to add AVOptions capabilities to a struct.
*
@@ -221,7 +231,7 @@
*/
enum AVOptionType{
- AV_OPT_TYPE_FLAGS,
+ AV_OPT_TYPE_FLAGS = 1,
AV_OPT_TYPE_INT,
AV_OPT_TYPE_INT64,
AV_OPT_TYPE_DOUBLE,
@@ -238,14 +248,99 @@ enum AVOptionType{
AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational
AV_OPT_TYPE_DURATION,
AV_OPT_TYPE_COLOR,
-#if FF_API_OLD_CHANNEL_LAYOUT
- AV_OPT_TYPE_CHANNEL_LAYOUT,
-#endif
AV_OPT_TYPE_BOOL,
AV_OPT_TYPE_CHLAYOUT,
+
+ /**
+ * May be combined with another regular option type to declare an array
+ * option.
+ *
+ * For array options, @ref AVOption.offset should refer to a pointer
+ * corresponding to the option type. The pointer should be immediately
+ * followed by an unsigned int that will store the number of elements in the
+ * array.
+ */
+ AV_OPT_TYPE_FLAG_ARRAY = (1 << 16),
};
/**
+ * A generic parameter which can be set by the user for muxing or encoding.
+ */
+#define AV_OPT_FLAG_ENCODING_PARAM (1 << 0)
+/**
+ * A generic parameter which can be set by the user for demuxing or decoding.
+ */
+#define AV_OPT_FLAG_DECODING_PARAM (1 << 1)
+#define AV_OPT_FLAG_AUDIO_PARAM (1 << 3)
+#define AV_OPT_FLAG_VIDEO_PARAM (1 << 4)
+#define AV_OPT_FLAG_SUBTITLE_PARAM (1 << 5)
+/**
+ * The option is intended for exporting values to the caller.
+ */
+#define AV_OPT_FLAG_EXPORT (1 << 6)
+/**
+ * The option may not be set through the AVOptions API, only read.
+ * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set.
+ */
+#define AV_OPT_FLAG_READONLY (1 << 7)
+/**
+ * A generic parameter which can be set by the user for bit stream filtering.
+ */
+#define AV_OPT_FLAG_BSF_PARAM (1 << 8)
+
+/**
+ * A generic parameter which can be set by the user at runtime.
+ */
+#define AV_OPT_FLAG_RUNTIME_PARAM (1 << 15)
+/**
+ * A generic parameter which can be set by the user for filtering.
+ */
+#define AV_OPT_FLAG_FILTERING_PARAM (1 << 16)
+/**
+ * Set if option is deprecated, users should refer to AVOption.help text for
+ * more information.
+ */
+#define AV_OPT_FLAG_DEPRECATED (1 << 17)
+/**
+ * Set if option constants can also reside in child objects.
+ */
+#define AV_OPT_FLAG_CHILD_CONSTS (1 << 18)
+
+/**
+ * May be set as default_val for AV_OPT_TYPE_FLAG_ARRAY options.
+ */
+typedef struct AVOptionArrayDef {
+ /**
+ * Native access only.
+ *
+ * Default value of the option, as would be serialized by av_opt_get() (i.e.
+ * using the value of sep as the separator).
+ */
+ const char *def;
+
+ /**
+ * Minimum number of elements in the array. When this field is non-zero, def
+ * must be non-NULL and contain at least this number of elements.
+ */
+ unsigned size_min;
+ /**
+ * Maximum number of elements in the array, 0 when unlimited.
+ */
+ unsigned size_max;
+
+ /**
+ * Separator between array elements in string representations of this
+ * option, used by av_opt_set() and av_opt_get(). It must be a printable
+ * ASCII character, excluding alphanumeric and the backslash. A comma is
+ * used when sep=0.
+ *
+ * The separator and the backslash must be backslash-escaped in order to
+ * appear in string representations of the option value.
+ */
+ char sep;
+} AVOptionArrayDef;
+
+/**
* AVOption
*/
typedef struct AVOption {
@@ -258,6 +353,8 @@ typedef struct AVOption {
const char *help;
/**
+ * Native access only.
+ *
* The offset relative to the context structure where the option
* value is stored. It should be 0 for named constants.
*/
@@ -265,6 +362,7 @@ typedef struct AVOption {
enum AVOptionType type;
/**
+ * Native access only, except when documented otherwise.
* the default value for scalar options
*/
union {
@@ -273,31 +371,22 @@ typedef struct AVOption {
const char *str;
/* TODO those are unused now */
AVRational q;
+
+ /**
+ * Used for AV_OPT_TYPE_FLAG_ARRAY options. May be NULL.
+ *
+ * Foreign access to some members allowed, as noted in AVOptionArrayDef
+ * documentation.
+ */
+ const AVOptionArrayDef *arr;
} default_val;
double min; ///< minimum valid value for the option
double max; ///< maximum valid value for the option
+ /**
+ * A combination of AV_OPT_FLAG_*.
+ */
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
-#define AV_OPT_FLAG_AUDIO_PARAM 8
-#define AV_OPT_FLAG_VIDEO_PARAM 16
-#define AV_OPT_FLAG_SUBTITLE_PARAM 32
-/**
- * The option is intended for exporting values to the caller.
- */
-#define AV_OPT_FLAG_EXPORT 64
-/**
- * The option may not be set through the AVOptions API, only read.
- * 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_RUNTIME_PARAM (1<<15) ///< a generic parameter which can be set by the user at runtime
-#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
-#define AV_OPT_FLAG_DEPRECATED (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information
-#define AV_OPT_FLAG_CHILD_CONSTS (1<<18) ///< set if option constants can also reside in child objects
-//FIXME think about enc-audio, ... style flags
/**
* The logical unit to which the option belongs. Non-constant
@@ -376,15 +465,9 @@ typedef struct AVOptionRanges {
} AVOptionRanges;
/**
- * Show the obj options.
- *
- * @param req_flags requested flags for the options to show. Show only the
- * options for which it is opt->flags & req_flags.
- * @param rej_flags rejected flags for the options to show. Show only the
- * options for which it is !(opt->flags & req_flags).
- * @param av_log_obj log context to use for showing the options
+ * @defgroup opt_mng AVOption (un)initialization and inspection.
+ * @{
*/
-int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags);
/**
* Set the values of all AVOption fields to their default values.
@@ -405,160 +488,36 @@ void av_opt_set_defaults(void *s);
void av_opt_set_defaults2(void *s, int mask, int flags);
/**
- * Parse the key/value pairs list in opts. For each key/value pair
- * found, stores the value in the field in ctx that is named like the
- * key. ctx must be an AVClass context, storing is done using
- * AVOptions.
- *
- * @param opts options string to parse, may be NULL
- * @param key_val_sep a 0-terminated list of characters used to
- * separate key from value
- * @param pairs_sep a 0-terminated list of characters used to separate
- * two pairs from each other
- * @return the number of successfully set key/value pairs, or a negative
- * value corresponding to an AVERROR code in case of error:
- * AVERROR(EINVAL) if opts cannot be parsed,
- * the error code issued by av_opt_set() if a key/value pair
- * cannot be set
- */
-int av_set_options_string(void *ctx, const char *opts,
- const char *key_val_sep, const char *pairs_sep);
-
-/**
- * Parse the key-value pairs list in opts. For each key=value pair found,
- * set the value of the corresponding option in ctx.
- *
- * @param ctx the AVClass object to set options on
- * @param opts the options string, key-value pairs separated by a
- * delimiter
- * @param shorthand a NULL-terminated array of options names for shorthand
- * notation: if the first field in opts has no key part,
- * the key is taken from the first element of shorthand;
- * then again for the second, etc., until either opts is
- * finished, shorthand is finished or a named option is
- * found; after that, all options must be named
- * @param key_val_sep a 0-terminated list of characters used to separate
- * key from value, for example '='
- * @param pairs_sep a 0-terminated list of characters used to separate
- * two pairs from each other, for example ':' or ','
- * @return the number of successfully set key=value pairs, or a negative
- * value corresponding to an AVERROR code in case of error:
- * AVERROR(EINVAL) if opts cannot be parsed,
- * the error code issued by av_set_string3() if a key/value pair
- * cannot be set
- *
- * Options names must use only the following characters: a-z A-Z 0-9 - . / _
- * Separators must use characters distinct from option names and from each
- * other.
- */
-int av_opt_set_from_string(void *ctx, const char *opts,
- const char *const *shorthand,
- const char *key_val_sep, const char *pairs_sep);
-/**
* Free all allocated objects in obj.
*/
void av_opt_free(void *obj);
/**
- * Check whether a particular flag is set in a flags field.
- *
- * @param field_name the name of the flag field option
- * @param flag_name the name of the flag to check
- * @return non-zero if the flag is set, zero if the flag isn't set,
- * isn't of the right type, or the flags field doesn't exist.
- */
-int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name);
-
-/**
- * Set all the options from a given dictionary on an object.
- *
- * @param obj a struct whose first element is a pointer to AVClass
- * @param options options to process. This dictionary will be freed and replaced
- * by a new one containing all options not found in obj.
- * Of course this new dictionary needs to be freed by caller
- * with av_dict_free().
- *
- * @return 0 on success, a negative AVERROR if some option was found in obj,
- * but could not be set.
- *
- * @see av_dict_copy()
- */
-int av_opt_set_dict(void *obj, struct AVDictionary **options);
-
-
-/**
- * Set all the options from a given dictionary on an object.
- *
- * @param obj a struct whose first element is a pointer to AVClass
- * @param options options to process. This dictionary will be freed and replaced
- * by a new one containing all options not found in obj.
- * Of course this new dictionary needs to be freed by caller
- * with av_dict_free().
- * @param search_flags A combination of AV_OPT_SEARCH_*.
- *
- * @return 0 on success, a negative AVERROR if some option was found in obj,
- * but could not be set.
+ * Iterate over all AVOptions belonging to obj.
*
- * @see av_dict_copy()
+ * @param obj an AVOptions-enabled struct or a double pointer to an
+ * AVClass describing it.
+ * @param prev result of the previous call to av_opt_next() on this object
+ * or NULL
+ * @return next AVOption or NULL
*/
-int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags);
+const AVOption *av_opt_next(const void *obj, const AVOption *prev);
/**
- * Extract a key-value pair from the beginning of a string.
- *
- * @param ropts pointer to the options string, will be updated to
- * point to the rest of the string (one of the pairs_sep
- * or the final NUL)
- * @param key_val_sep a 0-terminated list of characters used to separate
- * key from value, for example '='
- * @param pairs_sep a 0-terminated list of characters used to separate
- * two pairs from each other, for example ':' or ','
- * @param flags flags; see the AV_OPT_FLAG_* values below
- * @param rkey parsed key; must be freed using av_free()
- * @param rval parsed value; must be freed using av_free()
- *
- * @return >=0 for success, or a negative value corresponding to an
- * AVERROR code in case of error; in particular:
- * AVERROR(EINVAL) if no key is present
+ * Iterate over AVOptions-enabled children of obj.
*
+ * @param prev result of a previous call to this function or NULL
+ * @return next AVOptions-enabled child or NULL
*/
-int av_opt_get_key_value(const char **ropts,
- const char *key_val_sep, const char *pairs_sep,
- unsigned flags,
- char **rkey, char **rval);
-
-enum {
-
- /**
- * Accept to parse a value without a key; the key will then be returned
- * as NULL.
- */
- AV_OPT_FLAG_IMPLICIT_KEY = 1,
-};
+void *av_opt_child_next(void *obj, void *prev);
/**
- * @defgroup opt_eval_funcs Evaluating option strings
- * @{
- * This group of functions can be used to evaluate option strings
- * and get numbers out of them. They do the same thing as av_opt_set(),
- * except the result is written into the caller-supplied pointer.
- *
- * @param obj a struct whose first element is a pointer to AVClass.
- * @param o an option for which the string is to be evaluated.
- * @param val string to be evaluated.
- * @param *_out value of the string will be written here.
+ * Iterate over potential AVOptions-enabled children of parent.
*
- * @return 0 on success, a negative number on failure.
- */
-int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int *flags_out);
-int av_opt_eval_int (void *obj, const AVOption *o, const char *val, int *int_out);
-int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t *int64_out);
-int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float *float_out);
-int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double *double_out);
-int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational *q_out);
-/**
- * @}
+ * @param iter a pointer where iteration state is stored.
+ * @return AVClass corresponding to next potential child or NULL
*/
+const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter);
#define AV_OPT_SEARCH_CHILDREN (1 << 0) /**< Search in possible children of the
given object first. */
@@ -633,31 +592,161 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
int opt_flags, int search_flags, void **target_obj);
/**
- * Iterate over all AVOptions belonging to obj.
+ * Show the obj options.
*
- * @param obj an AVOptions-enabled struct or a double pointer to an
- * AVClass describing it.
- * @param prev result of the previous call to av_opt_next() on this object
- * or NULL
- * @return next AVOption or NULL
+ * @param req_flags requested flags for the options to show. Show only the
+ * options for which it is opt->flags & req_flags.
+ * @param rej_flags rejected flags for the options to show. Show only the
+ * options for which it is !(opt->flags & req_flags).
+ * @param av_log_obj log context to use for showing the options
*/
-const AVOption *av_opt_next(const void *obj, const AVOption *prev);
+int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags);
/**
- * Iterate over AVOptions-enabled children of obj.
+ * Extract a key-value pair from the beginning of a string.
+ *
+ * @param ropts pointer to the options string, will be updated to
+ * point to the rest of the string (one of the pairs_sep
+ * or the final NUL)
+ * @param key_val_sep a 0-terminated list of characters used to separate
+ * key from value, for example '='
+ * @param pairs_sep a 0-terminated list of characters used to separate
+ * two pairs from each other, for example ':' or ','
+ * @param flags flags; see the AV_OPT_FLAG_* values below
+ * @param rkey parsed key; must be freed using av_free()
+ * @param rval parsed value; must be freed using av_free()
+ *
+ * @return >=0 for success, or a negative value corresponding to an
+ * AVERROR code in case of error; in particular:
+ * AVERROR(EINVAL) if no key is present
*
- * @param prev result of a previous call to this function or NULL
- * @return next AVOptions-enabled child or NULL
*/
-void *av_opt_child_next(void *obj, void *prev);
+int av_opt_get_key_value(const char **ropts,
+ const char *key_val_sep, const char *pairs_sep,
+ unsigned flags,
+ char **rkey, char **rval);
+
+enum {
+
+ /**
+ * Accept to parse a value without a key; the key will then be returned
+ * as NULL.
+ */
+ AV_OPT_FLAG_IMPLICIT_KEY = 1,
+};
/**
- * Iterate over potential AVOptions-enabled children of parent.
+ * @}
+ */
+
+/**
+ * @defgroup opt_write Setting and modifying option values
+ * @{
+ */
+
+/**
+ * Parse the key/value pairs list in opts. For each key/value pair
+ * found, stores the value in the field in ctx that is named like the
+ * key. ctx must be an AVClass context, storing is done using
+ * AVOptions.
*
- * @param iter a pointer where iteration state is stored.
- * @return AVClass corresponding to next potential child or NULL
+ * @param opts options string to parse, may be NULL
+ * @param key_val_sep a 0-terminated list of characters used to
+ * separate key from value
+ * @param pairs_sep a 0-terminated list of characters used to separate
+ * two pairs from each other
+ * @return the number of successfully set key/value pairs, or a negative
+ * value corresponding to an AVERROR code in case of error:
+ * AVERROR(EINVAL) if opts cannot be parsed,
+ * the error code issued by av_opt_set() if a key/value pair
+ * cannot be set
*/
-const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter);
+int av_set_options_string(void *ctx, const char *opts,
+ const char *key_val_sep, const char *pairs_sep);
+
+/**
+ * Parse the key-value pairs list in opts. For each key=value pair found,
+ * set the value of the corresponding option in ctx.
+ *
+ * @param ctx the AVClass object to set options on
+ * @param opts the options string, key-value pairs separated by a
+ * delimiter
+ * @param shorthand a NULL-terminated array of options names for shorthand
+ * notation: if the first field in opts has no key part,
+ * the key is taken from the first element of shorthand;
+ * then again for the second, etc., until either opts is
+ * finished, shorthand is finished or a named option is
+ * found; after that, all options must be named
+ * @param key_val_sep a 0-terminated list of characters used to separate
+ * key from value, for example '='
+ * @param pairs_sep a 0-terminated list of characters used to separate
+ * two pairs from each other, for example ':' or ','
+ * @return the number of successfully set key=value pairs, or a negative
+ * value corresponding to an AVERROR code in case of error:
+ * AVERROR(EINVAL) if opts cannot be parsed,
+ * the error code issued by av_set_string3() if a key/value pair
+ * cannot be set
+ *
+ * Options names must use only the following characters: a-z A-Z 0-9 - . / _
+ * Separators must use characters distinct from option names and from each
+ * other.
+ */
+int av_opt_set_from_string(void *ctx, const char *opts,
+ const char *const *shorthand,
+ const char *key_val_sep, const char *pairs_sep);
+
+/**
+ * Set all the options from a given dictionary on an object.
+ *
+ * @param obj a struct whose first element is a pointer to AVClass
+ * @param options options to process. This dictionary will be freed and replaced
+ * by a new one containing all options not found in obj.
+ * Of course this new dictionary needs to be freed by caller
+ * with av_dict_free().
+ *
+ * @return 0 on success, a negative AVERROR if some option was found in obj,
+ * but could not be set.
+ *
+ * @see av_dict_copy()
+ */
+int av_opt_set_dict(void *obj, struct AVDictionary **options);
+
+
+/**
+ * Set all the options from a given dictionary on an object.
+ *
+ * @param obj a struct whose first element is a pointer to AVClass
+ * @param options options to process. This dictionary will be freed and replaced
+ * by a new one containing all options not found in obj.
+ * Of course this new dictionary needs to be freed by caller
+ * with av_dict_free().
+ * @param search_flags A combination of AV_OPT_SEARCH_*.
+ *
+ * @return 0 on success, a negative AVERROR if some option was found in obj,
+ * but could not be set.
+ *
+ * @see av_dict_copy()
+ */
+int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags);
+
+/**
+ * Copy options from src object into dest object.
+ *
+ * The underlying AVClass of both src and dest must coincide. The guarantee
+ * below does not apply if this is not fulfilled.
+ *
+ * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object.
+ * Original memory allocated for such options is freed unless both src and dest options points to the same memory.
+ *
+ * Even on error it is guaranteed that allocated options from src and dest
+ * no longer alias each other afterwards; in particular calling av_opt_free()
+ * on both src and dest is safe afterwards if dest has been memdup'ed from src.
+ *
+ * @param dest Object to copy from
+ * @param src Object to copy into
+ * @return 0 on success, negative on error
+ */
+int av_opt_copy(void *dest, const void *src);
/**
* @defgroup opt_set_funcs Option setting functions
@@ -697,10 +786,6 @@ int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_
int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
-#if FF_API_OLD_CHANNEL_LAYOUT
-attribute_deprecated
-int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
-#endif
int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *layout, int search_flags);
/**
* @note Any old dictionary present is discarded and replaced with a copy of the new one. The
@@ -726,6 +811,12 @@ int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, in
/**
* @}
+ * @}
+ */
+
+/**
+ * @defgroup opt_read Reading option values
+ * @{
*/
/**
@@ -756,10 +847,6 @@ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_
int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
-#if FF_API_OLD_CHANNEL_LAYOUT
-attribute_deprecated
-int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
-#endif
int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *layout);
/**
* @param[out] out_val The returned dictionary is a copy of the actual value and must
@@ -769,70 +856,40 @@ int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDiction
/**
* @}
*/
-/**
- * Gets a pointer to the requested field in a struct.
- * This function allows accessing a struct even when its fields are moved or
- * renamed since the application making the access has been compiled,
- *
- * @returns a pointer to the field, it can be cast to the correct type and read
- * or written to.
- */
-void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
-
-/**
- * Free an AVOptionRanges struct and set it to NULL.
- */
-void av_opt_freep_ranges(AVOptionRanges **ranges);
/**
- * Get a list of allowed ranges for the given option.
- *
- * The returned list may depend on other fields in obj like for example profile.
- *
- * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
- * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
- * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
+ * @defgroup opt_eval_funcs Evaluating option strings
+ * @{
+ * This group of functions can be used to evaluate option strings
+ * and get numbers out of them. They do the same thing as av_opt_set(),
+ * except the result is written into the caller-supplied pointer.
*
- * The result must be freed with av_opt_freep_ranges.
+ * @param obj a struct whose first element is a pointer to AVClass.
+ * @param o an option for which the string is to be evaluated.
+ * @param val string to be evaluated.
+ * @param *_out value of the string will be written here.
*
- * @return number of compontents returned on success, a negative errro code otherwise
+ * @return 0 on success, a negative number on failure.
*/
-int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
-
+int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int *flags_out);
+int av_opt_eval_int (void *obj, const AVOption *o, const char *val, int *int_out);
+int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t *int64_out);
+int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float *float_out);
+int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double *double_out);
+int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational *q_out);
/**
- * Copy options from src object into dest object.
- *
- * The underlying AVClass of both src and dest must coincide. The guarantee
- * below does not apply if this is not fulfilled.
- *
- * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object.
- * Original memory allocated for such options is freed unless both src and dest options points to the same memory.
- *
- * Even on error it is guaranteed that allocated options from src and dest
- * no longer alias each other afterwards; in particular calling av_opt_free()
- * on both src and dest is safe afterwards if dest has been memdup'ed from src.
- *
- * @param dest Object to copy from
- * @param src Object to copy into
- * @return 0 on success, negative on error
+ * @}
*/
-int av_opt_copy(void *dest, const void *src);
/**
- * Get a default list of allowed ranges for the given option.
- *
- * This list is constructed without using the AVClass.query_ranges() callback
- * and can be used as fallback from within the callback.
- *
- * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
- * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
- * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
- *
- * The result must be freed with av_opt_free_ranges.
+ * Gets a pointer to the requested field in a struct.
+ * This function allows accessing a struct even when its fields are moved or
+ * renamed since the application making the access has been compiled,
*
- * @return number of compontents returned on success, a negative errro code otherwise
+ * @returns a pointer to the field, it can be cast to the correct type and read
+ * or written to.
*/
-int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
+void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
/**
* Check if given option is set to its default value.
@@ -860,6 +917,15 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o);
*/
int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags);
+/**
+ * Check whether a particular flag is set in a flags field.
+ *
+ * @param field_name the name of the flag field option
+ * @param flag_name the name of the flag to check
+ * @return non-zero if the flag is set, zero if the flag isn't set,
+ * isn't of the right type, or the flags field doesn't exist.
+ */
+int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name);
#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only.
#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only.
@@ -884,6 +950,47 @@ int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_fla
*/
int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
const char key_val_sep, const char pairs_sep);
+
+/**
+ * @}
+ */
+
+/**
+ * Free an AVOptionRanges struct and set it to NULL.
+ */
+void av_opt_freep_ranges(AVOptionRanges **ranges);
+
+/**
+ * Get a list of allowed ranges for the given option.
+ *
+ * The returned list may depend on other fields in obj like for example profile.
+ *
+ * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+ * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+ * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
+ *
+ * The result must be freed with av_opt_freep_ranges.
+ *
+ * @return number of compontents returned on success, a negative errro code otherwise
+ */
+int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
+
+/**
+ * Get a default list of allowed ranges for the given option.
+ *
+ * This list is constructed without using the AVClass.query_ranges() callback
+ * and can be used as fallback from within the callback.
+ *
+ * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+ * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+ * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
+ *
+ * The result must be freed with av_opt_free_ranges.
+ *
+ * @return number of compontents returned on success, a negative errro code otherwise
+ */
+int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
+
/**
* @}
*/
diff --git a/media/ffvpx/libavutil/pixdesc.c b/media/ffvpx/libavutil/pixdesc.c
index f6d4d01460..1c0bcf2232 100644
--- a/media/ffvpx/libavutil/pixdesc.c
+++ b/media/ffvpx/libavutil/pixdesc.c
@@ -460,12 +460,6 @@ 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] = {
- .name = "xvmc",
- .flags = AV_PIX_FMT_FLAG_HWACCEL,
- },
-#endif
[AV_PIX_FMT_UYVY422] = {
.name = "uyvy422",
.nb_components = 3,
@@ -2860,6 +2854,9 @@ static const char * const color_space_names[] = {
[AVCOL_SPC_CHROMA_DERIVED_NCL] = "chroma-derived-nc",
[AVCOL_SPC_CHROMA_DERIVED_CL] = "chroma-derived-c",
[AVCOL_SPC_ICTCP] = "ictcp",
+ [AVCOL_SPC_IPT_C2] = "ipt-c2",
+ [AVCOL_SPC_YCGCO_RE] = "ycgco-re",
+ [AVCOL_SPC_YCGCO_RO] = "ycgco-ro",
};
static const char * const chroma_location_names[] = {
diff --git a/media/ffvpx/libavutil/pixfmt.h b/media/ffvpx/libavutil/pixfmt.h
index 9c87571f49..a7f50e1690 100644
--- a/media/ffvpx/libavutil/pixfmt.h
+++ b/media/ffvpx/libavutil/pixfmt.h
@@ -33,6 +33,13 @@
#define AVPALETTE_COUNT 256
/**
+ * Maximum number of planes in any pixel format.
+ * This should be used when a maximum is needed, but code should not
+ * be written to require a maximum for no good reason.
+ */
+#define AV_VIDEO_MAX_PLANES 4
+
+/**
* Pixel format.
*
* @note
@@ -288,10 +295,6 @@ enum AVPixelFormat {
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
-
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
@@ -620,6 +623,9 @@ enum AVColorSpace {
AVCOL_SPC_CHROMA_DERIVED_NCL = 12, ///< Chromaticity-derived non-constant luminance system
AVCOL_SPC_CHROMA_DERIVED_CL = 13, ///< Chromaticity-derived constant luminance system
AVCOL_SPC_ICTCP = 14, ///< ITU-R BT.2100-0, ICtCp
+ AVCOL_SPC_IPT_C2 = 15, ///< SMPTE ST 2128, IPT-C2
+ AVCOL_SPC_YCGCO_RE = 16, ///< YCgCo-R, even addition of bits
+ AVCOL_SPC_YCGCO_RO = 17, ///< YCgCo-R, odd addition of bits
AVCOL_SPC_NB ///< Not part of ABI
};
diff --git a/media/ffvpx/libavutil/rational.c b/media/ffvpx/libavutil/rational.c
index eb148ddb12..329fbf3302 100644
--- a/media/ffvpx/libavutil/rational.c
+++ b/media/ffvpx/libavutil/rational.c
@@ -114,7 +114,7 @@ AVRational av_d2q(double d, int max)
return (AVRational) { d < 0 ? -1 : 1, 0 };
frexp(d, &exponent);
exponent = FFMAX(exponent-1, 0);
- den = 1LL << (61 - exponent);
+ den = 1LL << (62 - exponent);
// (int64_t)rint() and llrint() do not work with gcc on ia64 and sparc64,
// see Ticket2713 for affected gcc/glibc versions
av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, max);
diff --git a/media/ffvpx/libavutil/rational.h b/media/ffvpx/libavutil/rational.h
index 8cbfc8e066..849f47f38d 100644
--- a/media/ffvpx/libavutil/rational.h
+++ b/media/ffvpx/libavutil/rational.h
@@ -168,6 +168,10 @@ static av_always_inline AVRational av_inv_q(AVRational q)
* In case of infinity, the returned value is expressed as `{1, 0}` or
* `{-1, 0}` depending on the sign.
*
+ * In general rational numbers with |num| <= 1<<26 && |den| <= 1<<26
+ * can be recovered exactly from their double representation.
+ * (no exceptions were found within 1B random ones)
+ *
* @param d `double` to convert
* @param max Maximum allowed numerator and denominator
* @return `d` in AVRational form
diff --git a/media/ffvpx/libavutil/thread.h b/media/ffvpx/libavutil/thread.h
index 2ded498c89..2c00c7cc35 100644
--- a/media/ffvpx/libavutil/thread.h
+++ b/media/ffvpx/libavutil/thread.h
@@ -26,6 +26,8 @@
#if HAVE_PRCTL
#include <sys/prctl.h>
+#elif (HAVE_PTHREAD_SETNAME_NP || HAVE_PTHREAD_SET_NAME_NP) && HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
#endif
#include "error.h"
@@ -213,11 +215,25 @@ static inline int ff_thread_once(char *control, void (*routine)(void))
static inline int ff_thread_setname(const char *name)
{
+ int ret = 0;
+
#if HAVE_PRCTL
- return AVERROR(prctl(PR_SET_NAME, name));
+ ret = AVERROR(prctl(PR_SET_NAME, name));
+#elif HAVE_PTHREAD_SETNAME_NP
+#if defined(__APPLE__)
+ ret = AVERROR(pthread_setname_np(name));
+#elif defined(__NetBSD__)
+ ret = AVERROR(pthread_setname_np(pthread_self(), "%s", name));
+#else
+ ret = AVERROR(pthread_setname_np(pthread_self(), name));
+#endif
+#elif HAVE_PTHREAD_SET_NAME_NP
+ pthread_set_name_np(pthread_self(), name);
+#else
+ ret = AVERROR(ENOSYS);
#endif
- return AVERROR(ENOSYS);
+ return ret;
}
#endif /* AVUTIL_THREAD_H */
diff --git a/media/ffvpx/libavutil/timecode.c b/media/ffvpx/libavutil/timecode.c
index b93f05b4b8..bd879bd3cc 100644
--- a/media/ffvpx/libavutil/timecode.c
+++ b/media/ffvpx/libavutil/timecode.c
@@ -210,7 +210,7 @@ static int fps_from_frame_rate(AVRational rate)
{
if (!rate.den || !rate.num)
return -1;
- return (rate.num + rate.den/2) / rate.den;
+ return (rate.num + rate.den/2LL) / rate.den;
}
int av_timecode_check_frame_rate(AVRational rate)
diff --git a/media/ffvpx/libavutil/timestamp.h b/media/ffvpx/libavutil/timestamp.h
index 9ae64da8a1..fa53a46b98 100644
--- a/media/ffvpx/libavutil/timestamp.h
+++ b/media/ffvpx/libavutil/timestamp.h
@@ -62,11 +62,18 @@ static inline char *av_ts_make_string(char *buf, int64_t ts)
* @param tb the timebase of the timestamp
* @return the buffer in input
*/
-static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb)
+char *av_ts_make_time_string2(char *buf, int64_t ts, AVRational tb);
+
+/**
+ * Fill the provided buffer with a string containing a timestamp
+ * representation.
+ *
+ * @see av_ts_make_time_string2
+ */
+static inline char *av_ts_make_time_string(char *buf, int64_t ts,
+ const AVRational *tb)
{
- if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
- else snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts);
- return buf;
+ return av_ts_make_time_string2(buf, ts, *tb);
}
/**
diff --git a/media/ffvpx/libavutil/tx.c b/media/ffvpx/libavutil/tx.c
index a1f767039b..426303d1f3 100644
--- a/media/ffvpx/libavutil/tx.c
+++ b/media/ffvpx/libavutil/tx.c
@@ -19,6 +19,7 @@
#include "avassert.h"
#include "intmath.h"
#include "cpu.h"
+#include "mem.h"
#include "qsort.h"
#include "bprint.h"
@@ -593,7 +594,8 @@ static void print_type(AVBPrint *bp, enum AVTXType type)
"unknown");
}
-static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio)
+static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio,
+ int log_level)
{
AVBPrint bp;
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
@@ -643,7 +645,7 @@ static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_pr
if (print_prio)
av_bprintf(&bp, ", prio: %i", prio);
- av_log(NULL, AV_LOG_DEBUG, "%s\n", bp.str);
+ av_log(NULL, log_level, "%s\n", bp.str);
}
static void print_tx_structure(AVTXContext *s, int depth)
@@ -653,7 +655,7 @@ static void print_tx_structure(AVTXContext *s, int depth)
for (int i = 0; i <= depth; i++)
av_log(NULL, AV_LOG_DEBUG, " ");
- print_cd_info(cd, cd->prio, s->len, 0);
+ print_cd_info(cd, cd->prio, s->len, 0, AV_LOG_DEBUG);
for (int i = 0; i < s->nb_sub; i++)
print_tx_structure(&s->sub[i], depth + 1);
@@ -816,11 +818,11 @@ av_cold int ff_tx_init_subtx(AVTXContext *s, enum AVTXType type,
AV_QSORT(cd_matches, nb_cd_matches, TXCodeletMatch, cmp_matches);
#if !CONFIG_SMALL
- av_log(NULL, AV_LOG_DEBUG, "%s\n", bp.str);
+ av_log(NULL, AV_LOG_TRACE, "%s\n", bp.str);
for (int i = 0; i < nb_cd_matches; i++) {
- av_log(NULL, AV_LOG_DEBUG, " %i: ", i + 1);
- print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 0, 1);
+ av_log(NULL, AV_LOG_TRACE, " %i: ", i + 1);
+ print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 0, 1, AV_LOG_TRACE);
}
#endif
@@ -914,10 +916,12 @@ av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type,
if (!(flags & AV_TX_INPLACE))
flags |= FF_TX_OUT_OF_PLACE;
- if (!scale && ((type == AV_TX_FLOAT_MDCT) || (type == AV_TX_INT32_MDCT)))
- scale = &default_scale_f;
- else if (!scale && (type == AV_TX_DOUBLE_MDCT))
+ if (!scale && ((type == AV_TX_DOUBLE_MDCT) || (type == AV_TX_DOUBLE_DCT) ||
+ (type == AV_TX_DOUBLE_DCT_I) || (type == AV_TX_DOUBLE_DST_I) ||
+ (type == AV_TX_DOUBLE_RDFT)))
scale = &default_scale_d;
+ else if (!scale && !TYPE_IS(FFT, type))
+ scale = &default_scale_f;
ret = ff_tx_init_subtx(&tmp, type, flags, NULL, len, inv, scale);
if (ret < 0)
diff --git a/media/ffvpx/libavutil/tx_template.c b/media/ffvpx/libavutil/tx_template.c
index a2c27465cb..701ef0d6de 100644
--- a/media/ffvpx/libavutil/tx_template.c
+++ b/media/ffvpx/libavutil/tx_template.c
@@ -24,6 +24,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "mem.h"
+
#define TABLE_DEF(name, size) \
DECLARE_ALIGNED(32, TXSample, TX_TAB(ff_tx_tab_ ##name))[size]
diff --git a/media/ffvpx/libavutil/version.h b/media/ffvpx/libavutil/version.h
index 772c4e209c..da1a833255 100644
--- a/media/ffvpx/libavutil/version.h
+++ b/media/ffvpx/libavutil/version.h
@@ -78,9 +78,9 @@
* @{
*/
-#define LIBAVUTIL_VERSION_MAJOR 58
-#define LIBAVUTIL_VERSION_MINOR 36
-#define LIBAVUTIL_VERSION_MICRO 101
+#define LIBAVUTIL_VERSION_MAJOR 59
+#define LIBAVUTIL_VERSION_MINOR 13
+#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \
@@ -105,20 +105,13 @@
* @{
*/
-#define FF_API_FIFO_PEEK2 (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_FIFO_OLD_API (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_OLD_CHANNEL_LAYOUT (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_AV_FOPEN_UTF8 (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_PKT_DURATION (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_REORDERED_OPAQUE (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_FRAME_PICTURE_NUMBER (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_HDR_VIVID_THREE_SPLINE (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_FRAME_PKT (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_INTERLACED_FRAME (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_FRAME_KEY (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_PALETTE_HAS_CHANGED (LIBAVUTIL_VERSION_MAJOR < 59)
-#define FF_API_VULKAN_CONTIGUOUS_MEMORY (LIBAVUTIL_VERSION_MAJOR < 59)
+#define FF_API_HDR_VIVID_THREE_SPLINE (LIBAVUTIL_VERSION_MAJOR < 60)
+#define FF_API_FRAME_PKT (LIBAVUTIL_VERSION_MAJOR < 60)
+#define FF_API_INTERLACED_FRAME (LIBAVUTIL_VERSION_MAJOR < 60)
+#define FF_API_FRAME_KEY (LIBAVUTIL_VERSION_MAJOR < 60)
+#define FF_API_PALETTE_HAS_CHANGED (LIBAVUTIL_VERSION_MAJOR < 60)
+#define FF_API_VULKAN_CONTIGUOUS_MEMORY (LIBAVUTIL_VERSION_MAJOR < 60)
+#define FF_API_H274_FILM_GRAIN_VCS (LIBAVUTIL_VERSION_MAJOR < 60)
/**
* @}
diff --git a/media/ffvpx/libavutil/x86/emms.h b/media/ffvpx/libavutil/x86/emms.h
deleted file mode 100644
index 8ceec110cf..0000000000
--- a/media/ffvpx/libavutil/x86/emms.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVUTIL_X86_EMMS_H
-#define AVUTIL_X86_EMMS_H
-
-#include "config.h"
-#include "libavutil/attributes.h"
-
-void avpriv_emms_asm(void);
-
-#if HAVE_MMX_INLINE
-#ifndef __MMX__
-#include "libavutil/cpu.h"
-#endif
-
-# define emms_c emms_c
-/**
- * Empty mmx state.
- * this must be called between any dsp function and float/double code.
- * for example sin(); dsp->idct_put(); emms_c(); cos()
- * Note, *alloc() and *free() also use float code in some libc implementations
- * thus this also applies to them or any function using them.
- */
-static av_always_inline void emms_c(void)
-{
-/* Some inlined functions may also use mmx instructions regardless of
- * runtime cpuflags. With that in mind, we unconditionally empty the
- * mmx state if the target cpu chosen at configure time supports it.
- */
-#if !defined(__MMX__)
- if(av_get_cpu_flags() & AV_CPU_FLAG_MMX)
-#endif
- __asm__ volatile ("emms" ::: "memory");
-}
-#elif HAVE_MMX && HAVE_MM_EMPTY
-# include <mmintrin.h>
-# define emms_c _mm_empty
-#elif HAVE_MMX_EXTERNAL
-# define emms_c avpriv_emms_asm
-#endif /* HAVE_MMX_INLINE */
-
-#endif /* AVUTIL_X86_EMMS_H */
diff --git a/media/ffvpx/libavutil/x86/fixed_dsp_init.c b/media/ffvpx/libavutil/x86/fixed_dsp_init.c
index d3f4b2e325..3dd508a4f4 100644
--- a/media/ffvpx/libavutil/x86/fixed_dsp_init.c
+++ b/media/ffvpx/libavutil/x86/fixed_dsp_init.c
@@ -16,14 +16,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "config.h"
-
#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
#include "libavutil/fixed_dsp.h"
#include "cpu.h"
-void ff_butterflies_fixed_sse2(int *av_restrict src0, int *av_restrict src1, int len);
+void ff_butterflies_fixed_sse2(int *restrict src0, int *restrict src1, int len);
av_cold void ff_fixed_dsp_init_x86(AVFixedDSPContext *fdsp)
{
diff --git a/media/ffvpx/libavutil/x86/float_dsp_init.c b/media/ffvpx/libavutil/x86/float_dsp_init.c
index ad6b506259..093bce9b94 100644
--- a/media/ffvpx/libavutil/x86/float_dsp_init.c
+++ b/media/ffvpx/libavutil/x86/float_dsp_init.c
@@ -16,13 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "config.h"
-
#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
#include "libavutil/float_dsp.h"
#include "cpu.h"
-#include "asm.h"
void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
int len);
@@ -76,7 +73,7 @@ void ff_vector_fmul_reverse_avx2(float *dst, const float *src0,
float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
float ff_scalarproduct_float_fma3(const float *v1, const float *v2, int order);
-void ff_butterflies_float_sse(float *av_restrict src0, float *av_restrict src1, int len);
+void ff_butterflies_float_sse(float *restrict src0, float *restrict src1, int len);
av_cold void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
{
diff --git a/media/ffvpx/libavutil/x86/intreadwrite.h b/media/ffvpx/libavutil/x86/intreadwrite.h
index 40f375b013..5e57d6a8cd 100644
--- a/media/ffvpx/libavutil/x86/intreadwrite.h
+++ b/media/ffvpx/libavutil/x86/intreadwrite.h
@@ -27,42 +27,6 @@
#if HAVE_MMX
-#if !HAVE_FAST_64BIT && defined(__MMX__)
-
-#define FF_COPY_SWAP_ZERO_USES_MMX
-
-#define AV_COPY64 AV_COPY64
-static av_always_inline void AV_COPY64(void *d, const void *s)
-{
- __asm__("movq %1, %%mm0 \n\t"
- "movq %%mm0, %0 \n\t"
- : "=m"(*(uint64_t*)d)
- : "m" (*(const uint64_t*)s)
- : "mm0");
-}
-
-#define AV_SWAP64 AV_SWAP64
-static av_always_inline void AV_SWAP64(void *a, void *b)
-{
- __asm__("movq %1, %%mm0 \n\t"
- "movq %0, %%mm1 \n\t"
- "movq %%mm0, %0 \n\t"
- "movq %%mm1, %1 \n\t"
- : "+m"(*(uint64_t*)a), "+m"(*(uint64_t*)b)
- ::"mm0", "mm1");
-}
-
-#define AV_ZERO64 AV_ZERO64
-static av_always_inline void AV_ZERO64(void *d)
-{
- __asm__("pxor %%mm0, %%mm0 \n\t"
- "movq %%mm0, %0 \n\t"
- : "=m"(*(uint64_t*)d)
- :: "mm0");
-}
-
-#endif /* !HAVE_FAST_64BIT && defined(__MMX__) */
-
#ifdef __SSE__
#define AV_COPY128 AV_COPY128
diff --git a/media/ffvpx/libavutil/x86/moz.build b/media/ffvpx/libavutil/x86/moz.build
index df33768f66..9a730c5746 100644
--- a/media/ffvpx/libavutil/x86/moz.build
+++ b/media/ffvpx/libavutil/x86/moz.build
@@ -16,6 +16,8 @@ SOURCES += [
'imgutils_init.c',
'lls.asm',
'lls_init.c',
+ 'pixelutils.asm',
+ 'pixelutils_init.c',
'tx_float.asm',
'tx_float_init.c',
]
diff --git a/media/ffvpx/libavutil/x86/tx_float.asm b/media/ffvpx/libavutil/x86/tx_float.asm
index e1533a8595..42006848f1 100644
--- a/media/ffvpx/libavutil/x86/tx_float.asm
+++ b/media/ffvpx/libavutil/x86/tx_float.asm
@@ -46,7 +46,7 @@
%endif
%assign i 16
-%rep 14
+%rep 18
cextern tab_ %+ i %+ _float ; ff_tab_i_float...
%assign i (i << 1)
%endrep
@@ -1385,7 +1385,11 @@ FFT_SPLIT_RADIX_DEF 8192, .16384pt
FFT_SPLIT_RADIX_DEF 16384, .32768pt
FFT_SPLIT_RADIX_DEF 32768, .65536pt
FFT_SPLIT_RADIX_DEF 65536, .131072pt
-FFT_SPLIT_RADIX_DEF 131072
+FFT_SPLIT_RADIX_DEF 131072, .262144pt
+FFT_SPLIT_RADIX_DEF 262144, .524288pt
+FFT_SPLIT_RADIX_DEF 524288, .1048576pt
+FFT_SPLIT_RADIX_DEF 1048576, .2097152pt
+FFT_SPLIT_RADIX_DEF 2097152
;===============================================================================
; Final synthesis + deinterleaving code
diff --git a/media/ffvpx/libavutil/x86/tx_float_init.c b/media/ffvpx/libavutil/x86/tx_float_init.c
index d3c0beb50f..36da9325e5 100644
--- a/media/ffvpx/libavutil/x86/tx_float_init.c
+++ b/media/ffvpx/libavutil/x86/tx_float_init.c
@@ -19,6 +19,7 @@
#define TX_FLOAT
#include "libavutil/tx_priv.h"
#include "libavutil/attributes.h"
+#include "libavutil/mem.h"
#include "libavutil/x86/cpu.h"
#include "config.h"
@@ -270,15 +271,15 @@ const FFTXCodelet * const ff_tx_codelet_list_float_x86[] = {
AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
TX_DEF(fft32_ns, FFT, 32, 32, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
AV_CPU_FLAG_AVXSLOW),
- TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 256, b8_i2, avx, AVX, 0, AV_CPU_FLAG_AVXSLOW),
- TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 320, b8_i2, avx, AVX,
+ TX_DEF(fft_sr, FFT, 64, 2097152, 2, 0, 256, b8_i2, avx, AVX, 0, AV_CPU_FLAG_AVXSLOW),
+ TX_DEF(fft_sr_asm, FFT, 64, 2097152, 2, 0, 320, b8_i2, avx, AVX,
AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
- TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 320, b8_i2, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
+ TX_DEF(fft_sr_ns, FFT, 64, 2097152, 2, 0, 320, b8_i2, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
AV_CPU_FLAG_AVXSLOW),
- TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 288, b8_i2, fma3, FMA3, 0, AV_CPU_FLAG_AVXSLOW),
- TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 352, b8_i2, fma3, FMA3,
+ TX_DEF(fft_sr, FFT, 64, 2097152, 2, 0, 288, b8_i2, fma3, FMA3, 0, AV_CPU_FLAG_AVXSLOW),
+ TX_DEF(fft_sr_asm, FFT, 64, 2097152, 2, 0, 352, b8_i2, fma3, FMA3,
AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
- TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
+ TX_DEF(fft_sr_ns, FFT, 64, 2097152, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
AV_CPU_FLAG_AVXSLOW),
#if HAVE_AVX2_EXTERNAL
@@ -287,11 +288,11 @@ const FFTXCodelet * const ff_tx_codelet_list_float_x86[] = {
TX_DEF(fft15_ns, FFT, 15, 15, 15, 0, 384, factor_init, avx2, AVX2,
AV_TX_INPLACE | FF_TX_PRESHUFFLE, AV_CPU_FLAG_AVXSLOW),
- TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 320, b8_i2, avx2, AVX2, 0,
+ TX_DEF(fft_sr, FFT, 64, 2097152, 2, 0, 320, b8_i2, avx2, AVX2, 0,
AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
- TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 384, b8_i2, avx2, AVX2,
+ TX_DEF(fft_sr_asm, FFT, 64, 2097152, 2, 0, 384, b8_i2, avx2, AVX2,
AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
- TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 384, b8_i2, avx2, AVX2, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
+ TX_DEF(fft_sr_ns, FFT, 64, 2097152, 2, 0, 384, b8_i2, avx2, AVX2, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
TX_DEF(fft_pfa_15xM, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 320, fft_pfa_init, avx2, AVX2,
diff --git a/media/ffvpx/libavutil/x86/x86inc.asm b/media/ffvpx/libavutil/x86/x86inc.asm
index e099ee4b10..e61d924bc1 100644
--- a/media/ffvpx/libavutil/x86/x86inc.asm
+++ b/media/ffvpx/libavutil/x86/x86inc.asm
@@ -1,7 +1,7 @@
;*****************************************************************************
-;* x86inc.asm: x264asm abstraction layer
+;* x86inc.asm: x86 abstraction layer
;*****************************************************************************
-;* Copyright (C) 2005-2018 x264 project
+;* Copyright (C) 2005-2024 x264 project
;*
;* Authors: Loren Merritt <lorenm@u.washington.edu>
;* Henrik Gramner <henrik@gramner.com>
@@ -21,21 +21,14 @@
;* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
;*****************************************************************************
-; This is a header file for the x264ASM assembly language, which uses
+; This is a header file for the x86inc.asm assembly language, which uses
; NASM/YASM syntax combined with a large number of macros to provide easy
; abstraction between different calling conventions (x86_32, win64, linux64).
; It also has various other useful features to simplify writing the kind of
-; DSP functions that are most often used in x264.
-
-; Unlike the rest of x264, this file is available under an ISC license, as it
-; has significant usefulness outside of x264 and we want it to be available
-; to the largest audience possible. Of course, if you modify it for your own
-; purposes to add a new feature, we strongly encourage contributing a patch
-; as this feature might be useful for others as well. Send patches or ideas
-; to x264-devel@videolan.org .
+; DSP functions that are most often used.
%ifndef private_prefix
- %define private_prefix x264
+ %error private_prefix not defined
%endif
%ifndef public_prefix
@@ -68,12 +61,19 @@
%endif
%define FORMAT_ELF 0
+%define FORMAT_MACHO 0
%ifidn __OUTPUT_FORMAT__,elf
%define FORMAT_ELF 1
%elifidn __OUTPUT_FORMAT__,elf32
%define FORMAT_ELF 1
%elifidn __OUTPUT_FORMAT__,elf64
%define FORMAT_ELF 1
+%elifidn __OUTPUT_FORMAT__,macho
+ %define FORMAT_MACHO 1
+%elifidn __OUTPUT_FORMAT__,macho32
+ %define FORMAT_MACHO 1
+%elifidn __OUTPUT_FORMAT__,macho64
+ %define FORMAT_MACHO 1
%endif
%ifdef PREFIX
@@ -82,6 +82,11 @@
%define mangle(x) x
%endif
+; Use VEX-encoding even in non-AVX functions
+%ifndef FORCE_VEX_ENCODING
+ %define FORCE_VEX_ENCODING 0
+%endif
+
; aout does not support align=
; NOTE: This section is out of sync with x264, in order to
; keep supporting OS/2.
@@ -99,28 +104,27 @@
%endif
%endmacro
-%if WIN64
- %define PIC
-%elif ARCH_X86_64 == 0
-; x86_32 doesn't require PIC.
-; Some distros prefer shared objects to be PIC, but nothing breaks if
-; the code contains a few textrels, so we'll skip that complexity.
- %undef PIC
-%endif
-%ifdef PIC
+%if ARCH_X86_64
+ %define PIC 1 ; always use PIC on x86-64
default rel
+%elifidn __OUTPUT_FORMAT__,win32
+ %define PIC 0 ; PIC isn't used on 32-bit Windows
+%elifndef PIC
+ %define PIC 0
%endif
-%macro CPUNOP 1
- %if HAVE_CPUNOP
- CPU %1
+%define HAVE_PRIVATE_EXTERN 1
+%ifdef __NASM_VERSION_ID__
+ %use smartalign
+ %if __NASM_VERSION_ID__ < 0x020e0000 ; 2.14
+ %define HAVE_PRIVATE_EXTERN 0
%endif
-%endmacro
+%endif
; Macros to eliminate most code duplication between x86_32 and x86_64:
; Currently this works only for leaf functions which load all their arguments
; into registers at the start, and make no other use of the stack. Luckily that
-; covers most of x264's asm.
+; covers most use cases.
; PROLOGUE:
; %1 = number of arguments. loads them from stack if needed.
@@ -232,6 +236,18 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%define gprsize 4
%endif
+%macro LEA 2
+%if ARCH_X86_64
+ lea %1, [%2]
+%elif PIC
+ call $+5 ; special-cased to not affect the RSB on most CPU:s
+ pop %1
+ add %1, (%2)-$+1
+%else
+ mov %1, %2
+%endif
+%endmacro
+
; Repeats an instruction/operation for multiple arguments.
; Example usage: "REPX {psrlw x, 8}, m0, m1, m2, m3"
%macro REPX 2-* ; operation, args
@@ -303,6 +319,10 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%endif
%endmacro
+%if ARCH_X86_64 == 0
+ %define movsxd movifnidn
+%endif
+
%macro movsxdifnidn 2
%ifnidn %1, %2
movsxd %1, %2
@@ -354,7 +374,46 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%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)
+; Large stack allocations on Windows need to use stack probing in order
+; to guarantee that all stack memory is committed before accessing it.
+; This is done by ensuring that the guard page(s) at the end of the
+; currently committed pages are touched prior to any pages beyond that.
+%if WIN64
+ %assign STACK_PROBE_SIZE 8192
+%elifidn __OUTPUT_FORMAT__, win32
+ %assign STACK_PROBE_SIZE 4096
+%else
+ %assign STACK_PROBE_SIZE 0
+%endif
+
+%macro PROBE_STACK 1 ; stack_size
+ %if STACK_PROBE_SIZE
+ %assign %%i STACK_PROBE_SIZE
+ %rep %1 / STACK_PROBE_SIZE
+ mov eax, [rsp-%%i]
+ %assign %%i %%i+STACK_PROBE_SIZE
+ %endrep
+ %endif
+%endmacro
+
+%macro RESET_STACK_STATE 0
+ %ifidn rstk, rsp
+ %assign stack_offset stack_offset - stack_size_padded
+ %else
+ %xdefine rstk rsp
+ %endif
+ %assign stack_size 0
+ %assign stack_size_padded 0
+ %assign xmm_regs_used 0
+%endmacro
+
+%macro ALLOC_STACK 0-2 0, 0 ; stack_size, n_xmm_regs
+ RESET_STACK_STATE
+ %ifnum %2
+ %if mmsize != 8
+ %assign xmm_regs_used %2
+ %endif
+ %endif
%ifnum %1
%if %1 != 0
%assign %%pad 0
@@ -364,16 +423,14 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%endif
%if WIN64
%assign %%pad %%pad + 32 ; shadow space
- %if mmsize != 8
- %assign xmm_regs_used %2
- %if xmm_regs_used > 8
- %assign %%pad %%pad + (xmm_regs_used-8)*16 ; callee-saved xmm registers
- %endif
+ %if xmm_regs_used > 8
+ %assign %%pad %%pad + (xmm_regs_used-8)*16 ; callee-saved xmm registers
%endif
%endif
%if required_stack_alignment <= STACK_ALIGNMENT
; maintain the current stack alignment
%assign stack_size_padded stack_size + %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1))
+ PROBE_STACK stack_size_padded
SUB rsp, stack_size_padded
%else
%assign %%reg_num (regs_used - 1)
@@ -389,6 +446,7 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%xdefine rstkm rstk
%endif
%assign stack_size_padded stack_size + ((%%pad + required_stack_alignment-1) & ~(required_stack_alignment-1))
+ PROBE_STACK stack_size_padded
mov rstk, rsp
and rsp, ~(required_stack_alignment-1)
sub rsp, stack_size_padded
@@ -399,7 +457,7 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%endif
%endmacro
-%macro SETUP_STACK_POINTER 1
+%macro SETUP_STACK_POINTER 0-1 0
%ifnum %1
%if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT
%if %1 > 0
@@ -462,35 +520,62 @@ DECLARE_REG 14, R13, 120
%endif
%endmacro
-%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 + high_mm_regs
- movaps [rstk + stack_offset + 8], xmm6
- %endif
- %if xmm_regs_used > 7 + high_mm_regs
- movaps [rstk + stack_offset + 24], xmm7
- %endif
- %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8
- %if %%xmm_regs_on_stack > 0
- %assign %%i 8
- %rep %%xmm_regs_on_stack
- movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i
- %assign %%i %%i+1
- %endrep
+; Push XMM registers to the stack. If no argument is specified all used register
+; will be pushed, otherwise only push previously unpushed registers.
+%macro WIN64_PUSH_XMM 0-2 ; new_xmm_regs_used, xmm_regs_pushed
+ %if mmsize != 8
+ %if %0 == 2
+ %assign %%pushed %2
+ %assign xmm_regs_used %1
+ %elif %0 == 1
+ %assign %%pushed xmm_regs_used
+ %assign xmm_regs_used %1
+ %else
+ %assign %%pushed 0
+ %endif
+ ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated.
+ %if %%pushed <= 6 + high_mm_regs && xmm_regs_used > 6 + high_mm_regs
+ movaps [rstk + stack_offset + 8], xmm6
+ %endif
+ %if %%pushed <= 7 + high_mm_regs && xmm_regs_used > 7 + high_mm_regs
+ movaps [rstk + stack_offset + 24], xmm7
+ %endif
+ %assign %%pushed %%pushed - high_mm_regs - 8
+ %if %%pushed < 0
+ %assign %%pushed 0
+ %endif
+ %assign %%regs_to_push xmm_regs_used - %%pushed - high_mm_regs - 8
+ %if %%regs_to_push > 0
+ ASSERT (%%regs_to_push + %%pushed) * 16 <= stack_size_padded - stack_size - 32
+ %assign %%i %%pushed + 8
+ %rep %%regs_to_push
+ movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i
+ %assign %%i %%i+1
+ %endrep
+ %endif
%endif
%endmacro
-%macro WIN64_SPILL_XMM 1
- %assign xmm_regs_used %1
- 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_on_stack*16 + 32
- %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1))
- SUB rsp, stack_size_padded
+; Allocated stack space for XMM registers and push all, or a subset, of those
+%macro WIN64_SPILL_XMM 1-2 ; xmm_regs_used, xmm_regs_reserved
+ RESET_STACK_STATE
+ %if mmsize != 8
+ %assign xmm_regs_used %1
+ ASSERT xmm_regs_used <= 16 + high_mm_regs
+ %if %0 == 2
+ ASSERT %2 >= %1
+ %assign %%xmm_regs_on_stack %2 - high_mm_regs - 8
+ %else
+ %assign %%xmm_regs_on_stack %1 - high_mm_regs - 8
+ %endif
+ %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_on_stack*16 + 32
+ %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1))
+ SUB rsp, stack_size_padded
+ %endif
+ WIN64_PUSH_XMM
%endif
- WIN64_PUSH_XMM
%endmacro
%macro WIN64_RESTORE_XMM_INTERNAL 0
@@ -521,9 +606,7 @@ DECLARE_REG 14, R13, 120
%macro WIN64_RESTORE_XMM 0
WIN64_RESTORE_XMM_INTERNAL
- %assign stack_offset (stack_offset-stack_size_padded)
- %assign stack_size_padded 0
- %assign xmm_regs_used 0
+ RESET_STACK_STATE
%endmacro
%define has_epilogue regs_used > 7 || stack_size > 0 || vzeroupper_required || xmm_regs_used > 6+high_mm_regs
@@ -558,12 +641,11 @@ DECLARE_REG 14, R13, 72
%macro PROLOGUE 2-5+ 0, 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
PUSH_IF_USED 9, 10, 11, 12, 13, 14
- ALLOC_STACK %4
+ ALLOC_STACK %4, %3
LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14
%if %0 > 4
%ifnum %4
@@ -627,7 +709,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
SETUP_STACK_POINTER %4
ASSERT regs_used <= 7
PUSH_IF_USED 3, 4, 5, 6
- ALLOC_STACK %4
+ ALLOC_STACK %4, %3
LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6
%if %0 > 4
%ifnum %4
@@ -660,11 +742,19 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
%endif ;======================================================================
%if WIN64 == 0
- %macro WIN64_SPILL_XMM 1
+ %macro WIN64_SPILL_XMM 1-2
+ RESET_STACK_STATE
+ %if mmsize != 8
+ %assign xmm_regs_used %1
+ %endif
%endmacro
%macro WIN64_RESTORE_XMM 0
+ RESET_STACK_STATE
%endmacro
- %macro WIN64_PUSH_XMM 0
+ %macro WIN64_PUSH_XMM 0-2
+ %if mmsize != 8 && %0 >= 1
+ %assign xmm_regs_used %1
+ %endif
%endmacro
%endif
@@ -705,7 +795,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, jna, jnae, jb, jbe, jnb, jnbe, jc, jnc, js, jns, jo, jno, jp, jnp
-%macro TAIL_CALL 2 ; callee, is_nonadjacent
+%macro TAIL_CALL 1-2 1 ; callee, is_nonadjacent
%if has_epilogue
call %1
RET
@@ -735,22 +825,25 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
%endmacro
%macro cglobal_internal 2-3+
annotate_function_size
- %if %1
- %xdefine %%FUNCTION_PREFIX private_prefix
- %xdefine %%VISIBILITY hidden
- %else
- %xdefine %%FUNCTION_PREFIX public_prefix
- %xdefine %%VISIBILITY
- %endif
%ifndef cglobaled_%2
- %xdefine %2 mangle(%%FUNCTION_PREFIX %+ _ %+ %2)
+ %if %1
+ %xdefine %2 mangle(private_prefix %+ _ %+ %2)
+ %else
+ %xdefine %2 mangle(public_prefix %+ _ %+ %2)
+ %endif
%xdefine %2.skip_prologue %2 %+ .skip_prologue
CAT_XDEFINE cglobaled_, %2, 1
%endif
%xdefine current_function %2
%xdefine current_function_section __SECT__
%if FORMAT_ELF
- global %2:function %%VISIBILITY
+ %if %1
+ global %2:function hidden
+ %else
+ global %2:function
+ %endif
+ %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN && %1
+ global %2:private_extern
%else
global %2
%endif
@@ -771,6 +864,8 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
%macro cglobal_label 1
%if FORMAT_ELF
global current_function %+ %1:function hidden
+ %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN
+ global current_function %+ %1:private_extern
%else
global current_function %+ %1
%endif
@@ -796,15 +891,34 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
%xdefine %1 mangle(private_prefix %+ _ %+ %1)
%if FORMAT_ELF
global %1:data hidden
+ %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN
+ global %1:private_extern
%else
global %1
%endif
%1: %2
%endmacro
-; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default.
%if FORMAT_ELF
+ ; The GNU linker assumes the stack is executable by default.
[SECTION .note.GNU-stack noalloc noexec nowrite progbits]
+
+ %ifdef __NASM_VERSION_ID__
+ %if __NASM_VERSION_ID__ >= 0x020e0300 ; 2.14.03
+ %if ARCH_X86_64
+ ; Control-flow Enforcement Technology (CET) properties.
+ [SECTION .note.gnu.property alloc noexec nowrite note align=gprsize]
+ dd 0x00000004 ; n_namesz
+ dd gprsize + 8 ; n_descsz
+ dd 0x00000005 ; n_type = NT_GNU_PROPERTY_TYPE_0
+ db "GNU",0 ; n_name
+ dd 0xc0000002 ; pr_type = GNU_PROPERTY_X86_FEATURE_1_AND
+ dd 0x00000004 ; pr_datasz
+ dd 0x00000002 ; pr_data = GNU_PROPERTY_X86_FEATURE_1_SHSTK
+ dd 0x00000000 ; pr_padding
+ %endif
+ %endif
+ %endif
%endif
; Tell debuggers how large the function was.
@@ -828,32 +942,34 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
; cpuflags
%assign cpuflags_mmx (1<<0)
-%assign cpuflags_mmx2 (1<<1) | cpuflags_mmx
-%assign cpuflags_3dnow (1<<2) | cpuflags_mmx
-%assign cpuflags_3dnowext (1<<3) | cpuflags_3dnow
-%assign cpuflags_sse (1<<4) | cpuflags_mmx2
-%assign cpuflags_sse2 (1<<5) | cpuflags_sse
-%assign cpuflags_sse2slow (1<<6) | cpuflags_sse2
-%assign cpuflags_lzcnt (1<<7) | cpuflags_sse2
-%assign cpuflags_sse3 (1<<8) | cpuflags_sse2
-%assign cpuflags_ssse3 (1<<9) | cpuflags_sse3
-%assign cpuflags_sse4 (1<<10)| cpuflags_ssse3
-%assign cpuflags_sse42 (1<<11)| cpuflags_sse4
-%assign cpuflags_aesni (1<<12)| cpuflags_sse42
-%assign cpuflags_avx (1<<13)| cpuflags_sse42
-%assign cpuflags_xop (1<<14)| cpuflags_avx
-%assign cpuflags_fma4 (1<<15)| cpuflags_avx
-%assign cpuflags_fma3 (1<<16)| cpuflags_avx
-%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_avx512icl (1<<25)| cpuflags_avx512
-
-%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)
+%assign cpuflags_mmx2 (1<<1) | cpuflags_mmx
+%assign cpuflags_3dnow (1<<2) | cpuflags_mmx
+%assign cpuflags_3dnowext (1<<3) | cpuflags_3dnow
+%assign cpuflags_sse (1<<4) | cpuflags_mmx2
+%assign cpuflags_sse2 (1<<5) | cpuflags_sse
+%assign cpuflags_sse2slow (1<<6) | cpuflags_sse2
+%assign cpuflags_lzcnt (1<<7) | cpuflags_sse2
+%assign cpuflags_sse3 (1<<8) | cpuflags_sse2
+%assign cpuflags_ssse3 (1<<9) | cpuflags_sse3
+%assign cpuflags_sse4 (1<<10) | cpuflags_ssse3
+%assign cpuflags_sse42 (1<<11) | cpuflags_sse4
+%assign cpuflags_aesni (1<<12) | cpuflags_sse42
+%assign cpuflags_clmul (1<<13) | cpuflags_sse42
+%assign cpuflags_gfni (1<<14) | cpuflags_aesni|cpuflags_clmul
+%assign cpuflags_avx (1<<15) | cpuflags_sse42
+%assign cpuflags_xop (1<<16) | cpuflags_avx
+%assign cpuflags_fma4 (1<<17) | cpuflags_avx
+%assign cpuflags_fma3 (1<<18) | cpuflags_avx
+%assign cpuflags_bmi1 (1<<19) | cpuflags_avx|cpuflags_lzcnt
+%assign cpuflags_bmi2 (1<<20) | cpuflags_bmi1
+%assign cpuflags_avx2 (1<<21) | cpuflags_fma3|cpuflags_bmi2
+%assign cpuflags_avx512 (1<<22) | cpuflags_avx2 ; F, CD, BW, DQ, VL
+%assign cpuflags_avx512icl (1<<23) | cpuflags_avx512|cpuflags_gfni ; VNNI, IFMA, VBMI, VBMI2, VPOPCNTDQ, BITALG, VAES, VPCLMULQDQ
+
+%assign cpuflags_cache32 (1<<24)
+%assign cpuflags_cache64 (1<<25)
+%assign cpuflags_aligned (1<<26) ; not a cpu feature, but a function variant
+%assign cpuflags_atom (1<<27)
; Returns a boolean value expressing whether or not the specified cpuflag is enabled.
%define cpuflag(x) (((((cpuflags & (cpuflags_ %+ x)) ^ (cpuflags_ %+ x)) - 1) >> 31) & 1)
@@ -895,9 +1011,17 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
%endif
%if ARCH_X86_64 || cpuflag(sse2)
- CPUNOP amdnop
+ %ifdef __NASM_VERSION_ID__
+ ALIGNMODE p6
+ %else
+ CPU amdnop
+ %endif
%else
- CPUNOP basicnop
+ %ifdef __NASM_VERSION_ID__
+ ALIGNMODE nop
+ %else
+ CPU basicnop
+ %endif
%endif
%endmacro
@@ -971,7 +1095,7 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
%endmacro
%macro INIT_XMM 0-1+
- %assign avx_enabled 0
+ %assign avx_enabled FORCE_VEX_ENCODING
%define RESET_MM_PERMUTATION INIT_XMM %1
%define mmsize 16
%define mova movdqa
@@ -983,6 +1107,9 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
%if WIN64
AVX512_MM_PERMUTATION 6 ; Swap callee-saved registers with volatile registers
%endif
+ %xdefine bcstw 1to8
+ %xdefine bcstd 1to4
+ %xdefine bcstq 1to2
%endmacro
%macro INIT_YMM 0-1+
@@ -996,6 +1123,9 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
INIT_CPUFLAGS %1
DEFINE_MMREGS ymm
AVX512_MM_PERMUTATION
+ %xdefine bcstw 1to16
+ %xdefine bcstd 1to8
+ %xdefine bcstq 1to4
%endmacro
%macro INIT_ZMM 0-1+
@@ -1009,6 +1139,9 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
INIT_CPUFLAGS %1
DEFINE_MMREGS zmm
AVX512_MM_PERMUTATION
+ %xdefine bcstw 1to32
+ %xdefine bcstd 1to16
+ %xdefine bcstq 1to8
%endmacro
INIT_XMM
@@ -1106,19 +1239,32 @@ INIT_XMM
%endif
%assign %%i 0
%rep num_mmregs
- CAT_XDEFINE %%f, %%i, m %+ %%i
+ %xdefine %%tmp m %+ %%i
+ CAT_XDEFINE %%f, %%i, regnumof %+ %%tmp
%assign %%i %%i+1
%endrep
%endmacro
-%macro LOAD_MM_PERMUTATION 1 ; name to load from
- %ifdef %1_m0
+%macro LOAD_MM_PERMUTATION 0-1 ; name to load from
+ %if %0
+ %xdefine %%f %1_m
+ %else
+ %xdefine %%f current_function %+ _m
+ %endif
+ %xdefine %%tmp %%f %+ 0
+ %ifnum %%tmp
+ DEFINE_MMREGS mmtype
%assign %%i 0
%rep num_mmregs
- CAT_XDEFINE m, %%i, %1_m %+ %%i
- CAT_XDEFINE nn, m %+ %%i, %%i
+ %xdefine %%tmp %%f %+ %%i
+ CAT_XDEFINE %%m, %%i, m %+ %%tmp
%assign %%i %%i+1
%endrep
+ %rep num_mmregs
+ %assign %%i %%i-1
+ CAT_XDEFINE m, %%i, %%m %+ %%i
+ CAT_XDEFINE nn, m %+ %%i, %%i
+ %endrep
%endif
%endmacro
@@ -1224,8 +1370,22 @@ INIT_XMM
%ifdef cpuname
%if notcpuflag(%2)
%error use of ``%1'' %2 instruction in cpuname function: current_function
- %elif cpuflags_%2 < cpuflags_sse && notcpuflag(sse2) && __sizeofreg > 8
+ %elif %3 == 0 && __sizeofreg == 16 && notcpuflag(sse2)
%error use of ``%1'' sse2 instruction in cpuname function: current_function
+ %elif %3 == 0 && __sizeofreg == 32 && notcpuflag(avx2)
+ %error use of ``%1'' avx2 instruction in cpuname function: current_function
+ %elif __sizeofreg == 16 && notcpuflag(sse)
+ %error use of ``%1'' sse instruction in cpuname function: current_function
+ %elif __sizeofreg == 32 && notcpuflag(avx)
+ %error use of ``%1'' avx instruction in cpuname function: current_function
+ %elif __sizeofreg == 64 && notcpuflag(avx512)
+ %error use of ``%1'' avx512 instruction in cpuname function: current_function
+ %elifidn %1, pextrw ; special case because the base instruction is mmx2,
+ %ifnid %6 ; but sse4 is required for memory operands
+ %if notcpuflag(sse4)
+ %error use of ``%1'' sse4 instruction in cpuname function: current_function
+ %endif
+ %endif
%endif
%endif
%endif
@@ -1267,11 +1427,79 @@ INIT_XMM
%1 %6, __src2
%endif
%elif %0 >= 9
- __instr %6, %7, %8, %9
+ %if avx_enabled && __sizeofreg >= 16 && %4 == 1
+ %ifnnum regnumof%7
+ %if %3
+ vmovaps %6, %7
+ %else
+ vmovdqa %6, %7
+ %endif
+ __instr %6, %6, %8, %9
+ %else
+ __instr %6, %7, %8, %9
+ %endif
+ %else
+ __instr %6, %7, %8, %9
+ %endif
%elif %0 == 8
- __instr %6, %7, %8
+ %if avx_enabled && __sizeofreg >= 16 && %4 == 0
+ %xdefine __src1 %7
+ %xdefine __src2 %8
+ %if %5
+ %ifnum regnumof%7
+ %ifnum regnumof%8
+ %if regnumof%7 < 8 && regnumof%8 >= 8 && regnumof%8 < 16 && sizeof%8 <= 32
+ ; Most VEX-encoded instructions require an additional byte to encode when
+ ; src2 is a high register (e.g. m8..15). If the instruction is commutative
+ ; we can swap src1 and src2 when doing so reduces the instruction length.
+ %xdefine __src1 %8
+ %xdefine __src2 %7
+ %endif
+ %endif
+ %elifnum regnumof%8 ; put memory operands in src2 when possible
+ %xdefine __src1 %8
+ %xdefine __src2 %7
+ %else
+ %assign __emulate_avx 1
+ %endif
+ %elifnnum regnumof%7
+ ; EVEX allows imm8 shift instructions to be used with memory operands,
+ ; but VEX does not. This handles those special cases.
+ %ifnnum %8
+ %assign __emulate_avx 1
+ %elif notcpuflag(avx512)
+ %assign __emulate_avx 1
+ %endif
+ %endif
+ %if __emulate_avx ; a separate load is required
+ %if %3
+ vmovaps %6, %7
+ %else
+ vmovdqa %6, %7
+ %endif
+ __instr %6, %6, %8
+ %else
+ __instr %6, __src1, __src2
+ %endif
+ %else
+ __instr %6, %7, %8
+ %endif
%elif %0 == 7
- __instr %6, %7
+ %if avx_enabled && __sizeofreg >= 16 && %5
+ %xdefine __src1 %6
+ %xdefine __src2 %7
+ %ifnum regnumof%6
+ %ifnum regnumof%7
+ %if regnumof%6 < 8 && regnumof%7 >= 8 && regnumof%7 < 16 && sizeof%7 <= 32
+ %xdefine __src1 %7
+ %xdefine __src2 %6
+ %endif
+ %endif
+ %endif
+ __instr %6, __src1, __src2
+ %else
+ __instr %6, %7
+ %endif
%else
__instr %6
%endif
@@ -1318,8 +1546,8 @@ AVX_INSTR andpd, sse2, 1, 0, 1
AVX_INSTR andps, sse, 1, 0, 1
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 blendvpd, sse4, 1, 1, 0 ; last operand must be xmm0 with legacy encoding
+AVX_INSTR blendvps, sse4, 1, 1, 0 ; last operand must be xmm0 with legacy encoding
AVX_INSTR cmpeqpd, sse2, 1, 0, 1
AVX_INSTR cmpeqps, sse, 1, 0, 1
AVX_INSTR cmpeqsd, sse2, 1, 0, 0
@@ -1356,38 +1584,41 @@ 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
-AVX_INSTR cvtdq2ps, sse2
-AVX_INSTR cvtpd2dq, sse2
-AVX_INSTR cvtpd2ps, sse2
-AVX_INSTR cvtps2dq, sse2
-AVX_INSTR cvtps2pd, sse2
-AVX_INSTR cvtsd2si, sse2
+AVX_INSTR comisd, sse2, 1
+AVX_INSTR comiss, sse, 1
+AVX_INSTR cvtdq2pd, sse2, 1
+AVX_INSTR cvtdq2ps, sse2, 1
+AVX_INSTR cvtpd2dq, sse2, 1
+AVX_INSTR cvtpd2ps, sse2, 1
+AVX_INSTR cvtps2dq, sse2, 1
+AVX_INSTR cvtps2pd, sse2, 1
+AVX_INSTR cvtsd2si, sse2, 1
AVX_INSTR cvtsd2ss, sse2, 1, 0, 0
AVX_INSTR cvtsi2sd, sse2, 1, 0, 0
AVX_INSTR cvtsi2ss, sse, 1, 0, 0
AVX_INSTR cvtss2sd, sse2, 1, 0, 0
-AVX_INSTR cvtss2si, sse
-AVX_INSTR cvttpd2dq, sse2
-AVX_INSTR cvttps2dq, sse2
-AVX_INSTR cvttsd2si, sse2
-AVX_INSTR cvttss2si, sse
+AVX_INSTR cvtss2si, sse, 1
+AVX_INSTR cvttpd2dq, sse2, 1
+AVX_INSTR cvttps2dq, sse2, 1
+AVX_INSTR cvttsd2si, sse2, 1
+AVX_INSTR cvttss2si, sse, 1
AVX_INSTR divpd, sse2, 1, 0, 0
AVX_INSTR divps, sse, 1, 0, 0
AVX_INSTR divsd, sse2, 1, 0, 0
AVX_INSTR divss, sse, 1, 0, 0
AVX_INSTR dppd, sse4, 1, 1, 0
AVX_INSTR dpps, sse4, 1, 1, 0
-AVX_INSTR extractps, sse4
+AVX_INSTR extractps, sse4, 1
+AVX_INSTR gf2p8affineinvqb, gfni, 0, 1, 0
+AVX_INSTR gf2p8affineqb, gfni, 0, 1, 0
+AVX_INSTR gf2p8mulb, gfni, 0, 0, 0
AVX_INSTR haddpd, sse3, 1, 0, 0
AVX_INSTR haddps, sse3, 1, 0, 0
AVX_INSTR hsubpd, sse3, 1, 0, 0
AVX_INSTR hsubps, sse3, 1, 0, 0
AVX_INSTR insertps, sse4, 1, 1, 0
AVX_INSTR lddqu, sse3
-AVX_INSTR ldmxcsr, sse
+AVX_INSTR ldmxcsr, sse, 1
AVX_INSTR maskmovdqu, sse2
AVX_INSTR maxpd, sse2, 1, 0, 1
AVX_INSTR maxps, sse, 1, 0, 1
@@ -1397,10 +1628,10 @@ AVX_INSTR minpd, sse2, 1, 0, 1
AVX_INSTR minps, sse, 1, 0, 1
AVX_INSTR minsd, sse2, 1, 0, 0
AVX_INSTR minss, sse, 1, 0, 0
-AVX_INSTR movapd, sse2
-AVX_INSTR movaps, sse
+AVX_INSTR movapd, sse2, 1
+AVX_INSTR movaps, sse, 1
AVX_INSTR movd, mmx
-AVX_INSTR movddup, sse3
+AVX_INSTR movddup, sse3, 1
AVX_INSTR movdqa, sse2
AVX_INSTR movdqu, sse2
AVX_INSTR movhlps, sse, 1, 0, 0
@@ -1409,19 +1640,19 @@ AVX_INSTR movhps, sse, 1, 0, 0
AVX_INSTR movlhps, sse, 1, 0, 0
AVX_INSTR movlpd, sse2, 1, 0, 0
AVX_INSTR movlps, sse, 1, 0, 0
-AVX_INSTR movmskpd, sse2
-AVX_INSTR movmskps, sse
+AVX_INSTR movmskpd, sse2, 1
+AVX_INSTR movmskps, sse, 1
AVX_INSTR movntdq, sse2
AVX_INSTR movntdqa, sse4
-AVX_INSTR movntpd, sse2
-AVX_INSTR movntps, sse
+AVX_INSTR movntpd, sse2, 1
+AVX_INSTR movntps, sse, 1
AVX_INSTR movq, mmx
AVX_INSTR movsd, sse2, 1, 0, 0
-AVX_INSTR movshdup, sse3
-AVX_INSTR movsldup, sse3
+AVX_INSTR movshdup, sse3, 1
+AVX_INSTR movsldup, sse3, 1
AVX_INSTR movss, sse, 1, 0, 0
-AVX_INSTR movupd, sse2
-AVX_INSTR movups, sse
+AVX_INSTR movupd, sse2, 1
+AVX_INSTR movups, sse, 1
AVX_INSTR mpsadbw, sse4, 0, 1, 0
AVX_INSTR mulpd, sse2, 1, 0, 1
AVX_INSTR mulps, sse, 1, 0, 1
@@ -1432,90 +1663,90 @@ AVX_INSTR orps, sse, 1, 0, 1
AVX_INSTR pabsb, ssse3
AVX_INSTR pabsd, ssse3
AVX_INSTR pabsw, ssse3
-AVX_INSTR packsswb, mmx, 0, 0, 0
AVX_INSTR packssdw, mmx, 0, 0, 0
-AVX_INSTR packuswb, mmx, 0, 0, 0
+AVX_INSTR packsswb, mmx, 0, 0, 0
AVX_INSTR packusdw, sse4, 0, 0, 0
+AVX_INSTR packuswb, mmx, 0, 0, 0
AVX_INSTR paddb, mmx, 0, 0, 1
-AVX_INSTR paddw, mmx, 0, 0, 1
AVX_INSTR paddd, mmx, 0, 0, 1
AVX_INSTR paddq, sse2, 0, 0, 1
AVX_INSTR paddsb, mmx, 0, 0, 1
AVX_INSTR paddsw, mmx, 0, 0, 1
AVX_INSTR paddusb, mmx, 0, 0, 1
AVX_INSTR paddusw, mmx, 0, 0, 1
+AVX_INSTR paddw, mmx, 0, 0, 1
AVX_INSTR palignr, ssse3, 0, 1, 0
AVX_INSTR pand, mmx, 0, 0, 1
AVX_INSTR pandn, mmx, 0, 0, 0
AVX_INSTR pavgb, mmx2, 0, 0, 1
AVX_INSTR pavgw, mmx2, 0, 0, 1
-AVX_INSTR pblendvb, sse4 ; can't be emulated
+AVX_INSTR pblendvb, sse4, 0, 1, 0 ; last operand must be xmm0 with legacy encoding
AVX_INSTR pblendw, sse4, 0, 1, 0
-AVX_INSTR pclmulqdq, fnord, 0, 1, 0
-AVX_INSTR pclmulhqhqdq, fnord, 0, 0, 0
-AVX_INSTR pclmulhqlqdq, fnord, 0, 0, 0
-AVX_INSTR pclmullqhqdq, fnord, 0, 0, 0
-AVX_INSTR pclmullqlqdq, fnord, 0, 0, 0
-AVX_INSTR pcmpestri, sse42
-AVX_INSTR pcmpestrm, sse42
-AVX_INSTR pcmpistri, sse42
-AVX_INSTR pcmpistrm, sse42
+AVX_INSTR pclmulhqhqdq, clmul, 0, 0, 0
+AVX_INSTR pclmulhqlqdq, clmul, 0, 0, 0
+AVX_INSTR pclmullqhqdq, clmul, 0, 0, 0
+AVX_INSTR pclmullqlqdq, clmul, 0, 0, 0
+AVX_INSTR pclmulqdq, clmul, 0, 1, 0
AVX_INSTR pcmpeqb, mmx, 0, 0, 1
-AVX_INSTR pcmpeqw, mmx, 0, 0, 1
AVX_INSTR pcmpeqd, mmx, 0, 0, 1
AVX_INSTR pcmpeqq, sse4, 0, 0, 1
+AVX_INSTR pcmpeqw, mmx, 0, 0, 1
+AVX_INSTR pcmpestri, sse42
+AVX_INSTR pcmpestrm, sse42
AVX_INSTR pcmpgtb, mmx, 0, 0, 0
-AVX_INSTR pcmpgtw, mmx, 0, 0, 0
AVX_INSTR pcmpgtd, mmx, 0, 0, 0
AVX_INSTR pcmpgtq, sse42, 0, 0, 0
+AVX_INSTR pcmpgtw, mmx, 0, 0, 0
+AVX_INSTR pcmpistri, sse42
+AVX_INSTR pcmpistrm, sse42
AVX_INSTR pextrb, sse4
AVX_INSTR pextrd, sse4
AVX_INSTR pextrq, sse4
AVX_INSTR pextrw, mmx2
-AVX_INSTR phaddw, ssse3, 0, 0, 0
AVX_INSTR phaddd, ssse3, 0, 0, 0
AVX_INSTR phaddsw, ssse3, 0, 0, 0
+AVX_INSTR phaddw, ssse3, 0, 0, 0
AVX_INSTR phminposuw, sse4
-AVX_INSTR phsubw, ssse3, 0, 0, 0
AVX_INSTR phsubd, ssse3, 0, 0, 0
AVX_INSTR phsubsw, ssse3, 0, 0, 0
+AVX_INSTR phsubw, ssse3, 0, 0, 0
AVX_INSTR pinsrb, sse4, 0, 1, 0
AVX_INSTR pinsrd, sse4, 0, 1, 0
AVX_INSTR pinsrq, sse4, 0, 1, 0
AVX_INSTR pinsrw, mmx2, 0, 1, 0
-AVX_INSTR pmaddwd, mmx, 0, 0, 1
AVX_INSTR pmaddubsw, ssse3, 0, 0, 0
+AVX_INSTR pmaddwd, mmx, 0, 0, 1
AVX_INSTR pmaxsb, sse4, 0, 0, 1
-AVX_INSTR pmaxsw, mmx2, 0, 0, 1
AVX_INSTR pmaxsd, sse4, 0, 0, 1
+AVX_INSTR pmaxsw, mmx2, 0, 0, 1
AVX_INSTR pmaxub, mmx2, 0, 0, 1
-AVX_INSTR pmaxuw, sse4, 0, 0, 1
AVX_INSTR pmaxud, sse4, 0, 0, 1
+AVX_INSTR pmaxuw, sse4, 0, 0, 1
AVX_INSTR pminsb, sse4, 0, 0, 1
-AVX_INSTR pminsw, mmx2, 0, 0, 1
AVX_INSTR pminsd, sse4, 0, 0, 1
+AVX_INSTR pminsw, mmx2, 0, 0, 1
AVX_INSTR pminub, mmx2, 0, 0, 1
-AVX_INSTR pminuw, sse4, 0, 0, 1
AVX_INSTR pminud, sse4, 0, 0, 1
+AVX_INSTR pminuw, sse4, 0, 0, 1
AVX_INSTR pmovmskb, mmx2
-AVX_INSTR pmovsxbw, sse4
AVX_INSTR pmovsxbd, sse4
AVX_INSTR pmovsxbq, sse4
+AVX_INSTR pmovsxbw, sse4
+AVX_INSTR pmovsxdq, sse4
AVX_INSTR pmovsxwd, sse4
AVX_INSTR pmovsxwq, sse4
-AVX_INSTR pmovsxdq, sse4
-AVX_INSTR pmovzxbw, sse4
AVX_INSTR pmovzxbd, sse4
AVX_INSTR pmovzxbq, sse4
+AVX_INSTR pmovzxbw, sse4
+AVX_INSTR pmovzxdq, sse4
AVX_INSTR pmovzxwd, sse4
AVX_INSTR pmovzxwq, sse4
-AVX_INSTR pmovzxdq, sse4
AVX_INSTR pmuldq, sse4, 0, 0, 1
AVX_INSTR pmulhrsw, ssse3, 0, 0, 1
AVX_INSTR pmulhuw, mmx2, 0, 0, 1
AVX_INSTR pmulhw, mmx, 0, 0, 1
-AVX_INSTR pmullw, mmx, 0, 0, 1
AVX_INSTR pmulld, sse4, 0, 0, 1
+AVX_INSTR pmullw, mmx, 0, 0, 1
AVX_INSTR pmuludq, sse2, 0, 0, 1
AVX_INSTR por, mmx, 0, 0, 1
AVX_INSTR psadbw, mmx2, 0, 0, 1
@@ -1524,57 +1755,57 @@ AVX_INSTR pshufd, sse2
AVX_INSTR pshufhw, sse2
AVX_INSTR pshuflw, sse2
AVX_INSTR psignb, ssse3, 0, 0, 0
-AVX_INSTR psignw, ssse3, 0, 0, 0
AVX_INSTR psignd, ssse3, 0, 0, 0
-AVX_INSTR psllw, mmx, 0, 0, 0
+AVX_INSTR psignw, ssse3, 0, 0, 0
AVX_INSTR pslld, mmx, 0, 0, 0
-AVX_INSTR psllq, mmx, 0, 0, 0
AVX_INSTR pslldq, sse2, 0, 0, 0
-AVX_INSTR psraw, mmx, 0, 0, 0
+AVX_INSTR psllq, mmx, 0, 0, 0
+AVX_INSTR psllw, mmx, 0, 0, 0
AVX_INSTR psrad, mmx, 0, 0, 0
-AVX_INSTR psrlw, mmx, 0, 0, 0
+AVX_INSTR psraw, mmx, 0, 0, 0
AVX_INSTR psrld, mmx, 0, 0, 0
-AVX_INSTR psrlq, mmx, 0, 0, 0
AVX_INSTR psrldq, sse2, 0, 0, 0
+AVX_INSTR psrlq, mmx, 0, 0, 0
+AVX_INSTR psrlw, mmx, 0, 0, 0
AVX_INSTR psubb, mmx, 0, 0, 0
-AVX_INSTR psubw, mmx, 0, 0, 0
AVX_INSTR psubd, mmx, 0, 0, 0
AVX_INSTR psubq, sse2, 0, 0, 0
AVX_INSTR psubsb, mmx, 0, 0, 0
AVX_INSTR psubsw, mmx, 0, 0, 0
AVX_INSTR psubusb, mmx, 0, 0, 0
AVX_INSTR psubusw, mmx, 0, 0, 0
+AVX_INSTR psubw, mmx, 0, 0, 0
AVX_INSTR ptest, sse4
AVX_INSTR punpckhbw, mmx, 0, 0, 0
-AVX_INSTR punpckhwd, mmx, 0, 0, 0
AVX_INSTR punpckhdq, mmx, 0, 0, 0
AVX_INSTR punpckhqdq, sse2, 0, 0, 0
+AVX_INSTR punpckhwd, mmx, 0, 0, 0
AVX_INSTR punpcklbw, mmx, 0, 0, 0
-AVX_INSTR punpcklwd, mmx, 0, 0, 0
AVX_INSTR punpckldq, mmx, 0, 0, 0
AVX_INSTR punpcklqdq, sse2, 0, 0, 0
+AVX_INSTR punpcklwd, mmx, 0, 0, 0
AVX_INSTR pxor, mmx, 0, 0, 1
-AVX_INSTR rcpps, sse
+AVX_INSTR rcpps, sse, 1
AVX_INSTR rcpss, sse, 1, 0, 0
-AVX_INSTR roundpd, sse4
-AVX_INSTR roundps, sse4
+AVX_INSTR roundpd, sse4, 1
+AVX_INSTR roundps, sse4, 1
AVX_INSTR roundsd, sse4, 1, 1, 0
AVX_INSTR roundss, sse4, 1, 1, 0
-AVX_INSTR rsqrtps, sse
+AVX_INSTR rsqrtps, sse, 1
AVX_INSTR rsqrtss, sse, 1, 0, 0
AVX_INSTR shufpd, sse2, 1, 1, 0
AVX_INSTR shufps, sse, 1, 1, 0
-AVX_INSTR sqrtpd, sse2
-AVX_INSTR sqrtps, sse
+AVX_INSTR sqrtpd, sse2, 1
+AVX_INSTR sqrtps, sse, 1
AVX_INSTR sqrtsd, sse2, 1, 0, 0
AVX_INSTR sqrtss, sse, 1, 0, 0
-AVX_INSTR stmxcsr, sse
+AVX_INSTR stmxcsr, sse, 1
AVX_INSTR subpd, sse2, 1, 0, 0
AVX_INSTR subps, sse, 1, 0, 0
AVX_INSTR subsd, sse2, 1, 0, 0
AVX_INSTR subss, sse, 1, 0, 0
-AVX_INSTR ucomisd, sse2
-AVX_INSTR ucomiss, sse
+AVX_INSTR ucomisd, sse2, 1
+AVX_INSTR ucomiss, sse, 1
AVX_INSTR unpckhpd, sse2, 1, 0, 0
AVX_INSTR unpckhps, sse, 1, 0, 0
AVX_INSTR unpcklpd, sse2, 1, 0, 0
@@ -1584,8 +1815,41 @@ AVX_INSTR xorps, sse, 1, 0, 1
; 3DNow instructions, for sharing code between AVX, SSE and 3DN
AVX_INSTR pfadd, 3dnow, 1, 0, 1
-AVX_INSTR pfsub, 3dnow, 1, 0, 0
AVX_INSTR pfmul, 3dnow, 1, 0, 1
+AVX_INSTR pfsub, 3dnow, 1, 0, 0
+
+;%1 == instruction
+;%2 == minimal instruction set
+%macro GPR_INSTR 2
+ %macro %1 2-5 fnord, %1, %2
+ %ifdef cpuname
+ %if notcpuflag(%5)
+ %error use of ``%4'' %5 instruction in cpuname function: current_function
+ %endif
+ %endif
+ %ifidn %3, fnord
+ %4 %1, %2
+ %else
+ %4 %1, %2, %3
+ %endif
+ %endmacro
+%endmacro
+
+GPR_INSTR andn, bmi1
+GPR_INSTR bextr, bmi1
+GPR_INSTR blsi, bmi1
+GPR_INSTR blsmsk, bmi1
+GPR_INSTR blsr, bmi1
+GPR_INSTR bzhi, bmi2
+GPR_INSTR crc32, sse42
+GPR_INSTR mulx, bmi2
+GPR_INSTR pdep, bmi2
+GPR_INSTR pext, bmi2
+GPR_INSTR popcnt, sse42
+GPR_INSTR rorx, bmi2
+GPR_INSTR sarx, bmi2
+GPR_INSTR shlx, bmi2
+GPR_INSTR shrx, bmi2
; base-4 constants for shuffles
%assign i 0
@@ -1618,15 +1882,11 @@ AVX_INSTR pfmul, 3dnow, 1, 0, 1
%endmacro
%endmacro
-FMA_INSTR pmacsww, pmullw, paddw
-FMA_INSTR pmacsdd, pmulld, paddd ; sse4 emulation
-FMA_INSTR pmacsdql, pmuldq, paddq ; sse4 emulation
+FMA_INSTR pmacsdd, pmulld, paddd ; sse4 emulation
+FMA_INSTR pmacsdql, pmuldq, paddq ; sse4 emulation
+FMA_INSTR pmacsww, pmullw, paddw
FMA_INSTR pmadcswd, pmaddwd, paddd
-; tzcnt is equivalent to "rep bsf" and is backwards-compatible with bsf.
-; This lets us use tzcnt without bumping the yasm version requirement yet.
-%define tzcnt rep bsf
-
; Macros for consolidating FMA3 and FMA4 using 4-operand (dst, src1, src2, src3) syntax.
; FMA3 is only possible if dst is the same as one of the src registers.
; Either src2 or src3 can be a memory operand.
@@ -1687,6 +1947,11 @@ FMA4_INSTR fnmsub, pd, ps, sd, ss
%assign %%evex_required 1
%endif
%endif
+ %ifnum regnumof%3
+ %if regnumof%3 >= 16 || sizeof%3 > 32
+ %assign %%evex_required 1
+ %endif
+ %endif
%if %%evex_required
%6 %%args
%else
@@ -1711,16 +1976,3 @@ 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
- %macro vpbroadcastq 2
- %if sizeof%1 == 16
- movddup %1, %2
- %else
- vbroadcastsd %1, %2
- %endif
- %endmacro
- %endif
-%endif
diff --git a/media/ffvpx/libavutil/x86/x86util.asm b/media/ffvpx/libavutil/x86/x86util.asm
index d7cd996842..836f6afcb8 100644
--- a/media/ffvpx/libavutil/x86/x86util.asm
+++ b/media/ffvpx/libavutil/x86/x86util.asm
@@ -802,10 +802,6 @@
%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