Bug 1652958 Update bundled libavutil library to 4.4.1 r=alwu

Depends on D133420

Differential Revision: https://phabricator.services.mozilla.com/D133421
This commit is contained in:
stransky 2021-12-24 19:41:35 +00:00
Родитель 853405776c
Коммит c9604382fa
64 изменённых файлов: 2131 добавлений и 514 удалений

Просмотреть файл

@ -32,6 +32,10 @@
# define FUNC # # define FUNC #
#endif #endif
#ifndef __has_feature
# define __has_feature(x) 0
#endif
.macro function name, export=0, align=2 .macro function name, export=0, align=2
.macro endfunc .macro endfunc
ELF .size \name, . - \name ELF .size \name, . - \name
@ -63,6 +67,8 @@ ELF .size \name, . - \name
.else .else
.section .rodata .section .rodata
.endif .endif
#elif defined(_WIN32)
.section .rdata
#elif !defined(__MACH__) #elif !defined(__MACH__)
.section .rodata .section .rodata
#else #else
@ -92,7 +98,11 @@ ELF .size \name, . - \name
add \rd, \rd, :lo12:\val+(\offset) add \rd, \rd, :lo12:\val+(\offset)
.endif .endif
#elif CONFIG_PIC #elif CONFIG_PIC
# if __has_feature(hwaddress_sanitizer)
adrp \rd, :pg_hi21_nc:\val+(\offset)
# else
adrp \rd, \val+(\offset) adrp \rd, \val+(\offset)
# endif
add \rd, \rd, :lo12:\val+(\offset) add \rd, \rd, :lo12:\val+(\offset)
#else #else
ldr \rd, =\val+\offset ldr \rd, =\val+\offset
@ -102,3 +112,6 @@ ELF .size \name, . - \name
#define GLUE(a, b) a ## b #define GLUE(a, b) a ## b
#define JOIN(a, b) GLUE(a, b) #define JOIN(a, b) GLUE(a, b)
#define X(s) JOIN(EXTERN_ASM, s) #define X(s) JOIN(EXTERN_ASM, s)
#define x18 do_not_use_x18
#define w18 do_not_use_w18

Просмотреть файл

@ -24,7 +24,13 @@
#include <stdint.h> #include <stdint.h>
#include "config.h" #include "config.h"
#if HAVE_INLINE_ASM #if defined(__APPLE__)
#include <mach/mach_time.h>
#define AV_READ_TIME mach_absolute_time
#elif HAVE_INLINE_ASM
#define AV_READ_TIME read_time #define AV_READ_TIME read_time

Просмотреть файл

@ -41,8 +41,12 @@
#define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf); #define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf);
#define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf); #define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf);
#if FF_API_CRYPTO_SIZE_T
unsigned long av_adler32_update(unsigned long adler, const uint8_t * buf, unsigned long av_adler32_update(unsigned long adler, const uint8_t * buf,
unsigned int len) unsigned int len)
#else
AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len)
#endif
{ {
unsigned long s1 = adler & 0xffff; unsigned long s1 = adler & 0xffff;
unsigned long s2 = adler >> 16; unsigned long s2 = adler >> 16;

Просмотреть файл

@ -27,8 +27,10 @@
#ifndef AVUTIL_ADLER32_H #ifndef AVUTIL_ADLER32_H
#define AVUTIL_ADLER32_H #define AVUTIL_ADLER32_H
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "attributes.h" #include "attributes.h"
#include "version.h"
/** /**
* @defgroup lavu_adler32 Adler-32 * @defgroup lavu_adler32 Adler-32
@ -38,6 +40,12 @@
* @{ * @{
*/ */
#if FF_API_CRYPTO_SIZE_T
typedef unsigned long AVAdler;
#else
typedef uint32_t AVAdler;
#endif
/** /**
* Calculate the Adler32 checksum of a buffer. * Calculate the Adler32 checksum of a buffer.
* *
@ -50,8 +58,12 @@
* @param len size of input buffer * @param len size of input buffer
* @return updated checksum * @return updated checksum
*/ */
unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf,
unsigned int len) av_pure; #if FF_API_CRYPTO_SIZE_T
unsigned int len) av_pure;
#else
size_t len) av_pure;
#endif
/** /**
* @} * @}

Просмотреть файл

@ -24,7 +24,13 @@
#include <stdint.h> #include <stdint.h>
#include "config.h" #include "config.h"
#if HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__) #if defined(__APPLE__)
#include <mach/mach_time.h>
#define AV_READ_TIME mach_absolute_time
#elif HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__)
#define AV_READ_TIME read_time #define AV_READ_TIME read_time

Просмотреть файл

@ -34,6 +34,12 @@
# define AV_GCC_VERSION_AT_MOST(x,y) 0 # define AV_GCC_VERSION_AT_MOST(x,y) 0
#endif #endif
#ifdef __has_builtin
# define AV_HAS_BUILTIN(x) __has_builtin(x)
#else
# define AV_HAS_BUILTIN(x) 0
#endif
#ifndef av_always_inline #ifndef av_always_inline
#if AV_GCC_VERSION_AT_LEAST(3,1) #if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_always_inline __attribute__((always_inline)) inline # define av_always_inline __attribute__((always_inline)) inline

Просмотреть файл

@ -136,6 +136,7 @@ end:
return p; return p;
} }
#if FF_API_D2STR
char *av_d2str(double d) char *av_d2str(double d)
{ {
char *str = av_malloc(16); char *str = av_malloc(16);
@ -143,6 +144,7 @@ char *av_d2str(double d)
snprintf(str, 16, "%f", d); snprintf(str, 16, "%f", d);
return str; return str;
} }
#endif
#define WHITESPACES " \n\t\r" #define WHITESPACES " \n\t\r"
@ -257,12 +259,18 @@ char *av_strireplace(const char *str, const char *from, const char *to)
const char *av_basename(const char *path) const char *av_basename(const char *path)
{ {
char *p = strrchr(path, '/'); char *p;
#if HAVE_DOS_PATHS #if HAVE_DOS_PATHS
char *q = strrchr(path, '\\'); char *q, *d;
char *d = strchr(path, ':'); #endif
if (!path || *path == '\0')
return ".";
p = strrchr(path, '/');
#if HAVE_DOS_PATHS
q = strrchr(path, '\\');
d = strchr(path, ':');
p = FFMAX3(p, q, d); p = FFMAX3(p, q, d);
#endif #endif
@ -274,11 +282,11 @@ const char *av_basename(const char *path)
const char *av_dirname(char *path) const char *av_dirname(char *path)
{ {
char *p = strrchr(path, '/'); char *p = path ? strrchr(path, '/') : NULL;
#if HAVE_DOS_PATHS #if HAVE_DOS_PATHS
char *q = strrchr(path, '\\'); char *q = path ? strrchr(path, '\\') : NULL;
char *d = strchr(path, ':'); char *d = path ? strchr(path, ':') : NULL;
d = d ? d + 1 : d; d = d ? d + 1 : d;
@ -328,17 +336,18 @@ int av_escape(char **dst, const char *src, const char *special_chars,
enum AVEscapeMode mode, int flags) enum AVEscapeMode mode, int flags)
{ {
AVBPrint dstbuf; AVBPrint dstbuf;
int ret;
av_bprint_init(&dstbuf, 1, AV_BPRINT_SIZE_UNLIMITED); av_bprint_init(&dstbuf, 1, INT_MAX); /* (int)dstbuf.len must be >= 0 */
av_bprint_escape(&dstbuf, src, special_chars, mode, flags); av_bprint_escape(&dstbuf, src, special_chars, mode, flags);
if (!av_bprint_is_complete(&dstbuf)) { if (!av_bprint_is_complete(&dstbuf)) {
av_bprint_finalize(&dstbuf, NULL); av_bprint_finalize(&dstbuf, NULL);
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} else {
av_bprint_finalize(&dstbuf, dst);
return dstbuf.len;
} }
if ((ret = av_bprint_finalize(&dstbuf, dst)) < 0)
return ret;
return dstbuf.len;
} }
int av_match_name(const char *name, const char *names) int av_match_name(const char *name, const char *names)

Просмотреть файл

@ -24,6 +24,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "attributes.h" #include "attributes.h"
#include "version.h"
/** /**
* @addtogroup lavu_string * @addtogroup lavu_string
@ -155,10 +156,14 @@ static inline size_t av_strnlen(const char *s, size_t len)
*/ */
char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2); char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2);
#if FF_API_D2STR
/** /**
* Convert a number to an av_malloced string. * Convert a number to an av_malloced string.
* @deprecated use av_asprintf() with "%f" or a more specific format
*/ */
attribute_deprecated
char *av_d2str(double d); char *av_d2str(double d);
#endif
/** /**
* Unescape the given string until a non escaped terminating char, * Unescape the given string until a non escaped terminating char,
@ -274,16 +279,21 @@ char *av_strireplace(const char *str, const char *from, const char *to);
/** /**
* Thread safe basename. * Thread safe basename.
* @param path the path, on DOS both \ and / are considered separators. * @param path the string to parse, on DOS both \ and / are considered separators.
* @return pointer to the basename substring. * @return pointer to the basename substring.
* If path does not contain a slash, the function returns a copy of path.
* If path is a NULL pointer or points to an empty string, a pointer
* to a string "." is returned.
*/ */
const char *av_basename(const char *path); const char *av_basename(const char *path);
/** /**
* Thread safe dirname. * Thread safe dirname.
* @param path the path, on DOS both \ and / are considered separators. * @param path the string to parse, on DOS both \ and / are considered separators.
* @return the path with the separator replaced by the string terminator or ".". * @return A pointer to a string that's the parent directory of path.
* @note the function may change the input string. * If path is a NULL pointer or points to an empty string, a pointer
* to a string "." is returned.
* @note the function may modify the contents of the path, so copies should be passed.
*/ */
const char *av_dirname(char *path); const char *av_dirname(char *path);
@ -314,6 +324,7 @@ enum AVEscapeMode {
AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode. AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode.
AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping. AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping.
AV_ESCAPE_MODE_QUOTE, ///< Use single-quote escaping. AV_ESCAPE_MODE_QUOTE, ///< Use single-quote escaping.
AV_ESCAPE_MODE_XML, ///< Use XML non-markup character data escaping.
}; };
/** /**
@ -333,6 +344,19 @@ enum AVEscapeMode {
*/ */
#define AV_ESCAPE_FLAG_STRICT (1 << 1) #define AV_ESCAPE_FLAG_STRICT (1 << 1)
/**
* Within AV_ESCAPE_MODE_XML, additionally escape single quotes for single
* quoted attributes.
*/
#define AV_ESCAPE_FLAG_XML_SINGLE_QUOTES (1 << 2)
/**
* Within AV_ESCAPE_MODE_XML, additionally escape double quotes for double
* quoted attributes.
*/
#define AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES (1 << 3)
/** /**
* Escape string in src, and put the escaped string in an allocated * Escape string in src, and put the escaped string in an allocated
* string in *dst, which must be freed with av_free(). * string in *dst, which must be freed with av_free().

Просмотреть файл

@ -26,6 +26,7 @@ av_buffer_pool_get
av_buffer_pool_init av_buffer_pool_init
av_buffer_pool_uninit av_buffer_pool_uninit
av_buffer_realloc av_buffer_realloc
av_buffer_replace
av_buffer_ref av_buffer_ref
av_buffer_unref av_buffer_unref
av_calloc av_calloc
@ -81,6 +82,9 @@ av_fifo_space
av_find_best_pix_fmt_of_2 av_find_best_pix_fmt_of_2
av_find_info_tag av_find_info_tag
av_find_nearest_q_idx av_find_nearest_q_idx
#ifndef MOZ_FFVPX_AUDIOONLY
av_film_grain_params_create_side_data
#endif
av_force_cpu_flags av_force_cpu_flags
av_fourcc_make_string av_fourcc_make_string
av_frame_alloc av_frame_alloc
@ -173,6 +177,7 @@ av_image_fill_arrays
av_image_fill_linesizes av_image_fill_linesizes
av_image_fill_max_pixsteps av_image_fill_max_pixsteps
av_image_fill_pointers av_image_fill_pointers
av_image_fill_plane_sizes
av_image_get_buffer_size av_image_get_buffer_size
av_image_get_linesize av_image_get_linesize
av_int_list_length_for_size av_int_list_length_for_size
@ -303,6 +308,9 @@ av_utf8_decode
av_util_ffversion av_util_ffversion
av_vbprintf av_vbprintf
av_version_info av_version_info
#ifndef MOZ_FFVPX_AUDIOONLY
av_video_enc_params_create_side_data
#endif
av_vlog av_vlog
av_write_image_line av_write_image_line
avpriv_alloc_fixed_dsp avpriv_alloc_fixed_dsp

Просмотреть файл

@ -79,12 +79,16 @@ static const uint8_t map2[256] =
int av_base64_decode(uint8_t *out, const char *in_str, int out_size) int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
{ {
uint8_t *dst = out; uint8_t *dst = out;
uint8_t *end = out + out_size; uint8_t *end;
// no sign extension // no sign extension
const uint8_t *in = in_str; const uint8_t *in = in_str;
unsigned bits = 0xff; unsigned bits = 0xff;
unsigned v; unsigned v;
if (!out)
goto validity_check;
end = out + out_size;
while (end - dst > 3) { while (end - dst > 3) {
BASE64_DEC_STEP(0); BASE64_DEC_STEP(0);
BASE64_DEC_STEP(1); BASE64_DEC_STEP(1);
@ -108,6 +112,7 @@ int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
*dst++ = v; *dst++ = v;
in += 4; in += 4;
} }
validity_check:
while (1) { while (1) {
BASE64_DEC_STEP(0); BASE64_DEC_STEP(0);
in++; in++;
@ -126,7 +131,7 @@ out2:
*dst++ = v >> 4; *dst++ = v >> 4;
out1: out1:
out0: out0:
return bits & 1 ? AVERROR_INVALIDDATA : dst - out; return bits & 1 ? AVERROR_INVALIDDATA : out ? dst - out : 0;
} }
/***************************************************************************** /*****************************************************************************

Просмотреть файл

@ -283,6 +283,35 @@ void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_cha
av_bprint_chars(dstbuf, '\'', 1); av_bprint_chars(dstbuf, '\'', 1);
break; break;
case AV_ESCAPE_MODE_XML:
/* escape XML non-markup character data as per 2.4 by default: */
/* [^<&]* - ([^<&]* ']]>' [^<&]*) */
/* additionally, given one of the AV_ESCAPE_FLAG_XML_* flags, */
/* escape those specific characters as required. */
for (; *src; src++) {
switch (*src) {
case '&' : av_bprintf(dstbuf, "%s", "&amp;"); break;
case '<' : av_bprintf(dstbuf, "%s", "&lt;"); break;
case '>' : av_bprintf(dstbuf, "%s", "&gt;"); break;
case '\'':
if (!(flags & AV_ESCAPE_FLAG_XML_SINGLE_QUOTES))
goto XML_DEFAULT_HANDLING;
av_bprintf(dstbuf, "%s", "&apos;");
break;
case '"' :
if (!(flags & AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES))
goto XML_DEFAULT_HANDLING;
av_bprintf(dstbuf, "%s", "&quot;");
break;
XML_DEFAULT_HANDLING:
default: av_bprint_chars(dstbuf, *src, 1);
}
}
break;
/* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */ /* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */
default: default:
/* \-escape characters */ /* \-escape characters */

Просмотреть файл

@ -20,12 +20,13 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "avassert.h"
#include "buffer_internal.h" #include "buffer_internal.h"
#include "common.h" #include "common.h"
#include "mem.h" #include "mem.h"
#include "thread.h" #include "thread.h"
AVBufferRef *av_buffer_create(uint8_t *data, int size, AVBufferRef *av_buffer_create(uint8_t *data, buffer_size_t size,
void (*free)(void *opaque, uint8_t *data), void (*free)(void *opaque, uint8_t *data),
void *opaque, int flags) void *opaque, int flags)
{ {
@ -43,8 +44,7 @@ AVBufferRef *av_buffer_create(uint8_t *data, int size,
atomic_init(&buf->refcount, 1); atomic_init(&buf->refcount, 1);
if (flags & AV_BUFFER_FLAG_READONLY) buf->flags = flags;
buf->flags |= BUFFER_FLAG_READONLY;
ref = av_mallocz(sizeof(*ref)); ref = av_mallocz(sizeof(*ref));
if (!ref) { if (!ref) {
@ -64,7 +64,7 @@ void av_buffer_default_free(void *opaque, uint8_t *data)
av_free(data); av_free(data);
} }
AVBufferRef *av_buffer_alloc(int size) AVBufferRef *av_buffer_alloc(buffer_size_t size)
{ {
AVBufferRef *ret = NULL; AVBufferRef *ret = NULL;
uint8_t *data = NULL; uint8_t *data = NULL;
@ -80,7 +80,7 @@ AVBufferRef *av_buffer_alloc(int size)
return ret; return ret;
} }
AVBufferRef *av_buffer_allocz(int size) AVBufferRef *av_buffer_allocz(buffer_size_t size)
{ {
AVBufferRef *ret = av_buffer_alloc(size); AVBufferRef *ret = av_buffer_alloc(size);
if (!ret) if (!ret)
@ -116,7 +116,7 @@ static void buffer_replace(AVBufferRef **dst, AVBufferRef **src)
} else } else
av_freep(dst); av_freep(dst);
if (atomic_fetch_add_explicit(&b->refcount, -1, memory_order_acq_rel) == 1) { if (atomic_fetch_sub_explicit(&b->refcount, 1, memory_order_acq_rel) == 1) {
b->free(b->opaque, b->data); b->free(b->opaque, b->data);
av_freep(&b); av_freep(&b);
} }
@ -166,10 +166,11 @@ int av_buffer_make_writable(AVBufferRef **pbuf)
return 0; return 0;
} }
int av_buffer_realloc(AVBufferRef **pbuf, int size) int av_buffer_realloc(AVBufferRef **pbuf, buffer_size_t size)
{ {
AVBufferRef *buf = *pbuf; AVBufferRef *buf = *pbuf;
uint8_t *tmp; uint8_t *tmp;
int ret;
if (!buf) { if (!buf) {
/* allocate a new buffer with av_realloc(), so it will be reallocatable /* allocate a new buffer with av_realloc(), so it will be reallocatable
@ -184,21 +185,21 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
buf->buffer->flags |= BUFFER_FLAG_REALLOCATABLE; buf->buffer->flags_internal |= BUFFER_FLAG_REALLOCATABLE;
*pbuf = buf; *pbuf = buf;
return 0; return 0;
} else if (buf->size == size) } else if (buf->size == size)
return 0; return 0;
if (!(buf->buffer->flags & BUFFER_FLAG_REALLOCATABLE) || if (!(buf->buffer->flags_internal & BUFFER_FLAG_REALLOCATABLE) ||
!av_buffer_is_writable(buf) || buf->data != buf->buffer->data) { !av_buffer_is_writable(buf) || buf->data != buf->buffer->data) {
/* cannot realloc, allocate a new reallocable buffer and copy data */ /* cannot realloc, allocate a new reallocable buffer and copy data */
AVBufferRef *new = NULL; AVBufferRef *new = NULL;
av_buffer_realloc(&new, size); ret = av_buffer_realloc(&new, size);
if (!new) if (ret < 0)
return AVERROR(ENOMEM); return ret;
memcpy(new->data, buf->data, FFMIN(size, buf->size)); memcpy(new->data, buf->data, FFMIN(size, buf->size));
@ -215,8 +216,34 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size)
return 0; return 0;
} }
AVBufferPool *av_buffer_pool_init2(int size, void *opaque, int av_buffer_replace(AVBufferRef **pdst, AVBufferRef *src)
AVBufferRef* (*alloc)(void *opaque, int size), {
AVBufferRef *dst = *pdst;
AVBufferRef *tmp;
if (!src) {
av_buffer_unref(pdst);
return 0;
}
if (dst && dst->buffer == src->buffer) {
/* make sure the data pointers match */
dst->data = src->data;
dst->size = src->size;
return 0;
}
tmp = av_buffer_ref(src);
if (!tmp)
return AVERROR(ENOMEM);
av_buffer_unref(pdst);
*pdst = tmp;
return 0;
}
AVBufferPool *av_buffer_pool_init2(buffer_size_t size, void *opaque,
AVBufferRef* (*alloc)(void *opaque, buffer_size_t size),
void (*pool_free)(void *opaque)) void (*pool_free)(void *opaque))
{ {
AVBufferPool *pool = av_mallocz(sizeof(*pool)); AVBufferPool *pool = av_mallocz(sizeof(*pool));
@ -228,6 +255,7 @@ AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
pool->size = size; pool->size = size;
pool->opaque = opaque; pool->opaque = opaque;
pool->alloc2 = alloc; pool->alloc2 = alloc;
pool->alloc = av_buffer_alloc; // fallback
pool->pool_free = pool_free; pool->pool_free = pool_free;
atomic_init(&pool->refcount, 1); atomic_init(&pool->refcount, 1);
@ -235,7 +263,7 @@ AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
return pool; return pool;
} }
AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)) AVBufferPool *av_buffer_pool_init(buffer_size_t size, AVBufferRef* (*alloc)(buffer_size_t size))
{ {
AVBufferPool *pool = av_mallocz(sizeof(*pool)); AVBufferPool *pool = av_mallocz(sizeof(*pool));
if (!pool) if (!pool)
@ -251,11 +279,7 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size))
return pool; return pool;
} }
/* static void buffer_pool_flush(AVBufferPool *pool)
* This function gets called when the pool has been uninited and
* all the buffers returned to it.
*/
static void buffer_pool_free(AVBufferPool *pool)
{ {
while (pool->pool) { while (pool->pool) {
BufferPoolEntry *buf = pool->pool; BufferPoolEntry *buf = pool->pool;
@ -264,6 +288,15 @@ static void buffer_pool_free(AVBufferPool *pool)
buf->free(buf->opaque, buf->data); buf->free(buf->opaque, buf->data);
av_freep(&buf); av_freep(&buf);
} }
}
/*
* This function gets called when the pool has been uninited and
* all the buffers returned to it.
*/
static void buffer_pool_free(AVBufferPool *pool)
{
buffer_pool_flush(pool);
ff_mutex_destroy(&pool->mutex); ff_mutex_destroy(&pool->mutex);
if (pool->pool_free) if (pool->pool_free)
@ -281,7 +314,11 @@ void av_buffer_pool_uninit(AVBufferPool **ppool)
pool = *ppool; pool = *ppool;
*ppool = NULL; *ppool = NULL;
if (atomic_fetch_add_explicit(&pool->refcount, -1, memory_order_acq_rel) == 1) ff_mutex_lock(&pool->mutex);
buffer_pool_flush(pool);
ff_mutex_unlock(&pool->mutex);
if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1)
buffer_pool_free(pool); buffer_pool_free(pool);
} }
@ -298,7 +335,7 @@ static void pool_release_buffer(void *opaque, uint8_t *data)
pool->pool = buf; pool->pool = buf;
ff_mutex_unlock(&pool->mutex); ff_mutex_unlock(&pool->mutex);
if (atomic_fetch_add_explicit(&pool->refcount, -1, memory_order_acq_rel) == 1) if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1)
buffer_pool_free(pool); buffer_pool_free(pool);
} }
@ -309,6 +346,8 @@ static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool)
BufferPoolEntry *buf; BufferPoolEntry *buf;
AVBufferRef *ret; AVBufferRef *ret;
av_assert0(pool->alloc || pool->alloc2);
ret = pool->alloc2 ? pool->alloc2(pool->opaque, pool->size) : ret = pool->alloc2 ? pool->alloc2(pool->opaque, pool->size) :
pool->alloc(pool->size); pool->alloc(pool->size);
if (!ret) if (!ret)
@ -355,3 +394,10 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool)
return ret; return ret;
} }
void *av_buffer_pool_buffer_get_opaque(AVBufferRef *ref)
{
BufferPoolEntry *buf = ref->buffer->opaque;
av_assert0(buf);
return buf->opaque;
}

Просмотреть файл

@ -25,8 +25,11 @@
#ifndef AVUTIL_BUFFER_H #ifndef AVUTIL_BUFFER_H
#define AVUTIL_BUFFER_H #define AVUTIL_BUFFER_H
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "version.h"
/** /**
* @defgroup lavu_buffer AVBuffer * @defgroup lavu_buffer AVBuffer
* @ingroup lavu_data * @ingroup lavu_data
@ -90,7 +93,11 @@ typedef struct AVBufferRef {
/** /**
* Size of data in bytes. * Size of data in bytes.
*/ */
#if FF_API_BUFFER_SIZE_T
int size; int size;
#else
size_t size;
#endif
} AVBufferRef; } AVBufferRef;
/** /**
@ -98,13 +105,21 @@ typedef struct AVBufferRef {
* *
* @return an AVBufferRef of given size or NULL when out of memory * @return an AVBufferRef of given size or NULL when out of memory
*/ */
#if FF_API_BUFFER_SIZE_T
AVBufferRef *av_buffer_alloc(int size); AVBufferRef *av_buffer_alloc(int size);
#else
AVBufferRef *av_buffer_alloc(size_t size);
#endif
/** /**
* Same as av_buffer_alloc(), except the returned buffer will be initialized * Same as av_buffer_alloc(), except the returned buffer will be initialized
* to zero. * to zero.
*/ */
#if FF_API_BUFFER_SIZE_T
AVBufferRef *av_buffer_allocz(int size); AVBufferRef *av_buffer_allocz(int size);
#else
AVBufferRef *av_buffer_allocz(size_t size);
#endif
/** /**
* Always treat the buffer as read-only, even when it has only one * Always treat the buffer as read-only, even when it has only one
@ -127,7 +142,11 @@ AVBufferRef *av_buffer_allocz(int size);
* *
* @return an AVBufferRef referring to data on success, NULL on failure. * @return an AVBufferRef referring to data on success, NULL on failure.
*/ */
#if FF_API_BUFFER_SIZE_T
AVBufferRef *av_buffer_create(uint8_t *data, int size, AVBufferRef *av_buffer_create(uint8_t *data, int size,
#else
AVBufferRef *av_buffer_create(uint8_t *data, size_t size,
#endif
void (*free)(void *opaque, uint8_t *data), void (*free)(void *opaque, uint8_t *data),
void *opaque, int flags); void *opaque, int flags);
@ -195,7 +214,27 @@ int av_buffer_make_writable(AVBufferRef **buf);
* reference to it (i.e. the one passed to this function). In all other cases * reference to it (i.e. the one passed to this function). In all other cases
* a new buffer is allocated and the data is copied. * a new buffer is allocated and the data is copied.
*/ */
#if FF_API_BUFFER_SIZE_T
int av_buffer_realloc(AVBufferRef **buf, int size); int av_buffer_realloc(AVBufferRef **buf, int size);
#else
int av_buffer_realloc(AVBufferRef **buf, size_t size);
#endif
/**
* Ensure dst refers to the same data as src.
*
* When *dst is already equivalent to src, do nothing. Otherwise unreference dst
* and replace it with a new reference to src.
*
* @param dst Pointer to either a valid buffer reference or NULL. On success,
* this will point to a buffer reference equivalent to src. On
* failure, dst will be left untouched.
* @param src A buffer reference to replace dst with. May be NULL, then this
* function is equivalent to av_buffer_unref(dst).
* @return 0 on success
* AVERROR(ENOMEM) on memory allocation failure.
*/
int av_buffer_replace(AVBufferRef **dst, AVBufferRef *src);
/** /**
* @} * @}
@ -246,7 +285,11 @@ typedef struct AVBufferPool AVBufferPool;
* (av_buffer_alloc()). * (av_buffer_alloc()).
* @return newly created buffer pool on success, NULL on error. * @return newly created buffer pool on success, NULL on error.
*/ */
#if FF_API_BUFFER_SIZE_T
AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)); AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size));
#else
AVBufferPool *av_buffer_pool_init(size_t size, AVBufferRef* (*alloc)(size_t size));
#endif
/** /**
* Allocate and initialize a buffer pool with a more complex allocator. * Allocate and initialize a buffer pool with a more complex allocator.
@ -254,16 +297,22 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size));
* @param size size of each buffer in this pool * @param size size of each buffer in this pool
* @param opaque arbitrary user data used by the allocator * @param opaque arbitrary user data used by the allocator
* @param alloc a function that will be used to allocate new buffers when the * @param alloc a function that will be used to allocate new buffers when the
* pool is empty. * pool is empty. May be NULL, then the default allocator will be
* used (av_buffer_alloc()).
* @param pool_free a function that will be called immediately before the pool * @param pool_free a function that will be called immediately before the pool
* is freed. I.e. after av_buffer_pool_uninit() is called * is freed. I.e. after av_buffer_pool_uninit() is called
* by the caller and all the frames are returned to the pool * by the caller and all the frames are returned to the pool
* and freed. It is intended to uninitialize the user opaque * and freed. It is intended to uninitialize the user opaque
* data. * data. May be NULL.
* @return newly created buffer pool on success, NULL on error. * @return newly created buffer pool on success, NULL on error.
*/ */
#if FF_API_BUFFER_SIZE_T
AVBufferPool *av_buffer_pool_init2(int size, void *opaque, AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
AVBufferRef* (*alloc)(void *opaque, int size), AVBufferRef* (*alloc)(void *opaque, int size),
#else
AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque,
AVBufferRef* (*alloc)(void *opaque, size_t size),
#endif
void (*pool_free)(void *opaque)); void (*pool_free)(void *opaque));
/** /**
@ -284,6 +333,19 @@ void av_buffer_pool_uninit(AVBufferPool **pool);
*/ */
AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); AVBufferRef *av_buffer_pool_get(AVBufferPool *pool);
/**
* Query the original opaque parameter of an allocated buffer in the pool.
*
* @param ref a buffer reference to a buffer returned by av_buffer_pool_get.
* @return the opaque parameter set by the buffer allocator function of the
* buffer pool.
*
* @note the opaque parameter of ref is used by the buffer pool implementation,
* therefore you have to use this function to access the original opaque
* parameter of an allocated buffer.
*/
void *av_buffer_pool_buffer_get_opaque(AVBufferRef *ref);
/** /**
* @} * @}
*/ */

Просмотреть файл

@ -22,21 +22,18 @@
#include <stdatomic.h> #include <stdatomic.h>
#include <stdint.h> #include <stdint.h>
#include "internal.h"
#include "buffer.h" #include "buffer.h"
#include "thread.h" #include "thread.h"
/**
* The buffer is always treated as read-only.
*/
#define BUFFER_FLAG_READONLY (1 << 0)
/** /**
* The buffer was av_realloc()ed, so it is reallocatable. * The buffer was av_realloc()ed, so it is reallocatable.
*/ */
#define BUFFER_FLAG_REALLOCATABLE (1 << 1) #define BUFFER_FLAG_REALLOCATABLE (1 << 0)
struct AVBuffer { struct AVBuffer {
uint8_t *data; /**< data described by this buffer */ uint8_t *data; /**< data described by this buffer */
int size; /**< size of data in bytes */ buffer_size_t size; /**< size of data in bytes */
/** /**
* number of existing AVBufferRef instances referring to this buffer * number of existing AVBufferRef instances referring to this buffer
@ -54,9 +51,14 @@ struct AVBuffer {
void *opaque; void *opaque;
/** /**
* A combination of BUFFER_FLAG_* * A combination of AV_BUFFER_FLAG_*
*/ */
int flags; int flags;
/**
* A combination of BUFFER_FLAG_*
*/
int flags_internal;
}; };
typedef struct BufferPoolEntry { typedef struct BufferPoolEntry {
@ -88,10 +90,10 @@ struct AVBufferPool {
*/ */
atomic_uint refcount; atomic_uint refcount;
int size; buffer_size_t size;
void *opaque; void *opaque;
AVBufferRef* (*alloc)(int size); AVBufferRef* (*alloc)(buffer_size_t size);
AVBufferRef* (*alloc2)(void *opaque, int size); AVBufferRef* (*alloc2)(void *opaque, buffer_size_t size);
void (*pool_free)(void *opaque); void (*pool_free)(void *opaque);
}; };

Просмотреть файл

@ -62,6 +62,11 @@ static const struct channel_name channel_names[] = {
[33] = { "SDL", "surround direct left" }, [33] = { "SDL", "surround direct left" },
[34] = { "SDR", "surround direct right" }, [34] = { "SDR", "surround direct right" },
[35] = { "LFE2", "low frequency 2" }, [35] = { "LFE2", "low frequency 2" },
[36] = { "TSL", "top side left" },
[37] = { "TSR", "top side right" },
[38] = { "BFC", "bottom front center" },
[39] = { "BFL", "bottom front left" },
[40] = { "BFR", "bottom front right" },
}; };
static const char *get_channel_name(int channel_id) static const char *get_channel_name(int channel_id)
@ -104,6 +109,7 @@ static const struct {
{ "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL }, { "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL },
{ "hexadecagonal", 16, AV_CH_LAYOUT_HEXADECAGONAL }, { "hexadecagonal", 16, AV_CH_LAYOUT_HEXADECAGONAL },
{ "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, }, { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, },
{ "22.2", 24, AV_CH_LAYOUT_22POINT2, },
}; };
static uint64_t get_channel_layout_single(const char *name, int name_len) static uint64_t get_channel_layout_single(const char *name, int name_len)

Просмотреть файл

@ -71,6 +71,11 @@
#define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL #define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL
#define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL #define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL
#define AV_CH_LOW_FREQUENCY_2 0x0000000800000000ULL #define AV_CH_LOW_FREQUENCY_2 0x0000000800000000ULL
#define AV_CH_TOP_SIDE_LEFT 0x0000001000000000ULL
#define AV_CH_TOP_SIDE_RIGHT 0x0000002000000000ULL
#define AV_CH_BOTTOM_FRONT_CENTER 0x0000004000000000ULL
#define AV_CH_BOTTOM_FRONT_LEFT 0x0000008000000000ULL
#define AV_CH_BOTTOM_FRONT_RIGHT 0x0000010000000000ULL
/** Channel mask value used for AVCodecContext.request_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 indicate that the user requests the channel order of the decoder output
@ -110,6 +115,7 @@
#define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT) #define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_HEXADECAGONAL (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) #define AV_CH_LAYOUT_HEXADECAGONAL (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT)
#define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT) #define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT)
#define AV_CH_LAYOUT_22POINT2 (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_BACK_CENTER|AV_CH_LOW_FREQUENCY_2|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_CENTER|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_BOTTOM_FRONT_CENTER|AV_CH_BOTTOM_FRONT_LEFT|AV_CH_BOTTOM_FRONT_RIGHT)
enum AVMatrixEncoding { enum AVMatrixEncoding {
AV_MATRIX_ENCODING_NONE, AV_MATRIX_ENCODING_NONE,

Просмотреть файл

@ -53,7 +53,7 @@
//rounded division & shift //rounded division & shift
#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
/* assume b>0 */ /* assume b>0 */
#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) #define ROUNDED_DIV(a,b) (((a)>=0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
/* Fast a/(1<<b) rounded toward +inf. Assume a>=0 and b>=0 */ /* Fast a/(1<<b) rounded toward +inf. Assume a>=0 and b>=0 */
#define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \ #define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \
: ((a) + (1<<(b)) - 1) >> (b)) : ((a) + (1<<(b)) - 1) >> (b))
@ -80,6 +80,15 @@
*/ */
#define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) #define FFNABS(a) ((a) <= 0 ? (a) : (-(a)))
/**
* Unsigned Absolute value.
* This takes the absolute value of a signed int and returns it as a unsigned.
* This also works with INT_MIN which would otherwise not be representable
* As with many macros, this evaluates its argument twice.
*/
#define FFABSU(a) ((a) <= 0 ? -(unsigned)(a) : (unsigned)(a))
#define FFABS64U(a) ((a) <= 0 ? -(uint64_t)(a) : (uint64_t)(a))
/** /**
* Comparator. * Comparator.
* For two numerical expressions x and y, gives 1 if x > y, -1 if x < y, and 0 * For two numerical expressions x and y, gives 1 if x > y, -1 if x < y, and 0
@ -106,8 +115,72 @@
# include "intmath.h" # include "intmath.h"
#endif #endif
/* Pull in unguarded fallback defines at the end of this file. */ #ifndef av_ceil_log2
#include "common.h" # define av_ceil_log2 av_ceil_log2_c
#endif
#ifndef av_clip
# define av_clip av_clip_c
#endif
#ifndef av_clip64
# define av_clip64 av_clip64_c
#endif
#ifndef av_clip_uint8
# define av_clip_uint8 av_clip_uint8_c
#endif
#ifndef av_clip_int8
# define av_clip_int8 av_clip_int8_c
#endif
#ifndef av_clip_uint16
# define av_clip_uint16 av_clip_uint16_c
#endif
#ifndef av_clip_int16
# define av_clip_int16 av_clip_int16_c
#endif
#ifndef av_clipl_int32
# define av_clipl_int32 av_clipl_int32_c
#endif
#ifndef av_clip_intp2
# define av_clip_intp2 av_clip_intp2_c
#endif
#ifndef av_clip_uintp2
# define av_clip_uintp2 av_clip_uintp2_c
#endif
#ifndef av_mod_uintp2
# define av_mod_uintp2 av_mod_uintp2_c
#endif
#ifndef av_sat_add32
# define av_sat_add32 av_sat_add32_c
#endif
#ifndef av_sat_dadd32
# define av_sat_dadd32 av_sat_dadd32_c
#endif
#ifndef av_sat_sub32
# define av_sat_sub32 av_sat_sub32_c
#endif
#ifndef av_sat_dsub32
# define av_sat_dsub32 av_sat_dsub32_c
#endif
#ifndef av_sat_add64
# define av_sat_add64 av_sat_add64_c
#endif
#ifndef av_sat_sub64
# define av_sat_sub64 av_sat_sub64_c
#endif
#ifndef av_clipf
# define av_clipf av_clipf_c
#endif
#ifndef av_clipd
# define av_clipd av_clipd_c
#endif
#ifndef av_popcount
# define av_popcount av_popcount_c
#endif
#ifndef av_popcount64
# define av_popcount64 av_popcount64_c
#endif
#ifndef av_parity
# define av_parity av_parity_c
#endif
#ifndef av_log2 #ifndef av_log2
av_const int av_log2(unsigned v); av_const int av_log2(unsigned v);
@ -240,7 +313,7 @@ static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
*/ */
static av_always_inline av_const unsigned av_mod_uintp2_c(unsigned a, unsigned p) static av_always_inline av_const unsigned av_mod_uintp2_c(unsigned a, unsigned p)
{ {
return a & ((1 << p) - 1); return a & ((1U << p) - 1);
} }
/** /**
@ -291,6 +364,45 @@ static av_always_inline int av_sat_dsub32_c(int a, int b)
return av_sat_sub32(a, av_sat_add32(b, b)); return av_sat_sub32(a, av_sat_add32(b, b));
} }
/**
* Add two signed 64-bit values with saturation.
*
* @param a one value
* @param b another value
* @return sum with signed saturation
*/
static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) {
#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_add_overflow)
int64_t tmp;
return !__builtin_add_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN);
#else
int64_t s = a+(uint64_t)b;
if ((int64_t)(a^b | ~s^b) >= 0)
return INT64_MAX ^ (b >> 63);
return s;
#endif
}
/**
* Subtract two signed 64-bit values with saturation.
*
* @param a one value
* @param b another value
* @return difference with signed saturation
*/
static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) {
#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_sub_overflow)
int64_t tmp;
return !__builtin_sub_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN);
#else
if (b <= 0 && a >= INT64_MAX + b)
return INT64_MAX;
if (b >= 0 && a <= INT64_MIN + b)
return INT64_MIN;
return a - b;
#endif
}
/** /**
* Clip a float value into the amin-amax range. * Clip a float value into the amin-amax range.
* @param a value to clip * @param a value to clip
@ -331,7 +443,7 @@ static av_always_inline av_const double av_clipd_c(double a, double amin, double
*/ */
static av_always_inline av_const int av_ceil_log2_c(int x) static av_always_inline av_const int av_ceil_log2_c(int x)
{ {
return av_log2((x - 1) << 1); return av_log2((x - 1U) << 1);
} }
/** /**
@ -373,7 +485,9 @@ static av_always_inline av_const int av_parity_c(uint32_t v)
* @param GET_BYTE Expression reading one byte from the input. * @param GET_BYTE Expression reading one byte from the input.
* Evaluated up to 7 times (4 for the currently * Evaluated up to 7 times (4 for the currently
* assigned Unicode range). With a memory buffer * assigned Unicode range). With a memory buffer
* input, this could be *ptr++. * input, this could be *ptr++, or if you want to make sure
* that *ptr stops at the end of a NULL terminated string then
* *ptr ? *ptr++ : 0
* @param ERROR Expression to be evaluated on invalid input, * @param ERROR Expression to be evaluated on invalid input,
* typically a goto statement. * typically a goto statement.
* *
@ -387,11 +501,11 @@ static av_always_inline av_const int av_parity_c(uint32_t v)
{\ {\
uint32_t top = (val & 128) >> 1;\ uint32_t top = (val & 128) >> 1;\
if ((val & 0xc0) == 0x80 || val >= 0xFE)\ if ((val & 0xc0) == 0x80 || val >= 0xFE)\
ERROR\ {ERROR}\
while (val & top) {\ while (val & top) {\
int tmp= (GET_BYTE) - 128;\ unsigned int tmp = (GET_BYTE) - 128;\
if(tmp>>6)\ if(tmp>>6)\
ERROR\ {ERROR}\
val= (val<<6) + tmp;\ val= (val<<6) + tmp;\
top <<= 5;\ top <<= 5;\
}\ }\
@ -408,13 +522,13 @@ static av_always_inline av_const int av_parity_c(uint32_t v)
* typically a goto statement. * typically a goto statement.
*/ */
#define GET_UTF16(val, GET_16BIT, ERROR)\ #define GET_UTF16(val, GET_16BIT, ERROR)\
val = GET_16BIT;\ val = (GET_16BIT);\
{\ {\
unsigned int hi = val - 0xD800;\ unsigned int hi = val - 0xD800;\
if (hi < 0x800) {\ if (hi < 0x800) {\
val = GET_16BIT - 0xDC00;\ val = (GET_16BIT) - 0xDC00;\
if (val > 0x3FFU || hi > 0x3FFU)\ if (val > 0x3FFU || hi > 0x3FFU)\
ERROR\ {ERROR}\
val += (hi<<10) + 0x10000;\ val += (hi<<10) + 0x10000;\
}\ }\
}\ }\
@ -492,69 +606,3 @@ static av_always_inline av_const int av_parity_c(uint32_t v)
#endif /* HAVE_AV_CONFIG_H */ #endif /* HAVE_AV_CONFIG_H */
#endif /* AVUTIL_COMMON_H */ #endif /* AVUTIL_COMMON_H */
/*
* The following definitions are outside the multiple inclusion guard
* to ensure they are immediately available in intmath.h.
*/
#ifndef av_ceil_log2
# define av_ceil_log2 av_ceil_log2_c
#endif
#ifndef av_clip
# define av_clip av_clip_c
#endif
#ifndef av_clip64
# define av_clip64 av_clip64_c
#endif
#ifndef av_clip_uint8
# define av_clip_uint8 av_clip_uint8_c
#endif
#ifndef av_clip_int8
# define av_clip_int8 av_clip_int8_c
#endif
#ifndef av_clip_uint16
# define av_clip_uint16 av_clip_uint16_c
#endif
#ifndef av_clip_int16
# define av_clip_int16 av_clip_int16_c
#endif
#ifndef av_clipl_int32
# define av_clipl_int32 av_clipl_int32_c
#endif
#ifndef av_clip_intp2
# define av_clip_intp2 av_clip_intp2_c
#endif
#ifndef av_clip_uintp2
# define av_clip_uintp2 av_clip_uintp2_c
#endif
#ifndef av_mod_uintp2
# define av_mod_uintp2 av_mod_uintp2_c
#endif
#ifndef av_sat_add32
# define av_sat_add32 av_sat_add32_c
#endif
#ifndef av_sat_dadd32
# define av_sat_dadd32 av_sat_dadd32_c
#endif
#ifndef av_sat_sub32
# define av_sat_sub32 av_sat_sub32_c
#endif
#ifndef av_sat_dsub32
# define av_sat_dsub32 av_sat_dsub32_c
#endif
#ifndef av_clipf
# define av_clipf av_clipf_c
#endif
#ifndef av_clipd
# define av_clipd av_clipd_c
#endif
#ifndef av_popcount
# define av_popcount av_popcount_c
#endif
#ifndef av_popcount64
# define av_popcount64 av_popcount64_c
#endif
#ifndef av_parity
# define av_parity av_parity_c
#endif

Просмотреть файл

@ -51,6 +51,8 @@ static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1);
static int get_cpu_flags(void) static int get_cpu_flags(void)
{ {
if (ARCH_MIPS)
return ff_get_cpu_flags_mips();
if (ARCH_AARCH64) if (ARCH_AARCH64)
return ff_get_cpu_flags_aarch64(); return ff_get_cpu_flags_aarch64();
if (ARCH_ARM) if (ARCH_ARM)
@ -169,6 +171,9 @@ int av_parse_cpu_flags(const char *s)
{ "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" },
{ "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
{ "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
#elif ARCH_MIPS
{ "mmi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMI }, .unit = "flags" },
{ "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" },
#endif #endif
{ NULL }, { NULL },
}; };
@ -250,6 +255,9 @@ int av_parse_cpu_caps(unsigned *flags, const char *s)
{ "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" },
{ "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
{ "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
#elif ARCH_MIPS
{ "mmi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMI }, .unit = "flags" },
{ "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" },
#endif #endif
{ NULL }, { NULL },
}; };
@ -283,6 +291,12 @@ int av_cpu_count(void)
DWORD_PTR proc_aff, sys_aff; DWORD_PTR proc_aff, sys_aff;
if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff)) if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff))
nb_cpus = av_popcount64(proc_aff); nb_cpus = av_popcount64(proc_aff);
#elif HAVE_SYSCTL && defined(HW_NCPUONLINE)
int mib[2] = { CTL_HW, HW_NCPUONLINE };
size_t len = sizeof(nb_cpus);
if (sysctl(mib, 2, &nb_cpus, &len, NULL, 0) == -1)
nb_cpus = 0;
#elif HAVE_SYSCTL && defined(HW_NCPU) #elif HAVE_SYSCTL && defined(HW_NCPU)
int mib[2] = { CTL_HW, HW_NCPU }; int mib[2] = { CTL_HW, HW_NCPU };
size_t len = sizeof(nb_cpus); size_t len = sizeof(nb_cpus);
@ -308,6 +322,8 @@ int av_cpu_count(void)
size_t av_cpu_max_align(void) size_t av_cpu_max_align(void)
{ {
if (ARCH_MIPS)
return ff_get_cpu_max_align_mips();
if (ARCH_AARCH64) if (ARCH_AARCH64)
return ff_get_cpu_max_align_aarch64(); return ff_get_cpu_max_align_aarch64();
if (ARCH_ARM) if (ARCH_ARM)

Просмотреть файл

@ -71,6 +71,9 @@
#define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations #define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations
#define AV_CPU_FLAG_SETEND (1 <<16) #define AV_CPU_FLAG_SETEND (1 <<16)
#define AV_CPU_FLAG_MMI (1 << 0)
#define AV_CPU_FLAG_MSA (1 << 1)
/** /**
* Return the flags which specify extensions supported by the CPU. * Return the flags which specify extensions supported by the CPU.
* The returned value is affected by av_force_cpu_flags() if that was used * The returned value is affected by av_force_cpu_flags() if that was used

Просмотреть файл

@ -41,11 +41,13 @@
#define CPUEXT_FAST(flags, cpuext) CPUEXT_SUFFIX_FAST(flags, , cpuext) #define CPUEXT_FAST(flags, cpuext) CPUEXT_SUFFIX_FAST(flags, , cpuext)
#define CPUEXT_SLOW(flags, cpuext) CPUEXT_SUFFIX_SLOW(flags, , cpuext) #define CPUEXT_SLOW(flags, cpuext) CPUEXT_SUFFIX_SLOW(flags, , cpuext)
int ff_get_cpu_flags_mips(void);
int ff_get_cpu_flags_aarch64(void); int ff_get_cpu_flags_aarch64(void);
int ff_get_cpu_flags_arm(void); int ff_get_cpu_flags_arm(void);
int ff_get_cpu_flags_ppc(void); int ff_get_cpu_flags_ppc(void);
int ff_get_cpu_flags_x86(void); int ff_get_cpu_flags_x86(void);
size_t ff_get_cpu_max_align_mips(void);
size_t ff_get_cpu_max_align_aarch64(void); size_t ff_get_cpu_max_align_aarch64(void);
size_t ff_get_cpu_max_align_arm(void); size_t ff_get_cpu_max_align_arm(void);
size_t ff_get_cpu_max_align_ppc(void); size_t ff_get_cpu_max_align_ppc(void);

Просмотреть файл

@ -103,8 +103,8 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value,
av_free(tag->key); av_free(tag->key);
*tag = m->elems[--m->count]; *tag = m->elems[--m->count];
} else if (copy_value) { } else if (copy_value) {
AVDictionaryEntry *tmp = av_realloc(m->elems, AVDictionaryEntry *tmp = av_realloc_array(m->elems,
(m->count + 1) * sizeof(*m->elems)); m->count + 1, sizeof(*m->elems));
if (!tmp) if (!tmp)
goto err_out; goto err_out;
m->elems = tmp; m->elems = tmp;

Просмотреть файл

@ -163,10 +163,11 @@ struct AVExpr {
e_last, e_st, e_while, e_taylor, e_root, e_floor, e_ceil, e_trunc, e_round, e_last, e_st, e_while, e_taylor, e_root, e_floor, e_ceil, e_trunc, e_round,
e_sqrt, e_not, e_random, e_hypot, e_gcd, e_sqrt, e_not, e_random, e_hypot, e_gcd,
e_if, e_ifnot, e_print, e_bitand, e_bitor, e_between, e_clip, e_atan2, e_lerp, e_if, e_ifnot, e_print, e_bitand, e_bitor, e_between, e_clip, e_atan2, e_lerp,
e_sgn,
} type; } type;
double value; // is sign in other types double value; // is sign in other types
int const_index;
union { union {
int const_index;
double (*func0)(double); double (*func0)(double);
double (*func1)(void *, double); double (*func1)(void *, double);
double (*func2)(void *, double, double); double (*func2)(void *, double, double);
@ -184,7 +185,7 @@ static double eval_expr(Parser *p, AVExpr *e)
{ {
switch (e->type) { switch (e->type) {
case e_value: return e->value; case e_value: return e->value;
case e_const: return e->value * p->const_values[e->a.const_index]; case e_const: return e->value * p->const_values[e->const_index];
case e_func0: return e->value * e->a.func0(eval_expr(p, e->param[0])); case e_func0: return e->value * e->a.func0(eval_expr(p, e->param[0]));
case e_func1: return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0])); case e_func1: return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0]));
case e_func2: return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1])); case e_func2: return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1]));
@ -197,6 +198,7 @@ static double eval_expr(Parser *p, AVExpr *e)
case e_ceil : return e->value * ceil (eval_expr(p, e->param[0])); case e_ceil : return e->value * ceil (eval_expr(p, e->param[0]));
case e_trunc: return e->value * trunc(eval_expr(p, e->param[0])); case e_trunc: return e->value * trunc(eval_expr(p, e->param[0]));
case e_round: return e->value * round(eval_expr(p, e->param[0])); case e_round: return e->value * round(eval_expr(p, e->param[0]));
case e_sgn: return e->value * FFDIFFSIGN(eval_expr(p, e->param[0]), 0);
case e_sqrt: return e->value * sqrt (eval_expr(p, e->param[0])); case e_sqrt: return e->value * sqrt (eval_expr(p, e->param[0]));
case e_not: return e->value * (eval_expr(p, e->param[0]) == 0); case e_not: return e->value * (eval_expr(p, e->param[0]) == 0);
case e_if: return e->value * (eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : case e_if: return e->value * (eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) :
@ -304,7 +306,7 @@ static double eval_expr(Parser *p, AVExpr *e)
double d = eval_expr(p, e->param[0]); double d = eval_expr(p, e->param[0]);
double d2 = eval_expr(p, e->param[1]); double d2 = eval_expr(p, e->param[1]);
switch (e->type) { switch (e->type) {
case e_mod: return e->value * (d - floor((!CONFIG_FTRAPV || d2) ? d / d2 : d * INFINITY) * d2); case e_mod: return e->value * (d - floor(d2 ? d / d2 : d * INFINITY) * d2);
case e_gcd: return e->value * av_gcd(d,d2); case e_gcd: return e->value * av_gcd(d,d2);
case e_max: return e->value * (d > d2 ? d : d2); case e_max: return e->value * (d > d2 ? d : d2);
case e_min: return e->value * (d < d2 ? d : d2); case e_min: return e->value * (d < d2 ? d : d2);
@ -315,7 +317,7 @@ static double eval_expr(Parser *p, AVExpr *e)
case e_lte: return e->value * (d <= d2 ? 1.0 : 0.0); case e_lte: return e->value * (d <= d2 ? 1.0 : 0.0);
case e_pow: return e->value * pow(d, d2); case e_pow: return e->value * pow(d, d2);
case e_mul: return e->value * (d * d2); case e_mul: return e->value * (d * d2);
case e_div: return e->value * ((!CONFIG_FTRAPV || d2 ) ? (d / d2) : d * INFINITY); case e_div: return e->value * (d2 ? (d / d2) : d * INFINITY);
case e_add: return e->value * (d + d2); case e_add: return e->value * (d + d2);
case e_last:return e->value * d2; case e_last:return e->value * d2;
case e_st : return e->value * (p->var[av_clip(d, 0, VARS-1)]= d2); case e_st : return e->value * (p->var[av_clip(d, 0, VARS-1)]= d2);
@ -365,7 +367,7 @@ static int parse_primary(AVExpr **e, Parser *p)
if (strmatch(p->s, p->const_names[i])) { if (strmatch(p->s, p->const_names[i])) {
p->s+= strlen(p->const_names[i]); p->s+= strlen(p->const_names[i]);
d->type = e_const; d->type = e_const;
d->a.const_index = i; d->const_index = i;
*e = d; *e = d;
return 0; return 0;
} }
@ -470,11 +472,13 @@ static int parse_primary(AVExpr **e, Parser *p)
else if (strmatch(next, "clip" )) d->type = e_clip; else if (strmatch(next, "clip" )) d->type = e_clip;
else if (strmatch(next, "atan2" )) d->type = e_atan2; else if (strmatch(next, "atan2" )) d->type = e_atan2;
else if (strmatch(next, "lerp" )) d->type = e_lerp; else if (strmatch(next, "lerp" )) d->type = e_lerp;
else if (strmatch(next, "sgn" )) d->type = e_sgn;
else { else {
for (i=0; p->func1_names && p->func1_names[i]; i++) { for (i=0; p->func1_names && p->func1_names[i]; i++) {
if (strmatch(next, p->func1_names[i])) { if (strmatch(next, p->func1_names[i])) {
d->a.func1 = p->funcs1[i]; d->a.func1 = p->funcs1[i];
d->type = e_func1; d->type = e_func1;
d->const_index = i;
*e = d; *e = d;
return 0; return 0;
} }
@ -484,6 +488,7 @@ static int parse_primary(AVExpr **e, Parser *p)
if (strmatch(next, p->func2_names[i])) { if (strmatch(next, p->func2_names[i])) {
d->a.func2 = p->funcs2[i]; d->a.func2 = p->funcs2[i];
d->type = e_func2; d->type = e_func2;
d->const_index = i;
*e = d; *e = d;
return 0; return 0;
} }
@ -657,6 +662,7 @@ static int verify_expr(AVExpr *e)
case e_sqrt: case e_sqrt:
case e_not: case e_not:
case e_random: case e_random:
case e_sgn:
return verify_expr(e->param[0]) && !e->param[1]; return verify_expr(e->param[0]) && !e->param[1];
case e_print: case e_print:
return verify_expr(e->param[0]) return verify_expr(e->param[0])
@ -731,6 +737,32 @@ end:
return ret; return ret;
} }
static int expr_count(AVExpr *e, unsigned *counter, int size, int type)
{
int i;
if (!e || !counter || !size)
return AVERROR(EINVAL);
for (i = 0; e->type != type && i < 3 && e->param[i]; i++)
expr_count(e->param[i], counter, size, type);
if (e->type == type && e->const_index < size)
counter[e->const_index]++;
return 0;
}
int av_expr_count_vars(AVExpr *e, unsigned *counter, int size)
{
return expr_count(e, counter, size, e_const);
}
int av_expr_count_func(AVExpr *e, unsigned *counter, int size, int arg)
{
return expr_count(e, counter, size, ((int[]){e_const, e_func1, e_func2})[arg]);
}
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque) double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
{ {
Parser p = { 0 }; Parser p = { 0 };

Просмотреть файл

@ -86,6 +86,30 @@ int av_expr_parse(AVExpr **expr, const char *s,
*/ */
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque); double av_expr_eval(AVExpr *e, const double *const_values, void *opaque);
/**
* Track the presence of variables and their number of occurrences in a parsed expression
*
* @param counter a zero-initialized array where the count of each variable will be stored
* @param size size of array
* @return 0 on success, a negative value indicates that no expression or array was passed
* or size was zero
*/
int av_expr_count_vars(AVExpr *e, unsigned *counter, int size);
/**
* Track the presence of user provided functions and their number of occurrences
* in a parsed expression.
*
* @param counter a zero-initialized array where the count of each function will be stored
* if you passed 5 functions with 2 arguments to av_expr_parse()
* then for arg=2 this will use upto 5 entries.
* @param size size of array
* @param arg number of arguments the counted functions have
* @return 0 on success, a negative value indicates that no expression or array was passed
* or size was zero
*/
int av_expr_count_func(AVExpr *e, unsigned *counter, int size, int arg);
/** /**
* Free a parsed expression previously created with av_expr_parse(). * Free a parsed expression previously created with av_expr_parse().
*/ */

Просмотреть файл

@ -22,6 +22,7 @@
#define AVUTIL_TIME_H #define AVUTIL_TIME_H
#include <stdint.h> #include <stdint.h>
#include <time.h>
/** /**
* Get the current time in microseconds. * Get the current time in microseconds.

Просмотреть файл

@ -0,0 +1,42 @@
/**
* 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 "film_grain_params.h"
AVFilmGrainParams *av_film_grain_params_alloc(size_t *size)
{
AVFilmGrainParams *params = av_mallocz(sizeof(AVFilmGrainParams));
if (size)
*size = sizeof(*params);
return params;
}
AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame)
{
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));
return (AVFilmGrainParams *)side_data->data;
}

Просмотреть файл

@ -0,0 +1,168 @@
/*
* 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_FILM_GRAIN_PARAMS_H
#define AVUTIL_FILM_GRAIN_PARAMS_H
#include "frame.h"
enum AVFilmGrainParamsType {
AV_FILM_GRAIN_PARAMS_NONE = 0,
/**
* The union is valid when interpreted as AVFilmGrainAOMParams (codec.aom)
*/
AV_FILM_GRAIN_PARAMS_AV1,
};
/**
* This structure describes how to handle film grain synthesis for AOM codecs.
*
* @note The struct must be allocated as part of AVFilmGrainParams using
* av_film_grain_params_alloc(). Its size is not a part of the public ABI.
*/
typedef struct AVFilmGrainAOMParams {
/**
* Number of points, and the scale and value for each point of the
* piecewise linear scaling function for the uma plane.
*/
int num_y_points;
uint8_t y_points[14][2 /* value, scaling */];
/**
* Signals whether to derive the chroma scaling function from the luma.
* Not equivalent to copying the luma values and scales.
*/
int chroma_scaling_from_luma;
/**
* If chroma_scaling_from_luma is set to 0, signals the chroma scaling
* function parameters.
*/
int num_uv_points[2 /* cb, cr */];
uint8_t uv_points[2 /* cb, cr */][10][2 /* value, scaling */];
/**
* Specifies the shift applied to the chroma components. For AV1, its within
* [8; 11] and determines the range and quantization of the film grain.
*/
int scaling_shift;
/**
* Specifies the auto-regression lag.
*/
int ar_coeff_lag;
/**
* Luma auto-regression coefficients. The number of coefficients is given by
* 2 * ar_coeff_lag * (ar_coeff_lag + 1).
*/
int8_t ar_coeffs_y[24];
/**
* Chroma auto-regression coefficients. The number of coefficients is given by
* 2 * ar_coeff_lag * (ar_coeff_lag + 1) + !!num_y_points.
*/
int8_t ar_coeffs_uv[2 /* cb, cr */][25];
/**
* Specifies the range of the auto-regressive coefficients. Values of 6,
* 7, 8 and so on represent a range of [-2, 2), [-1, 1), [-0.5, 0.5) and
* so on. For AV1 must be between 6 and 9.
*/
int ar_coeff_shift;
/**
* Signals the down shift applied to the generated gaussian numbers during
* synthesis.
*/
int grain_scale_shift;
/**
* Specifies the luma/chroma multipliers for the index to the component
* scaling function.
*/
int uv_mult[2 /* cb, cr */];
int uv_mult_luma[2 /* cb, cr */];
/**
* Offset used for component scaling function. For AV1 its a 9-bit value
* with a range [-256, 255]
*/
int uv_offset[2 /* cb, cr */];
/**
* Signals whether to overlap film grain blocks.
*/
int overlap_flag;
/**
* Signals to clip to limited color levels after film grain application.
*/
int limit_output_range;
} AVFilmGrainAOMParams;
/**
* This structure describes how to handle film grain synthesis in video
* for specific codecs. Must be present on every frame where film grain is
* meant to be synthesised for correct presentation.
*
* @note The struct must be allocated with av_film_grain_params_alloc() and
* its size is not a part of the public ABI.
*/
typedef struct AVFilmGrainParams {
/**
* Specifies the codec for which this structure is valid.
*/
enum AVFilmGrainParamsType type;
/**
* Seed to use for the synthesis process, if the codec allows for it.
*/
uint64_t seed;
/**
* 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.
*/
union {
AVFilmGrainAOMParams aom;
} codec;
} AVFilmGrainParams;
/**
* Allocate an AVFilmGrainParams structure and set its fields to
* default values. The resulting struct can be freed using av_freep().
* If size is not NULL it will be set to the number of bytes allocated.
*
* @return An AVFilmGrainParams filled with default values or NULL
* on failure.
*/
AVFilmGrainParams *av_film_grain_params_alloc(size_t *size);
/**
* Allocate a complete AVFilmGrainParams and add it to the frame.
*
* @param frame The frame which side data is added to.
*
* @return The AVFilmGrainParams structure to be filled by caller.
*/
AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame);
#endif /* AVUTIL_FILM_GRAIN_PARAMS_H */

Просмотреть файл

@ -134,9 +134,10 @@ static int scalarproduct_fixed_c(const int *v1, const int *v2, int len)
return (int)(p >> 31); return (int)(p >> 31);
} }
static void butterflies_fixed_c(int *v1, int *v2, int len) static void butterflies_fixed_c(int *v1s, int *v2, int len)
{ {
int i; int i;
unsigned int *v1 = v1s;
for (i = 0; i < len; i++){ for (i = 0; i < len; i++){
int t = v1[i] - v2[i]; int t = v1[i] - v2[i];

Просмотреть файл

@ -25,6 +25,7 @@
#include "imgutils.h" #include "imgutils.h"
#include "mem.h" #include "mem.h"
#include "samplefmt.h" #include "samplefmt.h"
#include "hwcontext.h"
#if FF_API_FRAME_GET_SET #if FF_API_FRAME_GET_SET
MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp) MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp)
@ -211,8 +212,10 @@ void av_frame_free(AVFrame **frame)
static int get_video_buffer(AVFrame *frame, int align) static int get_video_buffer(AVFrame *frame, int align)
{ {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
int ret, i, padded_height; int ret, i, padded_height, total_size;
int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align); int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align);
ptrdiff_t linesizes[4];
size_t sizes[4];
if (!desc) if (!desc)
return AVERROR(EINVAL); return AVERROR(EINVAL);
@ -237,12 +240,22 @@ static int get_video_buffer(AVFrame *frame, int align)
frame->linesize[i] = FFALIGN(frame->linesize[i], align); frame->linesize[i] = FFALIGN(frame->linesize[i], align);
} }
for (i = 0; i < 4; i++)
linesizes[i] = frame->linesize[i];
padded_height = FFALIGN(frame->height, 32); padded_height = FFALIGN(frame->height, 32);
if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, if ((ret = av_image_fill_plane_sizes(sizes, frame->format,
NULL, frame->linesize)) < 0) padded_height, linesizes)) < 0)
return ret; return ret;
frame->buf[0] = av_buffer_alloc(ret + 4*plane_padding); total_size = 4*plane_padding;
for (i = 0; i < 4; i++) {
if (sizes[i] > INT_MAX - total_size)
return AVERROR(EINVAL);
total_size += sizes[i];
}
frame->buf[0] = av_buffer_alloc(total_size);
if (!frame->buf[0]) { if (!frame->buf[0]) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; goto fail;
@ -336,7 +349,7 @@ int av_frame_get_buffer(AVFrame *frame, int align)
static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
{ {
int i; int ret, i;
dst->key_frame = src->key_frame; dst->key_frame = src->key_frame;
dst->pict_type = src->pict_type; dst->pict_type = src->pict_type;
@ -413,31 +426,18 @@ FF_DISABLE_DEPRECATION_WARNINGS
dst->qscale_table = NULL; dst->qscale_table = NULL;
dst->qstride = 0; dst->qstride = 0;
dst->qscale_type = 0; dst->qscale_type = 0;
av_buffer_unref(&dst->qp_table_buf); av_buffer_replace(&dst->qp_table_buf, src->qp_table_buf);
if (src->qp_table_buf) { if (dst->qp_table_buf) {
dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); dst->qscale_table = dst->qp_table_buf->data;
if (dst->qp_table_buf) { dst->qstride = src->qstride;
dst->qscale_table = dst->qp_table_buf->data; dst->qscale_type = src->qscale_type;
dst->qstride = src->qstride;
dst->qscale_type = src->qscale_type;
}
} }
FF_ENABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS
#endif #endif
av_buffer_unref(&dst->opaque_ref); ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
av_buffer_unref(&dst->private_ref); ret |= av_buffer_replace(&dst->private_ref, src->private_ref);
if (src->opaque_ref) { return ret;
dst->opaque_ref = av_buffer_ref(src->opaque_ref);
if (!dst->opaque_ref)
return AVERROR(ENOMEM);
}
if (src->private_ref) {
dst->private_ref = av_buffer_ref(src->private_ref);
if (!dst->private_ref)
return AVERROR(ENOMEM);
}
return 0;
} }
int av_frame_ref(AVFrame *dst, const AVFrame *src) int av_frame_ref(AVFrame *dst, const AVFrame *src)
@ -456,17 +456,17 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
ret = frame_copy_props(dst, src, 0); ret = frame_copy_props(dst, src, 0);
if (ret < 0) if (ret < 0)
return ret; goto fail;
/* duplicate the frame data if it's not refcounted */ /* duplicate the frame data if it's not refcounted */
if (!src->buf[0]) { if (!src->buf[0]) {
ret = av_frame_get_buffer(dst, 32); ret = av_frame_get_buffer(dst, 0);
if (ret < 0) if (ret < 0)
return ret; goto fail;
ret = av_frame_copy(dst, src); ret = av_frame_copy(dst, src);
if (ret < 0) if (ret < 0)
av_frame_unref(dst); goto fail;
return ret; return ret;
} }
@ -626,7 +626,11 @@ int av_frame_make_writable(AVFrame *frame)
tmp.channels = frame->channels; tmp.channels = frame->channels;
tmp.channel_layout = frame->channel_layout; tmp.channel_layout = frame->channel_layout;
tmp.nb_samples = frame->nb_samples; tmp.nb_samples = frame->nb_samples;
ret = av_frame_get_buffer(&tmp, 32);
if (frame->hw_frames_ctx)
ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0);
else
ret = av_frame_get_buffer(&tmp, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -721,7 +725,7 @@ AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
AVFrameSideData *av_frame_new_side_data(AVFrame *frame, AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
enum AVFrameSideDataType type, enum AVFrameSideDataType type,
int size) buffer_size_t size)
{ {
AVFrameSideData *ret; AVFrameSideData *ret;
AVBufferRef *buf = av_buffer_alloc(size); AVBufferRef *buf = av_buffer_alloc(size);
@ -752,6 +756,9 @@ static int frame_copy_video(AVFrame *dst, const AVFrame *src)
dst->height < src->height) dst->height < src->height)
return AVERROR(EINVAL); return AVERROR(EINVAL);
if (src->hw_frames_ctx || dst->hw_frames_ctx)
return av_hwframe_transfer_data(dst, src, 0);
planes = av_pix_fmt_count_planes(dst->format); planes = av_pix_fmt_count_planes(dst->format);
for (i = 0; i < planes; i++) for (i = 0; i < planes; i++)
if (!dst->data[i] || !src->data[i]) if (!dst->data[i] || !src->data[i])
@ -806,7 +813,7 @@ void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
{ {
int i; int i;
for (i = 0; i < frame->nb_side_data; i++) { for (i = frame->nb_side_data - 1; i >= 0; i--) {
AVFrameSideData *sd = frame->side_data[i]; AVFrameSideData *sd = frame->side_data[i];
if (sd->type == type) { if (sd->type == type) {
free_side_data(&frame->side_data[i]); free_side_data(&frame->side_data[i]);
@ -842,6 +849,9 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type)
#endif #endif
case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)"; case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)";
case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest"; 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";
} }
return NULL; return NULL;
} }

Просмотреть файл

@ -162,8 +162,8 @@ enum AVFrameSideDataType {
/** /**
* Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 uint32_t * Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 uint32_t
* where the first uint32_t describes how many (1-3) of the other timecodes are used. * where the first uint32_t describes how many (1-3) of the other timecodes are used.
* The timecode format is described in the av_timecode_get_smpte_from_framenum() * The timecode format is described in the documentation of av_timecode_get_smpte_from_framenum()
* function in libavutil/timecode.c. * function in libavutil/timecode.h.
*/ */
AV_FRAME_DATA_S12M_TIMECODE, AV_FRAME_DATA_S12M_TIMECODE,
@ -179,6 +179,25 @@ enum AVFrameSideDataType {
* array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size. * array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size.
*/ */
AV_FRAME_DATA_REGIONS_OF_INTEREST, AV_FRAME_DATA_REGIONS_OF_INTEREST,
/**
* Encoding parameters for a video frame, as described by AVVideoEncParams.
*/
AV_FRAME_DATA_VIDEO_ENC_PARAMS,
/**
* User data unregistered metadata associated with a video frame.
* This is the H.26[45] UDU SEI message, and shouldn't be used for any other purpose
* The data is stored as uint8_t in AVFrameSideData.data which is 16 bytes of
* uuid_iso_iec_11578 followed by AVFrameSideData.size - 16 bytes of user_data_payload_byte.
*/
AV_FRAME_DATA_SEI_UNREGISTERED,
/**
* Film grain parameters for a frame, described by AVFilmGrainParams.
* Must be present for every frame which should have film grain applied.
*/
AV_FRAME_DATA_FILM_GRAIN_PARAMS,
}; };
enum AVActiveFormatDescription { enum AVActiveFormatDescription {
@ -201,7 +220,11 @@ enum AVActiveFormatDescription {
typedef struct AVFrameSideData { typedef struct AVFrameSideData {
enum AVFrameSideDataType type; enum AVFrameSideDataType type;
uint8_t *data; uint8_t *data;
#if FF_API_BUFFER_SIZE_T
int size; int size;
#else
size_t size;
#endif
AVDictionary *metadata; AVDictionary *metadata;
AVBufferRef *buf; AVBufferRef *buf;
} AVFrameSideData; } AVFrameSideData;
@ -894,7 +917,11 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane);
*/ */
AVFrameSideData *av_frame_new_side_data(AVFrame *frame, AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
enum AVFrameSideDataType type, enum AVFrameSideDataType type,
#if FF_API_BUFFER_SIZE_T
int size); int size);
#else
size_t size);
#endif
/** /**
* Add a new side data to a frame from an existing AVBufferRef * Add a new side data to a frame from an existing AVBufferRef
@ -920,8 +947,7 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
enum AVFrameSideDataType type); enum AVFrameSideDataType type);
/** /**
* If side data of the supplied type exists in the frame, free it and remove it * Remove and free all side data instances of the given type.
* from the frame.
*/ */
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type); void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type);

Просмотреть файл

@ -58,6 +58,9 @@ static const HWContextType * const hw_table[] = {
#endif #endif
#if CONFIG_MEDIACODEC #if CONFIG_MEDIACODEC
&ff_hwcontext_type_mediacodec, &ff_hwcontext_type_mediacodec,
#endif
#if CONFIG_VULKAN
&ff_hwcontext_type_vulkan,
#endif #endif
NULL, NULL,
}; };
@ -73,6 +76,7 @@ static const char *const hw_type_names[] = {
[AV_HWDEVICE_TYPE_VDPAU] = "vdpau", [AV_HWDEVICE_TYPE_VDPAU] = "vdpau",
[AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox", [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox",
[AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec", [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec",
[AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
}; };
enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name) enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
@ -418,7 +422,7 @@ static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
frame_tmp->width = ctx->width; frame_tmp->width = ctx->width;
frame_tmp->height = ctx->height; frame_tmp->height = ctx->height;
ret = av_frame_get_buffer(frame_tmp, 32); ret = av_frame_get_buffer(frame_tmp, 0);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
@ -444,21 +448,54 @@ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
if (!dst->buf[0]) if (!dst->buf[0])
return transfer_data_alloc(dst, src, flags); return transfer_data_alloc(dst, src, flags);
if (src->hw_frames_ctx) { /*
ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; * Hardware -> Hardware Transfer.
* Unlike Software -> Hardware or Hardware -> Software, the transfer
* function could be provided by either the src or dst, depending on
* 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;
ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src); if (src_ctx->internal->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) {
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);
if (ret == AVERROR(ENOSYS))
ret = dst_ctx->internal->hw_type->transfer_data_to(dst_ctx, dst, src);
if (ret < 0) if (ret < 0)
return ret; return ret;
} else if (dst->hw_frames_ctx) { } else {
ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data; if (src->hw_frames_ctx) {
ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src); ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
if (ret < 0) if (ret < 0)
return ret; return ret;
} else } else if (dst->hw_frames_ctx) {
return AVERROR(ENOSYS); ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
if (ret < 0)
return ret;
} else {
return AVERROR(ENOSYS);
}
}
return 0; return 0;
} }
@ -520,6 +557,8 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
return ret; return ret;
} }
frame->extended_data = frame->data;
return 0; return 0;
} }
@ -604,9 +643,10 @@ fail:
return ret; return ret;
} }
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
enum AVHWDeviceType type, enum AVHWDeviceType type,
AVBufferRef *src_ref, int flags) AVBufferRef *src_ref,
AVDictionary *options, int flags)
{ {
AVBufferRef *dst_ref = NULL, *tmp_ref; AVBufferRef *dst_ref = NULL, *tmp_ref;
AVHWDeviceContext *dst_ctx, *tmp_ctx; AVHWDeviceContext *dst_ctx, *tmp_ctx;
@ -639,6 +679,7 @@ int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr,
if (dst_ctx->internal->hw_type->device_derive) { if (dst_ctx->internal->hw_type->device_derive) {
ret = dst_ctx->internal->hw_type->device_derive(dst_ctx, ret = dst_ctx->internal->hw_type->device_derive(dst_ctx,
tmp_ctx, tmp_ctx,
options,
flags); flags);
if (ret == 0) { if (ret == 0) {
dst_ctx->internal->source_device = av_buffer_ref(src_ref); dst_ctx->internal->source_device = av_buffer_ref(src_ref);
@ -670,6 +711,14 @@ fail:
return ret; return ret;
} }
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr,
enum AVHWDeviceType type,
AVBufferRef *src_ref, int flags)
{
return av_hwdevice_ctx_create_derived_opts(dst_ref_ptr, type, src_ref,
NULL, flags);
}
static void ff_hwframe_unmap(void *opaque, uint8_t *data) static void ff_hwframe_unmap(void *opaque, uint8_t *data)
{ {
HWMapDescriptor *hwmap = (HWMapDescriptor*)data; HWMapDescriptor *hwmap = (HWMapDescriptor*)data;

Просмотреть файл

@ -36,6 +36,7 @@ enum AVHWDeviceType {
AV_HWDEVICE_TYPE_DRM, AV_HWDEVICE_TYPE_DRM,
AV_HWDEVICE_TYPE_OPENCL, AV_HWDEVICE_TYPE_OPENCL,
AV_HWDEVICE_TYPE_MEDIACODEC, AV_HWDEVICE_TYPE_MEDIACODEC,
AV_HWDEVICE_TYPE_VULKAN,
}; };
typedef struct AVHWDeviceInternal AVHWDeviceInternal; typedef struct AVHWDeviceInternal AVHWDeviceInternal;
@ -327,6 +328,26 @@ int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ctx,
enum AVHWDeviceType type, enum AVHWDeviceType type,
AVBufferRef *src_ctx, int flags); AVBufferRef *src_ctx, int flags);
/**
* Create a new device of the specified type from an existing device.
*
* This function performs the same action as av_hwdevice_ctx_create_derived,
* however, it is able to set options for the new device to be derived.
*
* @param dst_ctx On success, a reference to the newly-created
* AVHWDeviceContext.
* @param type The type of the new device to create.
* @param src_ctx A reference to an existing AVHWDeviceContext which will be
* used to create the new device.
* @param options Options for the new device to create, same format as in
* av_hwdevice_ctx_create.
* @param flags Currently unused; should be set to zero.
* @return Zero on success, a negative AVERROR code on failure.
*/
int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ctx,
enum AVHWDeviceType type,
AVBufferRef *src_ctx,
AVDictionary *options, int flags);
/** /**
* Allocate an AVHWFramesContext tied to a given device context. * Allocate an AVHWFramesContext tied to a given device context.

Просмотреть файл

@ -67,7 +67,8 @@ typedef struct HWContextType {
int (*device_create)(AVHWDeviceContext *ctx, const char *device, int (*device_create)(AVHWDeviceContext *ctx, const char *device,
AVDictionary *opts, int flags); AVDictionary *opts, int flags);
int (*device_derive)(AVHWDeviceContext *dst_ctx, int (*device_derive)(AVHWDeviceContext *dst_ctx,
AVHWDeviceContext *src_ctx, int flags); AVHWDeviceContext *src_ctx,
AVDictionary *opts, int flags);
int (*device_init)(AVHWDeviceContext *ctx); int (*device_init)(AVHWDeviceContext *ctx);
void (*device_uninit)(AVHWDeviceContext *ctx); void (*device_uninit)(AVHWDeviceContext *ctx);
@ -172,5 +173,6 @@ extern const HWContextType ff_hwcontext_type_vaapi;
extern const HWContextType ff_hwcontext_type_vdpau; extern const HWContextType ff_hwcontext_type_vdpau;
extern const HWContextType ff_hwcontext_type_videotoolbox; extern const HWContextType ff_hwcontext_type_videotoolbox;
extern const HWContextType ff_hwcontext_type_mediacodec; extern const HWContextType ff_hwcontext_type_mediacodec;
extern const HWContextType ff_hwcontext_type_vulkan;
#endif /* AVUTIL_HWCONTEXT_INTERNAL_H */ #endif /* AVUTIL_HWCONTEXT_INTERNAL_H */

Просмотреть файл

@ -118,6 +118,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = {
#endif #endif
MAP(UYVY, YUV422, UYVY422, 0), MAP(UYVY, YUV422, UYVY422, 0),
MAP(YUY2, YUV422, YUYV422, 0), MAP(YUY2, YUV422, YUYV422, 0),
#ifdef VA_FOURCC_Y210
MAP(Y210, YUV422_10, Y210, 0),
#endif
MAP(411P, YUV411, YUV411P, 0), MAP(411P, YUV411, YUV411P, 0),
MAP(422V, YUV422, YUV440P, 0), MAP(422V, YUV422, YUV440P, 0),
MAP(444P, YUV444, YUV444P, 0), MAP(444P, YUV444, YUV444P, 0),
@ -135,6 +138,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = {
#endif #endif
MAP(ARGB, RGB32, ARGB, 0), MAP(ARGB, RGB32, ARGB, 0),
MAP(XRGB, RGB32, 0RGB, 0), MAP(XRGB, RGB32, 0RGB, 0),
#ifdef VA_FOURCC_X2R10G10B10
MAP(X2R10G10B10, RGB32_10, X2RGB10, 0),
#endif
}; };
#undef MAP #undef MAP
@ -264,14 +270,24 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
} }
for (i = j = 0; i < attr_count; i++) { for (i = j = 0; i < attr_count; i++) {
int k;
if (attr_list[i].type != VASurfaceAttribPixelFormat) if (attr_list[i].type != VASurfaceAttribPixelFormat)
continue; continue;
fourcc = attr_list[i].value.value.i; fourcc = attr_list[i].value.value.i;
pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc);
if (pix_fmt != AV_PIX_FMT_NONE)
if (pix_fmt == AV_PIX_FMT_NONE)
continue;
for (k = 0; k < j; k++) {
if (constraints->valid_sw_formats[k] == pix_fmt)
break;
}
if (k == j)
constraints->valid_sw_formats[j++] = pix_fmt; constraints->valid_sw_formats[j++] = pix_fmt;
} }
av_assert0(j == pix_fmt_count);
constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE; constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE;
} }
} else { } else {
@ -283,9 +299,19 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
err = AVERROR(ENOMEM); err = AVERROR(ENOMEM);
goto fail; goto fail;
} }
for (i = 0; i < ctx->nb_formats; i++) for (i = j = 0; i < ctx->nb_formats; i++) {
constraints->valid_sw_formats[i] = ctx->formats[i].pix_fmt; int k;
constraints->valid_sw_formats[i] = AV_PIX_FMT_NONE;
for (k = 0; k < j; k++) {
if (constraints->valid_sw_formats[k] == ctx->formats[i].pix_fmt)
break;
}
if (k == j)
constraints->valid_sw_formats[j++] = ctx->formats[i].pix_fmt;
}
constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE;
} }
constraints->valid_hw_formats = av_malloc_array(2, sizeof(pix_fmt)); constraints->valid_hw_formats = av_malloc_array(2, sizeof(pix_fmt));
@ -440,7 +466,7 @@ static void vaapi_buffer_free(void *opaque, uint8_t *data)
} }
} }
static AVBufferRef *vaapi_pool_alloc(void *opaque, int size) static AVBufferRef *vaapi_pool_alloc(void *opaque, buffer_size_t size)
{ {
AVHWFramesContext *hwfc = opaque; AVHWFramesContext *hwfc = opaque;
VAAPIFramesContext *ctx = hwfc->internal->priv; VAAPIFramesContext *ctx = hwfc->internal->priv;
@ -1623,13 +1649,15 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device,
} }
static int vaapi_device_derive(AVHWDeviceContext *ctx, static int vaapi_device_derive(AVHWDeviceContext *ctx,
AVHWDeviceContext *src_ctx, int flags) AVHWDeviceContext *src_ctx,
AVDictionary *opts, int flags)
{ {
#if HAVE_VAAPI_DRM #if HAVE_VAAPI_DRM
if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) { if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) {
AVDRMDeviceContext *src_hwctx = src_ctx->hwctx; AVDRMDeviceContext *src_hwctx = src_ctx->hwctx;
VADisplay *display; VADisplay *display;
VAAPIDevicePriv *priv; VAAPIDevicePriv *priv;
int fd;
if (src_hwctx->fd < 0) { if (src_hwctx->fd < 0) {
av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated " av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated "
@ -1637,17 +1665,65 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx,
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
priv = av_mallocz(sizeof(*priv)); #if CONFIG_LIBDRM
if (!priv) {
return AVERROR(ENOMEM); int node_type = drmGetNodeTypeFromFd(src_hwctx->fd);
char *render_node;
if (node_type < 0) {
av_log(ctx, AV_LOG_ERROR, "DRM instance fd does not appear "
"to refer to a DRM device.\n");
return AVERROR(EINVAL);
}
if (node_type == DRM_NODE_RENDER) {
fd = src_hwctx->fd;
} else {
render_node = drmGetRenderDeviceNameFromFd(src_hwctx->fd);
if (!render_node) {
av_log(ctx, AV_LOG_VERBOSE, "Using non-render node "
"because the device does not have an "
"associated render node.\n");
fd = src_hwctx->fd;
} else {
fd = open(render_node, O_RDWR);
if (fd < 0) {
av_log(ctx, AV_LOG_VERBOSE, "Using non-render node "
"because the associated render node "
"could not be opened.\n");
fd = src_hwctx->fd;
} else {
av_log(ctx, AV_LOG_VERBOSE, "Using render node %s "
"in place of non-render DRM device.\n",
render_node);
}
free(render_node);
}
}
}
#else
fd = src_hwctx->fd;
#endif
// Inherits the fd from the source context, which will close it. priv = av_mallocz(sizeof(*priv));
priv->drm_fd = -1; if (!priv) {
if (fd != src_hwctx->fd) {
// The fd was opened in this function.
close(fd);
}
return AVERROR(ENOMEM);
}
if (fd == src_hwctx->fd) {
// The fd is inherited from the source context and we are holding
// a reference to that, we don't want to close it from here.
priv->drm_fd = -1;
} else {
priv->drm_fd = fd;
}
ctx->user_opaque = priv; ctx->user_opaque = priv;
ctx->free = &vaapi_device_free; ctx->free = &vaapi_device_free;
display = vaGetDisplayDRM(src_hwctx->fd); display = vaGetDisplayDRM(fd);
if (!display) { if (!display) {
av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from " av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from "
"DRM device.\n"); "DRM device.\n");

Просмотреть файл

@ -108,45 +108,69 @@ int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int wi
return 0; return 0;
} }
int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, int av_image_fill_plane_sizes(size_t sizes[4], enum AVPixelFormat pix_fmt,
uint8_t *ptr, const int linesizes[4]) int height, const ptrdiff_t linesizes[4])
{ {
int i, total_size, size[4] = { 0 }, has_plane[4] = { 0 }; int i, has_plane[4] = { 0 };
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
memset(data , 0, sizeof(data[0])*4); memset(sizes , 0, sizeof(sizes[0])*4);
if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
return AVERROR(EINVAL); return AVERROR(EINVAL);
data[0] = ptr; if (linesizes[0] > SIZE_MAX / height)
if (linesizes[0] > (INT_MAX - 1024) / height)
return AVERROR(EINVAL); return AVERROR(EINVAL);
size[0] = linesizes[0] * height; sizes[0] = linesizes[0] * (size_t)height;
if (desc->flags & AV_PIX_FMT_FLAG_PAL || if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
desc->flags & FF_PSEUDOPAL) { desc->flags & FF_PSEUDOPAL) {
data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */ sizes[1] = 256 * 4; /* palette is stored here as 256 32 bits words */
return size[0] + 256 * 4; return 0;
} }
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
has_plane[desc->comp[i].plane] = 1; has_plane[desc->comp[i].plane] = 1;
total_size = size[0];
for (i = 1; i < 4 && has_plane[i]; i++) { for (i = 1; i < 4 && has_plane[i]; i++) {
int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
data[i] = data[i-1] + size[i-1];
h = (height + (1 << s) - 1) >> s; h = (height + (1 << s) - 1) >> s;
if (linesizes[i] > INT_MAX / h) if (linesizes[i] > SIZE_MAX / h)
return AVERROR(EINVAL); return AVERROR(EINVAL);
size[i] = h * linesizes[i]; sizes[i] = (size_t)h * linesizes[i];
if (total_size > INT_MAX - size[i])
return AVERROR(EINVAL);
total_size += size[i];
} }
return total_size; return 0;
}
int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height,
uint8_t *ptr, const int linesizes[4])
{
int i, ret;
ptrdiff_t linesizes1[4];
size_t sizes[4];
memset(data , 0, sizeof(data[0])*4);
for (i = 0; i < 4; i++)
linesizes1[i] = linesizes[i];
ret = av_image_fill_plane_sizes(sizes, pix_fmt, height, linesizes1);
if (ret < 0)
return ret;
ret = 0;
for (i = 0; i < 4; i++) {
if (sizes[i] > INT_MAX - ret)
return AVERROR(EINVAL);
ret += sizes[i];
}
data[0] = ptr;
for (i = 1; i < 4 && sizes[i]; i++)
data[i] = data[i - 1] + sizes[i - 1];
return ret;
} }
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt) int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
@ -194,6 +218,8 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
{ {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
int i, ret; int i, ret;
ptrdiff_t linesizes1[4];
size_t total_size, sizes[4];
uint8_t *buf; uint8_t *buf;
if (!desc) if (!desc)
@ -204,12 +230,20 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, align>7 ? FFALIGN(w, 8) : w)) < 0) if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, align>7 ? FFALIGN(w, 8) : w)) < 0)
return ret; return ret;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++) {
linesizes[i] = FFALIGN(linesizes[i], align); linesizes[i] = FFALIGN(linesizes[i], align);
linesizes1[i] = linesizes[i];
}
if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, NULL, linesizes)) < 0) if ((ret = av_image_fill_plane_sizes(sizes, pix_fmt, h, linesizes1)) < 0)
return ret; return ret;
buf = av_malloc(ret + align); total_size = align;
for (i = 0; i < 4; i++) {
if (total_size > SIZE_MAX - sizes[i])
return AVERROR(EINVAL);
total_size += sizes[i];
}
buf = av_malloc(total_size);
if (!buf) if (!buf)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, buf, linesizes)) < 0) { if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, buf, linesizes)) < 0) {
@ -220,6 +254,7 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt); avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt);
if (align < 4) { if (align < 4) {
av_log(NULL, AV_LOG_ERROR, "Formats with a palette require a minimum alignment of 4\n"); av_log(NULL, AV_LOG_ERROR, "Formats with a palette require a minimum alignment of 4\n");
av_free(buf);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
} }
@ -431,9 +466,10 @@ int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int av_image_get_buffer_size(enum AVPixelFormat pix_fmt,
int width, int height, int align) int width, int height, int align)
{ {
uint8_t *data[4]; int ret, i;
int linesize[4]; int linesize[4];
int ret; ptrdiff_t aligned_linesize[4];
size_t sizes[4];
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
if (!desc) if (!desc)
return AVERROR(EINVAL); return AVERROR(EINVAL);
@ -446,8 +482,24 @@ int av_image_get_buffer_size(enum AVPixelFormat pix_fmt,
if (desc->flags & FF_PSEUDOPAL) if (desc->flags & FF_PSEUDOPAL)
return FFALIGN(width, align) * height; return FFALIGN(width, align) * height;
return av_image_fill_arrays(data, linesize, NULL, pix_fmt, ret = av_image_fill_linesizes(linesize, pix_fmt, width);
width, height, align); if (ret < 0)
return ret;
for (i = 0; i < 4; i++)
aligned_linesize[i] = FFALIGN(linesize[i], align);
ret = av_image_fill_plane_sizes(sizes, pix_fmt, height, aligned_linesize);
if (ret < 0)
return ret;
ret = 0;
for (i = 0; i < 4; i++) {
if (sizes[i] > INT_MAX - ret)
return AVERROR(EINVAL);
ret += sizes[i];
}
return ret;
} }
int av_image_copy_to_buffer(uint8_t *dst, int dst_size, int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
@ -519,7 +571,6 @@ static void memset_bytes(uint8_t *dst, size_t dst_size, uint8_t *clear,
if (clear_size == 1) { if (clear_size == 1) {
memset(dst, clear[0], dst_size); memset(dst, clear[0], dst_size);
dst_size = 0;
} else { } else {
if (clear_size > dst_size) if (clear_size > dst_size)
clear_size = dst_size; clear_size = dst_size;

Просмотреть файл

@ -67,6 +67,20 @@ int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane);
*/ */
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width); int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width);
/**
* Fill plane sizes for an image with pixel format pix_fmt and height height.
*
* @param size the array to be filled with the size of each image plane
* @param linesizes the array containing the linesize for each
* plane, should be filled by av_image_fill_linesizes()
* @return >= 0 in case of success, a negative error code otherwise
*
* @note The linesize parameters have the type ptrdiff_t here, while they are
* int for av_image_fill_linesizes().
*/
int av_image_fill_plane_sizes(size_t size[4], enum AVPixelFormat pix_fmt,
int height, const ptrdiff_t linesizes[4]);
/** /**
* Fill plane data pointers for an image with pixel format pix_fmt and * Fill plane data pointers for an image with pixel format pix_fmt and
* height height. * height height.

Просмотреть файл

@ -43,7 +43,6 @@
#include "cpu.h" #include "cpu.h"
#include "dict.h" #include "dict.h"
#include "macros.h" #include "macros.h"
#include "mem.h"
#include "pixfmt.h" #include "pixfmt.h"
#include "version.h" #include "version.h"
@ -92,10 +91,6 @@
type av_##name##_get_##field(const str *s) { return s->field; } \ type av_##name##_get_##field(const str *s) { return s->field; } \
void av_##name##_set_##field(str *s, type v) { s->field = v; } void av_##name##_set_##field(str *s, type v) { s->field = v; }
// Some broken preprocessors need a second expansion
// to be forced to tokenize __VA_ARGS__
#define E1(x) x
/* Check if the hard coded offset of a struct member still matches reality. /* Check if the hard coded offset of a struct member still matches reality.
* Induce a compilation failure if not. * Induce a compilation failure if not.
*/ */
@ -103,75 +98,11 @@
int x_##o[offsetof(s, m) == o? 1: -1]; \ int x_##o[offsetof(s, m) == o? 1: -1]; \
} }
#define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \
uint8_t la_##v[sizeof(t s o) + (a)]; \
t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
#define LOCAL_ALIGNED_D(a, t, v, s, o, ...) \ #define FF_ALLOC_TYPED_ARRAY(p, nelem) (p = av_malloc_array(nelem, sizeof(*p)))
DECLARE_ALIGNED(a, t, la_##v) s o; \ #define FF_ALLOCZ_TYPED_ARRAY(p, nelem) (p = av_mallocz_array(nelem, sizeof(*p)))
t (*v) o = la_##v
#define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__) #define FF_PTR_ADD(ptr, off) ((off) ? (ptr) + (off) : (ptr))
#if HAVE_LOCAL_ALIGNED
# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,))
#else
# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,))
#endif
#if HAVE_LOCAL_ALIGNED
# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
#else
# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,))
#endif
#if HAVE_LOCAL_ALIGNED
# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
#else
# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,))
#endif
#if HAVE_LOCAL_ALIGNED
# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,))
#else
# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,))
#endif
#define FF_ALLOC_OR_GOTO(ctx, p, size, label)\
{\
p = av_malloc(size);\
if (!(p) && (size) != 0) {\
av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
goto label;\
}\
}
#define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)\
{\
p = av_mallocz(size);\
if (!(p) && (size) != 0) {\
av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
goto label;\
}\
}
#define FF_ALLOC_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\
{\
p = av_malloc_array(nelem, elsize);\
if (!p) {\
av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
goto label;\
}\
}
#define FF_ALLOCZ_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\
{\
p = av_mallocz_array(nelem, elsize);\
if (!p) {\
av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\
goto label;\
}\
}
#include "libm.h" #include "libm.h"
@ -353,7 +284,8 @@ void ff_check_pixfmt_descriptors(void);
/** /**
* Set a dictionary value to an ISO-8601 compliant timestamp string. * Set a dictionary value to an ISO-8601 compliant timestamp string.
* *
* @param s AVFormatContext * @param dict pointer to a pointer to a dictionary struct. If *dict is NULL
* a dictionary struct is allocated and put in *dict.
* @param key metadata key * @param key metadata key
* @param timestamp unix timestamp in microseconds * @param timestamp unix timestamp in microseconds
* @return <0 on error * @return <0 on error
@ -369,4 +301,11 @@ int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t time
#define FF_PSEUDOPAL 0 #define FF_PSEUDOPAL 0
#endif #endif
// Temporary typedef to simplify porting all AVBufferRef users to size_t
#if FF_API_BUFFER_SIZE_T
typedef int buffer_size_t;
#else
typedef size_t buffer_size_t;
#endif
#endif /* AVUTIL_INTERNAL_H */ #endif /* AVUTIL_INTERNAL_H */

Просмотреть файл

@ -24,7 +24,7 @@
#define AVUTIL_LLS_H #define AVUTIL_LLS_H
#include "macros.h" #include "macros.h"
#include "mem.h" #include "mem_internal.h"
#include "version.h" #include "version.h"
#define MAX_VARS 32 #define MAX_VARS 32

Просмотреть файл

@ -55,7 +55,7 @@ static int av_log_level = AV_LOG_INFO;
static int flags; static int flags;
#define NB_LEVELS 8 #define NB_LEVELS 8
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE #if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
#include <windows.h> #include <windows.h>
static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = { static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = {
[AV_LOG_PANIC /8] = 12, [AV_LOG_PANIC /8] = 12,
@ -120,50 +120,68 @@ static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = {
#endif #endif
static int use_color = -1; static int use_color = -1;
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
static void win_console_puts(const char *str)
{
const uint8_t *q = str;
uint16_t line[LINE_SZ];
while (*q) {
uint16_t *buf = line;
DWORD nb_chars = 0;
DWORD written;
while (*q && nb_chars < LINE_SZ - 1) {
uint32_t ch;
uint16_t tmp;
GET_UTF8(ch, *q ? *q++ : 0, ch = 0xfffd; goto continue_on_invalid;)
continue_on_invalid:
PUT_UTF16(ch, tmp, *buf++ = tmp; nb_chars++;)
}
WriteConsoleW(con, line, nb_chars, &written, NULL);
}
}
#endif
static void check_color_terminal(void) static void check_color_terminal(void)
{ {
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE char *term = getenv("TERM");
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
CONSOLE_SCREEN_BUFFER_INFO con_info; CONSOLE_SCREEN_BUFFER_INFO con_info;
DWORD dummy;
con = GetStdHandle(STD_ERROR_HANDLE); con = GetStdHandle(STD_ERROR_HANDLE);
use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") && if (con != INVALID_HANDLE_VALUE && !GetConsoleMode(con, &dummy))
!getenv("AV_LOG_FORCE_NOCOLOR"); con = INVALID_HANDLE_VALUE;
if (use_color) { if (con != INVALID_HANDLE_VALUE) {
GetConsoleScreenBufferInfo(con, &con_info); GetConsoleScreenBufferInfo(con, &con_info);
attr_orig = con_info.wAttributes; attr_orig = con_info.wAttributes;
background = attr_orig & 0xF0; background = attr_orig & 0xF0;
} }
#elif HAVE_ISATTY
char *term = getenv("TERM");
use_color = !getenv("NO_COLOR") && !getenv("AV_LOG_FORCE_NOCOLOR") &&
(getenv("TERM") && isatty(2) || getenv("AV_LOG_FORCE_COLOR"));
if ( getenv("AV_LOG_FORCE_256COLOR")
|| (term && strstr(term, "256color")))
use_color *= 256;
#else
use_color = getenv("AV_LOG_FORCE_COLOR") && !getenv("NO_COLOR") &&
!getenv("AV_LOG_FORCE_NOCOLOR");
#endif #endif
if (getenv("AV_LOG_FORCE_NOCOLOR")) {
use_color = 0;
} else if (getenv("AV_LOG_FORCE_COLOR")) {
use_color = 1;
} else {
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
use_color = (con != INVALID_HANDLE_VALUE);
#elif HAVE_ISATTY
use_color = (term && isatty(2));
#else
use_color = 0;
#endif
}
if (getenv("AV_LOG_FORCE_256COLOR") || term && strstr(term, "256color"))
use_color *= 256;
} }
static void colored_fputs(int level, int tint, const char *str) static void ansi_fputs(int level, int tint, const char *str, int local_use_color)
{ {
int local_use_color;
if (!*str)
return;
if (use_color < 0)
check_color_terminal();
if (level == AV_LOG_INFO/8) local_use_color = 0;
else local_use_color = use_color;
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE
if (local_use_color)
SetConsoleTextAttribute(con, background | color[level]);
fputs(str, stderr);
if (local_use_color)
SetConsoleTextAttribute(con, attr_orig);
#else
if (local_use_color == 1) { if (local_use_color == 1) {
fprintf(stderr, fprintf(stderr,
"\033[%"PRIu32";3%"PRIu32"m%s\033[0m", "\033[%"PRIu32";3%"PRIu32"m%s\033[0m",
@ -184,6 +202,32 @@ static void colored_fputs(int level, int tint, const char *str)
str); str);
} else } else
fputs(str, stderr); fputs(str, stderr);
}
static void colored_fputs(int level, int tint, const char *str)
{
int local_use_color;
if (!*str)
return;
if (use_color < 0)
check_color_terminal();
if (level == AV_LOG_INFO/8) local_use_color = 0;
else local_use_color = use_color;
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
if (con != INVALID_HANDLE_VALUE) {
if (local_use_color)
SetConsoleTextAttribute(con, background | color[level]);
win_console_puts(str);
if (local_use_color)
SetConsoleTextAttribute(con, attr_orig);
} else {
ansi_fputs(level, tint, str, local_use_color);
}
#else
ansi_fputs(level, tint, str, local_use_color);
#endif #endif
} }
@ -226,6 +270,8 @@ static const char *get_level_str(int level)
return "quiet"; return "quiet";
case AV_LOG_DEBUG: case AV_LOG_DEBUG:
return "debug"; return "debug";
case AV_LOG_TRACE:
return "trace";
case AV_LOG_VERBOSE: case AV_LOG_VERBOSE:
return "verbose"; return "verbose";
case AV_LOG_INFO: case AV_LOG_INFO:
@ -360,19 +406,28 @@ static void (*av_log_callback)(void*, int, const char*, va_list) =
void av_log(void* avcl, int level, const char *fmt, ...) void av_log(void* avcl, int level, const char *fmt, ...)
{ {
AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
va_list vl; va_list vl;
va_start(vl, fmt); va_start(vl, fmt);
if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
avc->log_level_offset_offset && level >= AV_LOG_FATAL)
level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
av_vlog(avcl, level, fmt, vl); av_vlog(avcl, level, fmt, vl);
va_end(vl); va_end(vl);
} }
void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...)
{
va_list vl;
va_start(vl, fmt);
av_vlog(avcl, *state ? subsequent_level : initial_level, fmt, vl);
va_end(vl);
*state = 1;
}
void av_vlog(void* avcl, int level, const char *fmt, va_list vl) void av_vlog(void* avcl, int level, const char *fmt, va_list vl)
{ {
AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
void (*log_callback)(void*, int, const char*, va_list) = av_log_callback; void (*log_callback)(void*, int, const char*, va_list) = av_log_callback;
if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
avc->log_level_offset_offset && level >= AV_LOG_FATAL)
level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
if (log_callback) if (log_callback)
log_callback(avcl, level, fmt, vl); log_callback(avcl, level, fmt, vl);
} }
@ -412,7 +467,7 @@ static void missing_feature_sample(int sample, void *avc, const char *msg,
"been implemented.\n"); "been implemented.\n");
if (sample) if (sample)
av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample " av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample "
"of this file to ftp://upload.ffmpeg.org/incoming/ " "of this file to https://streams.videolan.org/upload/ "
"and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n"); "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n");
} }

Просмотреть файл

@ -112,6 +112,7 @@ typedef struct AVClass {
*/ */
void* (*child_next)(void *obj, void *prev); void* (*child_next)(void *obj, void *prev);
#if FF_API_CHILD_CLASS_NEXT
/** /**
* Return an AVClass corresponding to the next potential * Return an AVClass corresponding to the next potential
* AVOptions-enabled child. * AVOptions-enabled child.
@ -120,7 +121,9 @@ typedef struct AVClass {
* child_next iterates over _already existing_ objects, while * child_next iterates over _already existing_ objects, while
* child_class_next iterates over _all possible_ children. * child_class_next iterates over _all possible_ children.
*/ */
attribute_deprecated
const struct AVClass* (*child_class_next)(const struct AVClass *prev); const struct AVClass* (*child_class_next)(const struct AVClass *prev);
#endif
/** /**
* Category used for visualization (like color) * Category used for visualization (like color)
@ -140,6 +143,21 @@ typedef struct AVClass {
* available since version (52.12) * available since version (52.12)
*/ */
int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags);
/**
* Iterate over the AVClasses corresponding to potential AVOptions-enabled
* children.
*
* @param iter pointer to opaque iteration state. The caller must initialize
* *iter to NULL before the first call.
* @return AVClass for the next AVOptions-enabled child or NULL if there are
* no more such children.
*
* @note The difference between child_next and this is that child_next
* iterates over _already existing_ objects, while child_class_iterate
* iterates over _all possible_ children.
*/
const struct AVClass* (*child_class_iterate)(void **iter);
} AVClass; } AVClass;
/** /**
@ -233,6 +251,27 @@ typedef struct AVClass {
*/ */
void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4); void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4);
/**
* Send the specified message to the log once with the initial_level and then with
* the subsequent_level. By default, all logging messages are sent to
* stderr. This behavior can be altered by setting a different logging callback
* function.
* @see av_log
*
* @param avcl A pointer to an arbitrary struct of which the first field is a
* pointer to an AVClass struct or NULL if general log.
* @param initial_level importance level of the message expressed using a @ref
* lavu_log_constants "Logging Constant" for the first occurance.
* @param subsequent_level importance level of the message expressed using a @ref
* lavu_log_constants "Logging Constant" after the first occurance.
* @param fmt The format string (printf-compatible) that specifies how
* subsequent arguments are converted to output.
* @param state a variable to keep trak of if a message has already been printed
* this must be initialized to 0 before the first use. The same state
* must not be accessed by 2 Threads simultaneously.
*/
void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...) av_printf_format(5, 6);
/** /**
* Send the specified message to the log if the level is less than or equal * Send the specified message to the log if the level is less than or equal

Просмотреть файл

@ -148,7 +148,7 @@ int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
{ {
int64_t a = tb_a.num * (int64_t)tb_b.den; int64_t a = tb_a.num * (int64_t)tb_b.den;
int64_t b = tb_b.num * (int64_t)tb_a.den; int64_t b = tb_b.num * (int64_t)tb_a.den;
if ((FFABS(ts_a)|a|FFABS(ts_b)|b) <= INT_MAX) if ((FFABS64U(ts_a)|a|FFABS64U(ts_b)|b) <= INT_MAX)
return (ts_a*a > ts_b*b) - (ts_a*a < ts_b*b); return (ts_a*a > ts_b*b) - (ts_a*a < ts_b*b);
if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b) if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b)
return -1; return -1;
@ -198,7 +198,7 @@ int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t i
m = inc_tb.num * (int64_t)ts_tb.den; m = inc_tb.num * (int64_t)ts_tb.den;
d = inc_tb.den * (int64_t)ts_tb.num; d = inc_tb.den * (int64_t)ts_tb.num;
if (m % d == 0) if (m % d == 0 && ts <= INT64_MAX - m / d)
return ts + m / d; return ts + m / d;
if (m < d) if (m < d)
return ts; return ts;
@ -206,6 +206,10 @@ int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t i
{ {
int64_t old = av_rescale_q(ts, ts_tb, inc_tb); int64_t old = av_rescale_q(ts, ts_tb, inc_tb);
int64_t old_ts = av_rescale_q(old, inc_tb, ts_tb); int64_t old_ts = av_rescale_q(old, inc_tb, ts_tb);
return av_rescale_q(old + 1, inc_tb, ts_tb) + (ts - old_ts);
if (old == INT64_MAX || old == AV_NOPTS_VALUE || old_ts == AV_NOPTS_VALUE)
return ts;
return av_sat_add64(av_rescale_q(old + 1, inc_tb, ts_tb), ts - old_ts);
} }
} }

Просмотреть файл

@ -134,6 +134,7 @@ int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const;
* *
* The operation is mathematically equivalent to `a * b / c`, but writing that * The operation is mathematically equivalent to `a * b / c`, but writing that
* directly can overflow, and does not support different rounding methods. * directly can overflow, and does not support different rounding methods.
* If the result is not representable then INT64_MIN is returned.
* *
* @see av_rescale(), av_rescale_q(), av_rescale_q_rnd() * @see av_rescale(), av_rescale_q(), av_rescale_q_rnd()
*/ */

Просмотреть файл

@ -78,8 +78,7 @@ void *av_malloc(size_t size)
{ {
void *ptr = NULL; void *ptr = NULL;
/* let's disallow possibly ambiguous cases */ if (size > max_alloc_size)
if (size > (max_alloc_size - 32))
return NULL; return NULL;
#if HAVE_POSIX_MEMALIGN #if HAVE_POSIX_MEMALIGN
@ -134,8 +133,7 @@ void *av_malloc(size_t size)
void *av_realloc(void *ptr, size_t size) void *av_realloc(void *ptr, size_t size)
{ {
/* let's disallow possibly ambiguous cases */ if (size > max_alloc_size)
if (size > (max_alloc_size - 32))
return NULL; return NULL;
#if HAVE_ALIGNED_MALLOC #if HAVE_ALIGNED_MALLOC
@ -183,23 +181,26 @@ int av_reallocp(void *ptr, size_t size)
void *av_malloc_array(size_t nmemb, size_t size) void *av_malloc_array(size_t nmemb, size_t size)
{ {
if (!size || nmemb >= INT_MAX / size) size_t result;
if (av_size_mult(nmemb, size, &result) < 0)
return NULL; return NULL;
return av_malloc(nmemb * size); return av_malloc(result);
} }
void *av_mallocz_array(size_t nmemb, size_t size) void *av_mallocz_array(size_t nmemb, size_t size)
{ {
if (!size || nmemb >= INT_MAX / size) size_t result;
if (av_size_mult(nmemb, size, &result) < 0)
return NULL; return NULL;
return av_mallocz(nmemb * size); return av_mallocz(result);
} }
void *av_realloc_array(void *ptr, size_t nmemb, size_t size) void *av_realloc_array(void *ptr, size_t nmemb, size_t size)
{ {
if (!size || nmemb >= INT_MAX / size) size_t result;
if (av_size_mult(nmemb, size, &result) < 0)
return NULL; return NULL;
return av_realloc(ptr, nmemb * size); return av_realloc(ptr, result);
} }
int av_reallocp_array(void *ptr, size_t nmemb, size_t size) int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
@ -243,9 +244,10 @@ void *av_mallocz(size_t size)
void *av_calloc(size_t nmemb, size_t size) void *av_calloc(size_t nmemb, size_t size)
{ {
if (size <= 0 || nmemb >= INT_MAX / size) size_t result;
if (av_size_mult(nmemb, size, &result) < 0)
return NULL; return NULL;
return av_mallocz(nmemb * size); return av_mallocz(result);
} }
char *av_strdup(const char *s) char *av_strdup(const char *s)
@ -478,12 +480,12 @@ void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
if (min_size <= *size) if (min_size <= *size)
return ptr; return ptr;
if (min_size > max_alloc_size - 32) { if (min_size > max_alloc_size) {
*size = 0; *size = 0;
return NULL; return NULL;
} }
min_size = FFMIN(max_alloc_size - 32, FFMAX(min_size + min_size / 16 + 32, min_size)); min_size = FFMIN(max_alloc_size, FFMAX(min_size + min_size / 16 + 32, min_size));
ptr = av_realloc(ptr, min_size); ptr = av_realloc(ptr, min_size);
/* we could set this to the unmodified min_size but this is safer /* we could set this to the unmodified min_size but this is safer

Просмотреть файл

@ -33,6 +33,7 @@
#include "attributes.h" #include "attributes.h"
#include "error.h" #include "error.h"
#include "avutil.h" #include "avutil.h"
#include "version.h"
/** /**
* @addtogroup lavu_mem * @addtogroup lavu_mem
@ -49,6 +50,10 @@
* dealing with memory consistently possible on all platforms. * dealing with memory consistently possible on all platforms.
* *
* @{ * @{
*/
#if FF_API_DECLARE_ALIGNED
/**
* *
* @defgroup lavu_mem_macros Alignment Macros * @defgroup lavu_mem_macros Alignment Macros
* Helper macros for declaring aligned variables. * Helper macros for declaring aligned variables.
@ -125,6 +130,7 @@
/** /**
* @} * @}
*/ */
#endif
/** /**
* @defgroup lavu_mem_attrs Function Attributes * @defgroup lavu_mem_attrs Function Attributes

Просмотреть файл

@ -21,8 +21,120 @@
#ifndef AVUTIL_MEM_INTERNAL_H #ifndef AVUTIL_MEM_INTERNAL_H
#define AVUTIL_MEM_INTERNAL_H #define AVUTIL_MEM_INTERNAL_H
#include "config.h"
#include <stdint.h>
#include "avassert.h" #include "avassert.h"
#include "mem.h" #include "mem.h"
#include "version.h"
#if !FF_API_DECLARE_ALIGNED
/**
* @def DECLARE_ALIGNED(n,t,v)
* Declare a variable that is aligned in memory.
*
* @code{.c}
* DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42;
* DECLARE_ALIGNED(32, uint8_t, aligned_array)[128];
*
* // The default-alignment equivalent would be
* uint16_t aligned_int = 42;
* uint8_t aligned_array[128];
* @endcode
*
* @param n Minimum alignment in bytes
* @param t Type of the variable (or array element)
* @param v Name of the variable
*/
/**
* @def DECLARE_ASM_ALIGNED(n,t,v)
* Declare an aligned variable appropriate for use in inline assembly code.
*
* @code{.c}
* DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008);
* @endcode
*
* @param n Minimum alignment in bytes
* @param t Type of the variable (or array element)
* @param v Name of the variable
*/
/**
* @def DECLARE_ASM_CONST(n,t,v)
* Declare a static constant aligned variable appropriate for use in inline
* assembly code.
*
* @code{.c}
* DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008);
* @endcode
*
* @param n Minimum alignment in bytes
* @param t Type of the variable (or array element)
* @param v Name of the variable
*/
#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C)
#define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
#define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
#define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v
#elif defined(__DJGPP__)
#define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v
#define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v
#define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v
#elif defined(__GNUC__) || defined(__clang__)
#define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
#define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v
#define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v
#elif defined(_MSC_VER)
#define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v
#define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v
#define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v
#else
#define DECLARE_ALIGNED(n,t,v) t v
#define DECLARE_ASM_ALIGNED(n,t,v) t v
#define DECLARE_ASM_CONST(n,t,v) static const t v
#endif
#endif
// Some broken preprocessors need a second expansion
// to be forced to tokenize __VA_ARGS__
#define E1(x) x
#define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \
uint8_t la_##v[sizeof(t s o) + (a)]; \
t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
#define LOCAL_ALIGNED_D(a, t, v, s, o, ...) \
DECLARE_ALIGNED(a, t, la_##v) s o; \
t (*v) o = la_##v
#define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__)
#if HAVE_LOCAL_ALIGNED
# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,))
#else
# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,))
#endif
#if HAVE_LOCAL_ALIGNED
# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
#else
# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,))
#endif
#if HAVE_LOCAL_ALIGNED
# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
#else
# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,))
#endif
#if HAVE_LOCAL_ALIGNED
# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,))
#else
# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,))
#endif
static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
{ {

Просмотреть файл

@ -47,7 +47,7 @@ SOURCES += [
] ]
if CONFIG['MOZ_WAYLAND']: if CONFIG['MOZ_WAYLAND']:
SOURCES += [ SOURCES += [
'hwcontext_vaapi.c', 'hwcontext_vaapi.c'
] ]
USE_LIBS += ['mozva'] USE_LIBS += ['mozva']
@ -56,12 +56,14 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
'adler32.c', 'adler32.c',
'base64.c', 'base64.c',
'color_utils.c', 'color_utils.c',
'film_grain_params.c',
'integer.c', 'integer.c',
'intmath.c', 'intmath.c',
'lls.c', 'lls.c',
'pixelutils.c', 'pixelutils.c',
'threadmessage.c', 'threadmessage.c',
'timecode.c' 'timecode.c',
'video_enc_params.c'
] ]
SYMBOLS_FILE = 'avutil.symbols' SYMBOLS_FILE = 'avutil.symbols'

Просмотреть файл

@ -229,13 +229,15 @@ 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) static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
{ {
int ret = 0; int ret = 0;
int num, den;
char c;
if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) { if (o->type == AV_OPT_TYPE_RATIONAL || o->type == AV_OPT_TYPE_VIDEO_RATE) {
if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0) int num, den;
return ret; char c;
ret = 0; if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0)
return ret;
ret = 0;
}
} }
for (;;) { for (;;) {
@ -254,11 +256,12 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
} }
{ {
const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, 0);
int res; int res;
int ci = 0; int ci = 0;
double const_values[64]; double const_values[64];
const char * const_names[64]; const char * const_names[64];
int search_flags = (o->flags & AV_OPT_FLAG_CHILD_CONSTS) ? AV_OPT_SEARCH_CHILDREN : 0;
const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, search_flags);
if (o_named && o_named->type == AV_OPT_TYPE_CONST) if (o_named && o_named->type == AV_OPT_TYPE_CONST)
d = DEFAULT_NUMVAL(o_named); d = DEFAULT_NUMVAL(o_named);
else { else {
@ -330,12 +333,7 @@ static int set_string_image_size(void *obj, const AVOption *o, const char *val,
static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst) static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst)
{ {
int ret; int ret = av_parse_video_rate(dst, val);
if (!val) {
ret = AVERROR(EINVAL);
} else {
ret = av_parse_video_rate(dst, val);
}
if (ret < 0) if (ret < 0)
av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
return ret; return ret;
@ -446,6 +444,24 @@ static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val,
AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format"); AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format");
} }
static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst)
{
AVDictionary *options = NULL;
if (val) {
int ret = av_dict_parse_string(&options, val, "=", ":", 0);
if (ret < 0) {
av_dict_free(&options);
return ret;
}
}
av_dict_free((AVDictionary **)dst);
*dst = (uint8_t *)options;
return 0;
}
int av_opt_set(void *obj, const char *name, const char *val, int search_flags) int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
{ {
int ret = 0; int ret = 0;
@ -455,7 +471,7 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
return AVERROR_OPTION_NOT_FOUND; return AVERROR_OPTION_NOT_FOUND;
if (!val && (o->type != AV_OPT_TYPE_STRING && 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_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE && o->type != AV_OPT_TYPE_IMAGE_SIZE &&
o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR && o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL)) o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL))
return AVERROR(EINVAL); return AVERROR(EINVAL);
@ -527,6 +543,8 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
return ret; return ret;
} }
break; break;
case AV_OPT_TYPE_DICT:
return set_string_dict(obj, o, val, dst);
} }
av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
@ -855,6 +873,12 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
i64 = *(int64_t *)dst; i64 = *(int64_t *)dst;
ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64); ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
break; break;
case AV_OPT_TYPE_DICT:
if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
*out_val = NULL;
return 0;
}
return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, '=', ':');
default: default:
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
@ -1034,6 +1058,23 @@ int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
return res & flag->default_val.i64; return res & flag->default_val.i64;
} }
static void log_int_value(void *av_log_obj, int level, int64_t i)
{
if (i == INT_MAX) {
av_log(av_log_obj, level, "INT_MAX");
} else if (i == INT_MIN) {
av_log(av_log_obj, level, "INT_MIN");
} else if (i == UINT32_MAX) {
av_log(av_log_obj, level, "UINT32_MAX");
} else if (i == INT64_MAX) {
av_log(av_log_obj, level, "I64_MAX");
} else if (i == INT64_MIN) {
av_log(av_log_obj, level, "I64_MIN");
} else {
av_log(av_log_obj, level, "%"PRId64, i);
}
}
static void log_value(void *av_log_obj, int level, double d) static void log_value(void *av_log_obj, int level, double d)
{ {
if (d == INT_MAX) { if (d == INT_MAX) {
@ -1102,7 +1143,7 @@ static char *get_opt_flags_string(void *obj, const char *unit, int64_t value)
} }
static void opt_list(void *obj, void *av_log_obj, const char *unit, static void opt_list(void *obj, void *av_log_obj, const char *unit,
int req_flags, int rej_flags) int req_flags, int rej_flags, enum AVOptionType parent_type)
{ {
const AVOption *opt = NULL; const AVOption *opt = NULL;
AVOptionRanges *r; AVOptionRanges *r;
@ -1157,6 +1198,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
case AV_OPT_TYPE_BINARY: case AV_OPT_TYPE_BINARY:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>"); av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
break; break;
case AV_OPT_TYPE_DICT:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<dictionary>");
break;
case AV_OPT_TYPE_IMAGE_SIZE: case AV_OPT_TYPE_IMAGE_SIZE:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>"); av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
break; break;
@ -1182,6 +1226,11 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>"); av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>");
break; break;
case AV_OPT_TYPE_CONST: 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: default:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
break; break;
@ -1195,6 +1244,8 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.');
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.');
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.');
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_RUNTIME_PARAM) ? 'T' : '.');
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DEPRECATED) ? 'P' : '.');
if (opt->help) if (opt->help)
av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
@ -1224,6 +1275,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
!((opt->type == AV_OPT_TYPE_COLOR || !((opt->type == AV_OPT_TYPE_COLOR ||
opt->type == AV_OPT_TYPE_IMAGE_SIZE || opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
opt->type == AV_OPT_TYPE_STRING || opt->type == AV_OPT_TYPE_STRING ||
opt->type == AV_OPT_TYPE_DICT ||
opt->type == AV_OPT_TYPE_VIDEO_RATE) && opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
!opt->default_val.str)) { !opt->default_val.str)) {
av_log(av_log_obj, AV_LOG_INFO, " (default "); av_log(av_log_obj, AV_LOG_INFO, " (default ");
@ -1254,7 +1306,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
if (def_const) if (def_const)
av_log(av_log_obj, AV_LOG_INFO, "%s", def_const); av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
else else
log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64); log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
break; break;
} }
case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_DOUBLE:
@ -1274,6 +1326,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
case AV_OPT_TYPE_COLOR: case AV_OPT_TYPE_COLOR:
case AV_OPT_TYPE_IMAGE_SIZE: case AV_OPT_TYPE_IMAGE_SIZE:
case AV_OPT_TYPE_STRING: case AV_OPT_TYPE_STRING:
case AV_OPT_TYPE_DICT:
case AV_OPT_TYPE_VIDEO_RATE: case AV_OPT_TYPE_VIDEO_RATE:
av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
break; break;
@ -1286,7 +1339,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
av_log(av_log_obj, AV_LOG_INFO, "\n"); av_log(av_log_obj, AV_LOG_INFO, "\n");
if (opt->unit && opt->type != AV_OPT_TYPE_CONST) if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags); opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags, opt->type);
} }
} }
@ -1297,7 +1350,7 @@ int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name); av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name);
opt_list(obj, av_log_obj, NULL, req_flags, rej_flags); opt_list(obj, av_log_obj, NULL, req_flags, rej_flags, -1);
return 0; return 0;
} }
@ -1363,8 +1416,8 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
set_string_binary(s, opt, opt->default_val.str, dst); set_string_binary(s, opt, opt->default_val.str, dst);
break; break;
case AV_OPT_TYPE_DICT: case AV_OPT_TYPE_DICT:
/* Cannot set defaults for these types */ set_string_dict(s, opt, opt->default_val.str, dst);
break; break;
default: default:
av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n",
opt->type, opt->name); opt->type, opt->name);
@ -1627,8 +1680,9 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
if (search_flags & AV_OPT_SEARCH_CHILDREN) { if (search_flags & AV_OPT_SEARCH_CHILDREN) {
if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
const AVClass *child = NULL; void *iter = NULL;
while (child = av_opt_child_class_next(c, child)) const AVClass *child;
while (child = av_opt_child_class_iterate(c, &iter))
if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
return o; return o;
} else { } else {
@ -1663,12 +1717,31 @@ void *av_opt_child_next(void *obj, void *prev)
return NULL; return NULL;
} }
#if FF_API_CHILD_CLASS_NEXT
FF_DISABLE_DEPRECATION_WARNINGS
const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev) const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
{ {
if (parent->child_class_next) if (parent->child_class_next)
return parent->child_class_next(prev); return parent->child_class_next(prev);
return NULL; return NULL;
} }
FF_ENABLE_DEPRECATION_WARNINGS
#endif
const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter)
{
if (parent->child_class_iterate)
return parent->child_class_iterate(iter);
#if FF_API_CHILD_CLASS_NEXT
FF_DISABLE_DEPRECATION_WARNINGS
if (parent->child_class_next) {
*iter = parent->child_class_next(*iter);
return *iter;
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
return NULL;
}
void *av_opt_ptr(const AVClass *class, void *obj, const char *name) void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
{ {
@ -1948,9 +2021,23 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o)
av_free(tmp.data); av_free(tmp.data);
return ret; return ret;
} }
case AV_OPT_TYPE_DICT: case AV_OPT_TYPE_DICT: {
/* Binary and dict have not default support yet. Any pointer is not default. */ AVDictionary *dict1 = NULL;
return !!(*(void **)dst); AVDictionary *dict2 = *(AVDictionary **)dst;
AVDictionaryEntry *en1 = NULL;
AVDictionaryEntry *en2 = NULL;
ret = av_dict_parse_string(&dict1, o->default_val.str, "=", ":", 0);
if (ret < 0) {
av_dict_free(&dict1);
return ret;
}
do {
en1 = av_dict_get(dict1, "", en1, AV_DICT_IGNORE_SUFFIX);
en2 = av_dict_get(dict2, "", en2, AV_DICT_IGNORE_SUFFIX);
} while (en1 && en2 && !strcmp(en1->key, en2->key) && !strcmp(en1->value, en2->value));
av_dict_free(&dict1);
return (!en1 && !en2);
}
case AV_OPT_TYPE_IMAGE_SIZE: case AV_OPT_TYPE_IMAGE_SIZE:
if (!o->default_val.str || !strcmp(o->default_val.str, "none")) if (!o->default_val.str || !strcmp(o->default_val.str, "none"))
w = h = 0; w = h = 0;
@ -2034,6 +2121,8 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
av_freep(&buf); av_freep(&buf);
} }
} }
av_bprint_finalize(&bprint, buffer); ret = av_bprint_finalize(&bprint, buffer);
if (ret < 0)
return ret;
return 0; return 0;
} }

Просмотреть файл

@ -114,7 +114,7 @@
* libavcodec exports generic options, while its priv_data field exports * libavcodec exports generic options, while its priv_data field exports
* codec-specific options). In such a case, it is possible to set up the * codec-specific options). In such a case, it is possible to set up the
* parent struct to export a child's options. To do that, simply * parent struct to export a child's options. To do that, simply
* implement AVClass.child_next() and AVClass.child_class_next() in the * implement AVClass.child_next() and AVClass.child_class_iterate() in the
* parent struct's AVClass. * parent struct's AVClass.
* Assuming that the test_struct from above now also contains a * Assuming that the test_struct from above now also contains a
* child_struct field: * child_struct field:
@ -143,23 +143,25 @@
* return t->child_struct; * return t->child_struct;
* return NULL * return NULL
* } * }
* const AVClass child_class_next(const AVClass *prev) * const AVClass child_class_iterate(void **iter)
* { * {
* return prev ? NULL : &child_class; * const AVClass *c = *iter ? NULL : &child_class;
* *iter = (void*)(uintptr_t)c;
* return c;
* } * }
* @endcode * @endcode
* Putting child_next() and child_class_next() as defined above into * Putting child_next() and child_class_iterate() as defined above into
* test_class will now make child_struct's options accessible through * test_class will now make child_struct's options accessible through
* test_struct (again, proper setup as described above needs to be done on * test_struct (again, proper setup as described above needs to be done on
* child_struct right after it is created). * child_struct right after it is created).
* *
* From the above example it might not be clear why both child_next() * From the above example it might not be clear why both child_next()
* and child_class_next() are needed. The distinction is that child_next() * and child_class_iterate() are needed. The distinction is that child_next()
* iterates over actually existing objects, while child_class_next() * iterates over actually existing objects, while child_class_iterate()
* iterates over all possible child classes. E.g. if an AVCodecContext * iterates over all possible child classes. E.g. if an AVCodecContext
* was initialized to use a codec which has private options, then its * was initialized to use a codec which has private options, then its
* child_next() will return AVCodecContext.priv_data and finish * child_next() will return AVCodecContext.priv_data and finish
* iterating. OTOH child_class_next() on AVCodecContext.av_class will * iterating. OTOH child_class_iterate() on AVCodecContext.av_class will
* iterate over all available codecs with private options. * iterate over all available codecs with private options.
* *
* @subsection avoptions_implement_named_constants Named constants * @subsection avoptions_implement_named_constants Named constants
@ -194,7 +196,7 @@
* For enumerating there are basically two cases. The first is when you want to * For enumerating there are basically two cases. The first is when you want to
* get all options that may potentially exist on the struct and its children * get all options that may potentially exist on the struct and its children
* (e.g. when constructing documentation). In that case you should call * (e.g. when constructing documentation). In that case you should call
* av_opt_child_class_next() recursively on the parent struct's AVClass. The * av_opt_child_class_iterate() recursively on the parent struct's AVClass. The
* second case is when you have an already initialized struct with all its * second case is when you have an already initialized struct with all its
* children and you want to get all options that can be actually written or read * children and you want to get all options that can be actually written or read
* from it. In that case you should call av_opt_child_next() recursively (and * from it. In that case you should call av_opt_child_next() recursively (and
@ -288,8 +290,10 @@ typedef struct AVOption {
*/ */
#define AV_OPT_FLAG_READONLY 128 #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_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_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_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 //FIXME think about enc-audio, ... style flags
/** /**
@ -644,13 +648,26 @@ const AVOption *av_opt_next(const void *obj, const AVOption *prev);
*/ */
void *av_opt_child_next(void *obj, void *prev); void *av_opt_child_next(void *obj, void *prev);
#if FF_API_CHILD_CLASS_NEXT
/** /**
* Iterate over potential AVOptions-enabled children of parent. * Iterate over potential AVOptions-enabled children of parent.
* *
* @param prev result of a previous call to this function or NULL * @param prev result of a previous call to this function or NULL
* @return AVClass corresponding to next potential child or NULL * @return AVClass corresponding to next potential child or NULL
*
* @deprecated use av_opt_child_class_iterate
*/ */
attribute_deprecated
const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev); const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev);
#endif
/**
* Iterate over potential AVOptions-enabled children of parent.
*
* @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);
/** /**
* @defgroup opt_set_funcs Option setting functions * @defgroup opt_set_funcs Option setting functions
@ -669,6 +686,9 @@ const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *pre
* scalars or named flags separated by '+' or '-'. Prefixing a flag * scalars or named flags separated by '+' or '-'. Prefixing a flag
* with '+' causes it to be set without affecting the other flags; * with '+' causes it to be set without affecting the other flags;
* similarly, '-' unsets a flag. * similarly, '-' unsets a flag.
* If the field is of a dictionary type, it has to be a ':' separated list of
* key=value parameters. Values containing ':' special characters must be
* escaped.
* @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN * @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
* is passed here, then the option may be set on a child of obj. * is passed here, then the option may be set on a child of obj.
* *
@ -729,9 +749,10 @@ int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, in
/** /**
* @note the returned string will be av_malloc()ed and must be av_free()ed by the caller * @note the returned string will be av_malloc()ed and must be av_free()ed by the caller
* *
* @note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the option has * @note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the
* AV_OPT_TYPE_STRING or AV_OPT_TYPE_BINARY and is set to NULL, *out_val will be set * option is of type AV_OPT_TYPE_STRING, AV_OPT_TYPE_BINARY or AV_OPT_TYPE_DICT
* to NULL instead of an allocated empty string. * and is set to NULL, *out_val will be set to NULL instead of an allocated
* empty string.
*/ */
int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val);
int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val);

Просмотреть файл

@ -28,7 +28,7 @@
#include "common.h" #include "common.h"
#include "eval.h" #include "eval.h"
#include "log.h" #include "log.h"
/* #include "random_seed.h" */ //#include "random_seed.h"
#include "time_internal.h" #include "time_internal.h"
#include "parseutils.h" #include "parseutils.h"
#include "fftime.h" #include "fftime.h"
@ -736,12 +736,14 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
if (*q) if (*q)
return AVERROR(EINVAL); return AVERROR(EINVAL);
if (INT64_MAX / suffix < t) if (INT64_MAX / suffix < t || t < INT64_MIN / suffix)
return AVERROR(ERANGE); return AVERROR(ERANGE);
t *= suffix; t *= suffix;
if (INT64_MAX - microseconds < t) if (INT64_MAX - microseconds < t)
return AVERROR(ERANGE); return AVERROR(ERANGE);
t += microseconds; t += microseconds;
if (t == INT64_MIN && negative)
return AVERROR(ERANGE);
*timeval = negative ? -t : t; *timeval = negative ? -t : t;
return 0; return 0;
} }

Просмотреть файл

@ -205,6 +205,29 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
{ 0, 4, 1, 0, 8, 3, 7, 2 }, /* V */ { 0, 4, 1, 0, 8, 3, 7, 2 }, /* V */
}, },
}, },
[AV_PIX_FMT_Y210LE] = {
.name = "y210le",
.nb_components = 3,
.log2_chroma_w = 1,
.log2_chroma_h = 0,
.comp = {
{ 0, 4, 0, 6, 10, 3, 9, 1 }, /* Y */
{ 0, 8, 2, 6, 10, 7, 9, 3 }, /* U */
{ 0, 8, 6, 6, 10, 7, 9, 7 }, /* V */
},
},
[AV_PIX_FMT_Y210BE] = {
.name = "y210be",
.nb_components = 3,
.log2_chroma_w = 1,
.log2_chroma_h = 0,
.comp = {
{ 0, 4, 0, 6, 10, 3, 9, 1 }, /* Y */
{ 0, 8, 2, 6, 10, 7, 9, 3 }, /* U */
{ 0, 8, 6, 6, 10, 7, 9, 7 }, /* V */
},
.flags = AV_PIX_FMT_FLAG_BE,
},
[AV_PIX_FMT_RGB24] = { [AV_PIX_FMT_RGB24] = {
.name = "rgb24", .name = "rgb24",
.nb_components = 3, .nb_components = 3,
@ -229,6 +252,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
}, },
.flags = AV_PIX_FMT_FLAG_RGB, .flags = AV_PIX_FMT_FLAG_RGB,
}, },
[AV_PIX_FMT_X2RGB10LE] = {
.name = "x2rgb10le",
.nb_components= 3,
.log2_chroma_w= 0,
.log2_chroma_h= 0,
.comp = {
{ 0, 4, 2, 4, 10, 3, 9, 2 }, /* R */
{ 0, 4, 1, 2, 10, 3, 9, 3 }, /* G */
{ 0, 4, 0, 0, 10, 3, 9, 4 }, /* B */
},
.flags = AV_PIX_FMT_FLAG_RGB,
},
[AV_PIX_FMT_X2RGB10BE] = {
.name = "x2rgb10be",
.nb_components= 3,
.log2_chroma_w= 0,
.log2_chroma_h= 0,
.comp = {
{ 0, 4, 0, 4, 10, 3, 9, 2 }, /* R */
{ 0, 4, 1, 2, 10, 3, 9, 3 }, /* G */
{ 0, 4, 2, 0, 10, 3, 9, 4 }, /* B */
},
.flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE,
},
[AV_PIX_FMT_YUV422P] = { [AV_PIX_FMT_YUV422P] = {
.name = "yuv422p", .name = "yuv422p",
.nb_components = 3, .nb_components = 3,
@ -2344,6 +2391,10 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
}, },
.flags = AV_PIX_FMT_FLAG_PLANAR, .flags = AV_PIX_FMT_FLAG_PLANAR,
}, },
[AV_PIX_FMT_VULKAN] = {
.name = "vulkan",
.flags = AV_PIX_FMT_FLAG_HWACCEL,
},
}; };
#if FF_API_PLUS1_MINUS1 #if FF_API_PLUS1_MINUS1
FF_ENABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS
@ -2369,7 +2420,7 @@ static const char * const color_primaries_names[AVCOL_PRI_NB] = {
[AVCOL_PRI_SMPTE428] = "smpte428", [AVCOL_PRI_SMPTE428] = "smpte428",
[AVCOL_PRI_SMPTE431] = "smpte431", [AVCOL_PRI_SMPTE431] = "smpte431",
[AVCOL_PRI_SMPTE432] = "smpte432", [AVCOL_PRI_SMPTE432] = "smpte432",
[AVCOL_PRI_JEDEC_P22] = "jedec-p22", [AVCOL_PRI_EBU3213] = "ebu3213",
}; };
static const char * const color_transfer_names[] = { static const char * const color_transfer_names[] = {
@ -2608,7 +2659,7 @@ void ff_check_pixfmt_descriptors(void){
continue; continue;
av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0); av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0);
av_assert0(tmp[0] == 0 && tmp[1] == 0); av_assert0(tmp[0] == 0 && tmp[1] == 0);
tmp[0] = tmp[1] = (1<<c->depth) - 1; tmp[0] = tmp[1] = (1ULL << c->depth) - 1;
av_write_image_line(tmp, data, linesize, d, 0, 0, j, 2); av_write_image_line(tmp, data, linesize, d, 0, 0, j, 2);
} }
} }
@ -2651,11 +2702,13 @@ static int get_color_type(const AVPixFmtDescriptor *desc) {
if(desc->nb_components == 1 || desc->nb_components == 2) if(desc->nb_components == 1 || desc->nb_components == 2)
return FF_COLOR_GRAY; return FF_COLOR_GRAY;
if(desc->name && !strncmp(desc->name, "yuvj", 4)) if (desc->name) {
return FF_COLOR_YUV_JPEG; if (av_strstart(desc->name, "yuvj", NULL))
return FF_COLOR_YUV_JPEG;
if(desc->name && !strncmp(desc->name, "xyz", 3)) if (av_strstart(desc->name, "xyz", NULL))
return FF_COLOR_XYZ; return FF_COLOR_XYZ;
}
if(desc->flags & AV_PIX_FMT_FLAG_RGB) if(desc->flags & AV_PIX_FMT_FLAG_RGB)
return FF_COLOR_RGB; return FF_COLOR_RGB;
@ -2856,8 +2909,7 @@ int av_color_range_from_name(const char *name)
int i; int i;
for (i = 0; i < FF_ARRAY_ELEMS(color_range_names); i++) { for (i = 0; i < FF_ARRAY_ELEMS(color_range_names); i++) {
size_t len = strlen(color_range_names[i]); if (av_strstart(name, color_range_names[i], NULL))
if (!strncmp(color_range_names[i], name, len))
return i; return i;
} }
@ -2875,13 +2927,10 @@ int av_color_primaries_from_name(const char *name)
int i; int i;
for (i = 0; i < FF_ARRAY_ELEMS(color_primaries_names); i++) { for (i = 0; i < FF_ARRAY_ELEMS(color_primaries_names); i++) {
size_t len;
if (!color_primaries_names[i]) if (!color_primaries_names[i])
continue; continue;
len = strlen(color_primaries_names[i]); if (av_strstart(name, color_primaries_names[i], NULL))
if (!strncmp(color_primaries_names[i], name, len))
return i; return i;
} }
@ -2899,13 +2948,10 @@ int av_color_transfer_from_name(const char *name)
int i; int i;
for (i = 0; i < FF_ARRAY_ELEMS(color_transfer_names); i++) { for (i = 0; i < FF_ARRAY_ELEMS(color_transfer_names); i++) {
size_t len;
if (!color_transfer_names[i]) if (!color_transfer_names[i])
continue; continue;
len = strlen(color_transfer_names[i]); if (av_strstart(name, color_transfer_names[i], NULL))
if (!strncmp(color_transfer_names[i], name, len))
return i; return i;
} }
@ -2923,13 +2969,10 @@ int av_color_space_from_name(const char *name)
int i; int i;
for (i = 0; i < FF_ARRAY_ELEMS(color_space_names); i++) { for (i = 0; i < FF_ARRAY_ELEMS(color_space_names); i++) {
size_t len;
if (!color_space_names[i]) if (!color_space_names[i])
continue; continue;
len = strlen(color_space_names[i]); if (av_strstart(name, color_space_names[i], NULL))
if (!strncmp(color_space_names[i], name, len))
return i; return i;
} }
@ -2947,13 +2990,10 @@ int av_chroma_location_from_name(const char *name)
int i; int i;
for (i = 0; i < FF_ARRAY_ELEMS(chroma_location_names); i++) { for (i = 0; i < FF_ARRAY_ELEMS(chroma_location_names); i++) {
size_t len;
if (!chroma_location_names[i]) if (!chroma_location_names[i])
continue; continue;
len = strlen(chroma_location_names[i]); if (av_strstart(name, chroma_location_names[i], NULL))
if (!strncmp(chroma_location_names[i], name, len))
return i; return i;
} }

Просмотреть файл

@ -147,6 +147,7 @@ typedef struct AVPixFmtDescriptor {
*/ */
#define AV_PIX_FMT_FLAG_RGB (1 << 5) #define AV_PIX_FMT_FLAG_RGB (1 << 5)
#if FF_API_PSEUDOPAL
/** /**
* The pixel format is "pseudo-paletted". This means that it contains a * The pixel format is "pseudo-paletted". This means that it contains a
* fixed palette in the 2nd plane but the palette is fixed/constant for each * fixed palette in the 2nd plane but the palette is fixed/constant for each
@ -164,6 +165,7 @@ typedef struct AVPixFmtDescriptor {
* before the deprecation, though). * before the deprecation, though).
*/ */
#define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6) #define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6)
#endif
/** /**
* The pixel format has an alpha channel. This is set on all formats that * The pixel format has an alpha channel. This is set on all formats that

Просмотреть файл

@ -257,18 +257,18 @@ enum AVPixelFormat {
AV_PIX_FMT_GBRP14LE, ///< planar GBR 4:4:4 42bpp, little-endian AV_PIX_FMT_GBRP14LE, ///< planar GBR 4:4:4 42bpp, little-endian
AV_PIX_FMT_YUVJ411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV411P and setting color_range AV_PIX_FMT_YUVJ411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV411P and setting color_range
AV_PIX_FMT_BAYER_BGGR8, ///< bayer, BGBG..(odd line), GRGR..(even line), 8-bit samples */ AV_PIX_FMT_BAYER_BGGR8, ///< bayer, BGBG..(odd line), GRGR..(even line), 8-bit samples
AV_PIX_FMT_BAYER_RGGB8, ///< bayer, RGRG..(odd line), GBGB..(even line), 8-bit samples */ AV_PIX_FMT_BAYER_RGGB8, ///< bayer, RGRG..(odd line), GBGB..(even line), 8-bit samples
AV_PIX_FMT_BAYER_GBRG8, ///< bayer, GBGB..(odd line), RGRG..(even line), 8-bit samples */ AV_PIX_FMT_BAYER_GBRG8, ///< bayer, GBGB..(odd line), RGRG..(even line), 8-bit samples
AV_PIX_FMT_BAYER_GRBG8, ///< bayer, GRGR..(odd line), BGBG..(even line), 8-bit samples */ AV_PIX_FMT_BAYER_GRBG8, ///< bayer, GRGR..(odd line), BGBG..(even line), 8-bit samples
AV_PIX_FMT_BAYER_BGGR16LE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, little-endian */ AV_PIX_FMT_BAYER_BGGR16LE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, little-endian
AV_PIX_FMT_BAYER_BGGR16BE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, big-endian */ AV_PIX_FMT_BAYER_BGGR16BE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, big-endian
AV_PIX_FMT_BAYER_RGGB16LE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, little-endian */ AV_PIX_FMT_BAYER_RGGB16LE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, little-endian
AV_PIX_FMT_BAYER_RGGB16BE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, big-endian */ AV_PIX_FMT_BAYER_RGGB16BE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, big-endian
AV_PIX_FMT_BAYER_GBRG16LE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, little-endian */ AV_PIX_FMT_BAYER_GBRG16LE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, little-endian
AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian */ AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian
AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian */ AV_PIX_FMT_BAYER_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 */ AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian
AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing
@ -348,6 +348,18 @@ enum AVPixelFormat {
AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V)
AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped
/**
* Vulkan hardware images.
*
* data[0] points to an AVVkFrame
*/
AV_PIX_FMT_VULKAN,
AV_PIX_FMT_Y210BE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, big-endian
AV_PIX_FMT_Y210LE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, little-endian
AV_PIX_FMT_X2RGB10LE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), little-endian, X=unused/undefined
AV_PIX_FMT_X2RGB10BE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), big-endian, X=unused/undefined
AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
}; };
@ -436,6 +448,9 @@ enum AVPixelFormat {
#define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE) #define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE)
#define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE) #define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE)
#define AV_PIX_FMT_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE)
#define AV_PIX_FMT_X2RGB10 AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE)
/** /**
* Chromaticity coordinates of the source primaries. * Chromaticity coordinates of the source primaries.
* These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1. * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1.
@ -456,7 +471,8 @@ enum AVColorPrimaries {
AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428,
AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3
AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3
AVCOL_PRI_JEDEC_P22 = 22, ///< JEDEC P22 phosphors AVCOL_PRI_EBU3213 = 22, ///< EBU Tech. 3213-E / JEDEC P22 phosphors
AVCOL_PRI_JEDEC_P22 = AVCOL_PRI_EBU3213,
AVCOL_PRI_NB ///< Not part of ABI AVCOL_PRI_NB ///< Not part of ABI
}; };
@ -514,12 +530,60 @@ enum AVColorSpace {
}; };
/** /**
* MPEG vs JPEG YUV range. * Visual content value range.
*
* These values are based on definitions that can be found in multiple
* specifications, such as ITU-T BT.709 (3.4 - Quantization of RGB, luminance
* and colour-difference signals), ITU-T BT.2020 (Table 5 - Digital
* Representation) as well as ITU-T BT.2100 (Table 9 - Digital 10- and 12-bit
* integer representation). At the time of writing, the BT.2100 one is
* recommended, as it also defines the full range representation.
*
* Common definitions:
* - For RGB and luminance planes such as Y in YCbCr and I in ICtCp,
* 'E' is the original value in range of 0.0 to 1.0.
* - For chrominance planes such as Cb,Cr and Ct,Cp, 'E' is the original
* value in range of -0.5 to 0.5.
* - 'n' is the output bit depth.
* - For additional definitions such as rounding and clipping to valid n
* bit unsigned integer range, please refer to BT.2100 (Table 9).
*/ */
enum AVColorRange { enum AVColorRange {
AVCOL_RANGE_UNSPECIFIED = 0, AVCOL_RANGE_UNSPECIFIED = 0,
AVCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
AVCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges /**
* Narrow or limited range content.
*
* - For luminance planes:
*
* (219 * E + 16) * 2^(n-8)
*
* F.ex. the range of 16-235 for 8 bits
*
* - For chrominance planes:
*
* (224 * E + 128) * 2^(n-8)
*
* F.ex. the range of 16-240 for 8 bits
*/
AVCOL_RANGE_MPEG = 1,
/**
* Full range content.
*
* - For RGB and luminance planes:
*
* (2^n - 1) * E
*
* F.ex. the range of 0-255 for 8 bits
*
* - For chrominance planes:
*
* (2^n - 1) * E + 2^(n - 1)
*
* F.ex. the range of 1-255 for 8 bits
*/
AVCOL_RANGE_JPEG = 2,
AVCOL_RANGE_NB ///< Not part of ABI AVCOL_RANGE_NB ///< Not part of ABI
}; };

Просмотреть файл

@ -182,3 +182,12 @@ uint32_t av_q2intfloat(AVRational q) {
return sign<<31 | (150-shift)<<23 | (n - (1<<23)); return sign<<31 | (150-shift)<<23 | (n - (1<<23));
} }
AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def)
{
int64_t gcd, lcm;
gcd = av_gcd(a.den, b.den);
lcm = (a.den / gcd) * b.den;
return lcm < max_den ? av_make_q(av_gcd(a.num, b.num), lcm) : def;
}

Просмотреть файл

@ -207,6 +207,12 @@ int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
*/ */
uint32_t av_q2intfloat(AVRational q); uint32_t av_q2intfloat(AVRational q);
/**
* Return the best rational so that a and b are multiple of it.
* If the resulting denominator is larger than max_den, return def.
*/
AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def);
/** /**
* @} * @}
*/ */

Просмотреть файл

@ -33,16 +33,19 @@
#include "log.h" #include "log.h"
#define ASSERT_PTHREAD_ABORT(func, ret) do { \
char errbuf[AV_ERROR_MAX_STRING_SIZE] = ""; \
av_log(NULL, AV_LOG_FATAL, AV_STRINGIFY(func) \
" failed with error: %s\n", \
av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, \
AVERROR(ret))); \
abort(); \
} while (0)
#define ASSERT_PTHREAD_NORET(func, ...) do { \ #define ASSERT_PTHREAD_NORET(func, ...) do { \
int ret = func(__VA_ARGS__); \ int ret = func(__VA_ARGS__); \
if (ret) { \ if (ret) \
char errbuf[AV_ERROR_MAX_STRING_SIZE] = ""; \ ASSERT_PTHREAD_ABORT(func, ret); \
av_log(NULL, AV_LOG_FATAL, AV_STRINGIFY(func) \
" failed with error: %s\n", \
av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, \
AVERROR(ret))); \
abort(); \
} \
} while (0) } while (0)
#define ASSERT_PTHREAD(func, ...) do { \ #define ASSERT_PTHREAD(func, ...) do { \
@ -109,6 +112,15 @@ static inline int strict_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t
ASSERT_PTHREAD(pthread_cond_wait, cond, mutex); ASSERT_PTHREAD(pthread_cond_wait, cond, mutex);
} }
static inline int strict_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime)
{
int ret = pthread_cond_timedwait(cond, mutex, abstime);
if (ret && ret != ETIMEDOUT)
ASSERT_PTHREAD_ABORT(pthread_cond_timedwait, ret);
return ret;
}
static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
{ {
ASSERT_PTHREAD(pthread_once, once_control, init_routine); ASSERT_PTHREAD(pthread_once, once_control, init_routine);
@ -124,6 +136,7 @@ static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_
#define pthread_cond_signal strict_pthread_cond_signal #define pthread_cond_signal strict_pthread_cond_signal
#define pthread_cond_broadcast strict_pthread_cond_broadcast #define pthread_cond_broadcast strict_pthread_cond_broadcast
#define pthread_cond_wait strict_pthread_cond_wait #define pthread_cond_wait strict_pthread_cond_wait
#define pthread_cond_timedwait strict_pthread_cond_timedwait
#define pthread_once strict_pthread_once #define pthread_once strict_pthread_once
#endif #endif

Просмотреть файл

@ -33,7 +33,7 @@
#include <windows.h> #include <windows.h>
#endif #endif
#include "fftime.h" #include "time.h"
#include "error.h" #include "error.h"
int64_t av_gettime(void) int64_t av_gettime(void)
@ -57,7 +57,7 @@ int64_t av_gettime_relative(void)
{ {
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
#ifdef __APPLE__ #ifdef __APPLE__
if (clock_gettime) if (&clock_gettime)
#endif #endif
{ {
struct timespec ts; struct timespec ts;
@ -72,7 +72,7 @@ int av_gettime_relative_is_monotonic(void)
{ {
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
#ifdef __APPLE__ #ifdef __APPLE__
if (!clock_gettime) if (!&clock_gettime)
return 0; return 0;
#endif #endif
return 1; return 1;

Просмотреть файл

@ -33,23 +33,20 @@
int av_timecode_adjust_ntsc_framenum2(int framenum, int fps) int av_timecode_adjust_ntsc_framenum2(int framenum, int fps)
{ {
/* only works for NTSC 29.97 and 59.94 */ /* only works for multiples of NTSC 29.97 */
int drop_frames = 0; int drop_frames = 0;
int d, m, frames_per_10mins; int d, m, frames_per_10mins;
if (fps == 30) { if (fps && fps % 30 == 0) {
drop_frames = 2; drop_frames = fps / 30 * 2;
frames_per_10mins = 17982; frames_per_10mins = fps / 30 * 17982;
} else if (fps == 60) {
drop_frames = 4;
frames_per_10mins = 35964;
} else } else
return framenum; return framenum;
d = framenum / frames_per_10mins; d = framenum / frames_per_10mins;
m = framenum % frames_per_10mins; m = framenum % frames_per_10mins;
return framenum + 9 * drop_frames * d + drop_frames * ((m - drop_frames) / (frames_per_10mins / 10)); return framenum + 9U * drop_frames * d + drop_frames * ((m - drop_frames) / (frames_per_10mins / 10));
} }
uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum)
@ -65,20 +62,41 @@ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum)
ss = framenum / fps % 60; ss = framenum / fps % 60;
mm = framenum / (fps*60) % 60; mm = framenum / (fps*60) % 60;
hh = framenum / (fps*3600) % 24; hh = framenum / (fps*3600) % 24;
return 0 << 31 | // color frame flag (0: unsync mode, 1: sync mode) return av_timecode_get_smpte(tc->rate, drop, hh, mm, ss, ff);
drop << 30 | // drop frame flag (0: non drop, 1: drop) }
(ff / 10) << 28 | // tens of frames
(ff % 10) << 24 | // units of frames uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff)
0 << 23 | // PC (NTSC) or BGF0 (PAL) {
(ss / 10) << 20 | // tens of seconds uint32_t tc = 0;
(ss % 10) << 16 | // units of seconds
0 << 15 | // BGF0 (NTSC) or BGF2 (PAL) /* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS.
(mm / 10) << 12 | // tens of minutes See SMPTE ST 12-1:2014 Sec 12.1 for more info. */
(mm % 10) << 8 | // units of minutes if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) {
0 << 7 | // BGF2 (NTSC) or PC (PAL) if (ff % 2 == 1) {
0 << 6 | // BGF1 if (av_cmp_q(rate, (AVRational) {50, 1}) == 0)
(hh / 10) << 4 | // tens of hours tc |= (1 << 7);
(hh % 10); // units of hours else
tc |= (1 << 23);
}
ff /= 2;
}
hh = hh % 24;
mm = av_clip(mm, 0, 59);
ss = av_clip(ss, 0, 59);
ff = ff % 40;
tc |= drop << 30;
tc |= (ff / 10) << 28;
tc |= (ff % 10) << 24;
tc |= (ss / 10) << 20;
tc |= (ss % 10) << 16;
tc |= (mm / 10) << 12;
tc |= (mm % 10) << 8;
tc |= (hh / 10) << 4;
tc |= (hh % 10);
return tc;
} }
char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum) char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
@ -96,8 +114,8 @@ char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
} }
ff = framenum % fps; ff = framenum % fps;
ss = framenum / fps % 60; ss = framenum / fps % 60;
mm = framenum / (fps*60) % 60; mm = framenum / (fps*60LL) % 60;
hh = framenum / (fps*3600); hh = framenum / (fps*3600LL);
if (tc->flags & AV_TIMECODE_FLAG_24HOURSMAX) if (tc->flags & AV_TIMECODE_FLAG_24HOURSMAX)
hh = hh % 24; hh = hh % 24;
snprintf(buf, AV_TIMECODE_STR_SIZE, "%s%02d:%02d:%02d%c%02d", snprintf(buf, AV_TIMECODE_STR_SIZE, "%s%02d:%02d:%02d%c%02d",
@ -115,16 +133,33 @@ static unsigned bcd2uint(uint8_t bcd)
return low + 10*high; return low + 10*high;
} }
char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df) char *av_timecode_make_smpte_tc_string2(char *buf, AVRational rate, uint32_t tcsmpte, int prevent_df, int skip_field)
{ {
unsigned hh = bcd2uint(tcsmpte & 0x3f); // 6-bit hours unsigned hh = bcd2uint(tcsmpte & 0x3f); // 6-bit hours
unsigned mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes unsigned mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes
unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds
unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames
unsigned drop = tcsmpte & 1<<30 && !prevent_df; // 1-bit drop if not arbitrary bit unsigned drop = tcsmpte & 1<<30 && !prevent_df; // 1-bit drop if not arbitrary bit
if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) {
ff <<= 1;
if (!skip_field) {
if (av_cmp_q(rate, (AVRational) {50, 1}) == 0)
ff += !!(tcsmpte & 1 << 7);
else
ff += !!(tcsmpte & 1 << 23);
}
}
snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u", snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u",
hh, mm, ss, drop ? ';' : ':', ff); hh, mm, ss, drop ? ';' : ':', ff);
return buf; return buf;
}
char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df)
{
return av_timecode_make_smpte_tc_string2(buf, (AVRational){30, 1}, tcsmpte, prevent_df, 1);
} }
char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit) char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit)
@ -158,8 +193,8 @@ static int check_timecode(void *log_ctx, AVTimecode *tc)
av_log(log_ctx, AV_LOG_ERROR, "Valid timecode frame rate must be specified. Minimum value is 1\n"); av_log(log_ctx, AV_LOG_ERROR, "Valid timecode frame rate must be specified. Minimum value is 1\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps != 30 && tc->fps != 60) { if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps % 30 != 0) {
av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 or 60000/1001 FPS\n"); av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with multiples of 30000/1001 FPS\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
if (check_fps(tc->fps) < 0) { if (check_fps(tc->fps) < 0) {
@ -191,19 +226,12 @@ int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start
return check_timecode(log_ctx, tc); return check_timecode(log_ctx, tc);
} }
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx) int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx)
{ {
char c; int ret;
int hh, mm, ss, ff, ret;
if (sscanf(str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) {
av_log(log_ctx, AV_LOG_ERROR, "Unable to parse timecode, "
"syntax: hh:mm:ss[:;.]ff\n");
return AVERROR_INVALIDDATA;
}
memset(tc, 0, sizeof(*tc)); memset(tc, 0, sizeof(*tc));
tc->flags = c != ':' ? AV_TIMECODE_FLAG_DROPFRAME : 0; // drop if ';', '.', ... tc->flags = flags;
tc->rate = rate; tc->rate = rate;
tc->fps = fps_from_frame_rate(rate); tc->fps = fps_from_frame_rate(rate);
@ -214,7 +242,22 @@ int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *st
tc->start = (hh*3600 + mm*60 + ss) * tc->fps + ff; tc->start = (hh*3600 + mm*60 + ss) * tc->fps + ff;
if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */ if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */
int tmins = 60*hh + mm; int tmins = 60*hh + mm;
tc->start -= (tc->fps == 30 ? 2 : 4) * (tmins - tmins/10); tc->start -= (tc->fps / 30 * 2) * (tmins - tmins/10);
} }
return 0; return 0;
} }
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
{
char c;
int hh, mm, ss, ff, flags;
if (sscanf(str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) {
av_log(log_ctx, AV_LOG_ERROR, "Unable to parse timecode, "
"syntax: hh:mm:ss[:;.]ff\n");
return AVERROR_INVALIDDATA;
}
flags = c != ':' ? AV_TIMECODE_FLAG_DROPFRAME : 0; // drop if ';', '.', ...
return av_timecode_init_from_components(tc, rate, flags, hh, mm, ss, ff, log_ctx);
}

Просмотреть файл

@ -49,9 +49,9 @@ typedef struct {
* Adjust frame number for NTSC drop frame time code. * Adjust frame number for NTSC drop frame time code.
* *
* @param framenum frame number to adjust * @param framenum frame number to adjust
* @param fps frame per second, 30 or 60 * @param fps frame per second, multiples of 30
* @return adjusted frame number * @return adjusted frame number
* @warning adjustment is only valid in NTSC 29.97 and 59.94 * @warning adjustment is only valid for multiples of NTSC 29.97
*/ */
int av_timecode_adjust_ntsc_framenum2(int framenum, int fps); int av_timecode_adjust_ntsc_framenum2(int framenum, int fps);
@ -62,14 +62,39 @@ int av_timecode_adjust_ntsc_framenum2(int framenum, int fps);
* @param framenum frame number * @param framenum frame number
* @return the SMPTE binary representation * @return the SMPTE binary representation
* *
* See SMPTE ST 314M-2005 Sec 4.4.2.2.1 "Time code pack (TC)"
* the format description as follows:
* bits 0-5: hours, in BCD(6bits)
* bits 6: BGF1
* bits 7: BGF2 (NTSC) or FIELD (PAL)
* bits 8-14: minutes, in BCD(7bits)
* bits 15: BGF0 (NTSC) or BGF2 (PAL)
* bits 16-22: seconds, in BCD(7bits)
* bits 23: FIELD (NTSC) or BGF0 (PAL)
* bits 24-29: frames, in BCD(6bits)
* bits 30: drop frame flag (0: non drop, 1: drop)
* bits 31: color frame flag (0: unsync mode, 1: sync mode)
* @note BCD numbers (6 or 7 bits): 4 or 5 lower bits for units, 2 higher bits for tens.
* @note Frame number adjustment is automatically done in case of drop timecode, * @note Frame number adjustment is automatically done in case of drop timecode,
* you do NOT have to call av_timecode_adjust_ntsc_framenum2(). * you do NOT have to call av_timecode_adjust_ntsc_framenum2().
* @note The frame number is relative to tc->start. * @note The frame number is relative to tc->start.
* @note Color frame (CF), binary group flags (BGF) and biphase mark polarity * @note Color frame (CF) and binary group flags (BGF) bits are set to zero.
* correction (PC) bits are set to zero.
*/ */
uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum); uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum);
/**
* Convert sei info to SMPTE 12M binary representation.
*
* @param rate frame rate in rational form
* @param drop drop flag
* @param hh hour
* @param mm minute
* @param ss second
* @param ff frame number
* @return the SMPTE binary representation
*/
uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff);
/** /**
* Load timecode string in buf. * Load timecode string in buf.
* *
@ -84,6 +109,23 @@ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum)
*/ */
char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum); char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum);
/**
* Get the timecode string from the SMPTE timecode format.
*
* In contrast to av_timecode_make_smpte_tc_string this function supports 50/60
* fps timecodes by using the field bit.
*
* @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long
* @param rate frame rate of the timecode
* @param tcsmpte the 32-bit SMPTE timecode
* @param prevent_df prevent the use of a drop flag when it is known the DF bit
* is arbitrary
* @param skip_field prevent the use of a field flag when it is known the field
* bit is arbitrary (e.g. because it is used as PC flag)
* @return the buf parameter
*/
char *av_timecode_make_smpte_tc_string2(char *buf, AVRational rate, uint32_t tcsmpte, int prevent_df, int skip_field);
/** /**
* Get the timecode string from the SMPTE timecode format. * Get the timecode string from the SMPTE timecode format.
* *
@ -118,6 +160,23 @@ char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit);
*/ */
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx); int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx);
/**
* Init a timecode struct from the passed timecode components.
*
* @param log_ctx a pointer to an arbitrary struct of which the first field
* is a pointer to an AVClass struct (used for av_log)
* @param tc pointer to an allocated AVTimecode
* @param rate frame rate in rational form
* @param flags miscellaneous flags such as drop frame, +24 hours, ...
* (see AVTimecodeFlag)
* @param hh hours
* @param mm minutes
* @param ss seconds
* @param ff frames
* @return 0 on success, AVERROR otherwise
*/
int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx);
/** /**
* Parse timecode representation (hh:mm:ss[:;.]ff). * Parse timecode representation (hh:mm:ss[:;.]ff).
* *

Просмотреть файл

@ -87,7 +87,7 @@
if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \ if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \
int i; \ int i; \
av_log(NULL, AV_LOG_ERROR, \ av_log(NULL, AV_LOG_ERROR, \
"%7"PRIu64" " FF_TIMER_UNITS " in %s,%8d runs,%7d skips", \ "%7" PRIu64 " " FF_TIMER_UNITS " in %s,%8d runs,%7d skips",\
tsum * 10 / tcount, id, tcount, tskip_count); \ tsum * 10 / tcount, id, tcount, tskip_count); \
for (i = 0; i < 32; i++) \ for (i = 0; i < 32; i++) \
av_log(NULL, AV_LOG_VERBOSE, " %2d", av_log2(2*thistogram[i]));\ av_log(NULL, AV_LOG_VERBOSE, " %2d", av_log2(2*thistogram[i]));\

Просмотреть файл

@ -70,7 +70,7 @@ const char *avutil_configuration(void)
const char *avutil_license(void) const char *avutil_license(void)
{ {
#define LICENSE_PREFIX "libavutil license: " #define LICENSE_PREFIX "libavutil license: "
return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; return &LICENSE_PREFIX FFMPEG_LICENSE[sizeof(LICENSE_PREFIX) - 1];
} }
const char *av_get_media_type_string(enum AVMediaType media_type) const char *av_get_media_type_string(enum AVMediaType media_type)

Просмотреть файл

@ -79,7 +79,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 56 #define LIBAVUTIL_VERSION_MAJOR 56
#define LIBAVUTIL_VERSION_MINOR 31 #define LIBAVUTIL_VERSION_MINOR 70
#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
@ -129,7 +129,18 @@
#ifndef FF_API_PSEUDOPAL #ifndef FF_API_PSEUDOPAL
#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) #define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57)
#endif #endif
#ifndef FF_API_CHILD_CLASS_NEXT
#define FF_API_CHILD_CLASS_NEXT (LIBAVUTIL_VERSION_MAJOR < 57)
#endif
#ifndef FF_API_BUFFER_SIZE_T
#define FF_API_BUFFER_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 57)
#endif
#ifndef FF_API_D2STR
#define FF_API_D2STR (LIBAVUTIL_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_DECLARE_ALIGNED
#define FF_API_DECLARE_ALIGNED (LIBAVUTIL_VERSION_MAJOR < 58)
#endif
/** /**
* @} * @}

Просмотреть файл

@ -0,0 +1,82 @@
/*
* 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 <limits.h>
#include <stddef.h>
#include <stdint.h>
#include "buffer.h"
#include "common.h"
#include "frame.h"
#include "mem.h"
#include "video_enc_params.h"
AVVideoEncParams *av_video_enc_params_alloc(enum AVVideoEncParamsType type,
unsigned int nb_blocks, size_t *out_size)
{
AVVideoEncParams *par;
size_t size;
size = sizeof(*par);
if (nb_blocks > (SIZE_MAX - size) / sizeof(AVVideoBlockParams))
return NULL;
size += sizeof(AVVideoBlockParams) * nb_blocks;
par = av_mallocz(size);
if (!par)
return NULL;
par->type = type;
par->nb_blocks = nb_blocks;
par->block_size = sizeof(AVVideoBlockParams);
par->blocks_offset = sizeof(*par);
if (out_size)
*out_size = size;
return par;
}
AVVideoEncParams*
av_video_enc_params_create_side_data(AVFrame *frame, enum AVVideoEncParamsType type,
unsigned int nb_blocks)
{
AVBufferRef *buf;
AVVideoEncParams *par;
size_t size;
par = av_video_enc_params_alloc(type, nb_blocks, &size);
if (!par)
return NULL;
if (size > INT_MAX) {
av_free(par);
return NULL;
}
buf = av_buffer_create((uint8_t *)par, size, NULL, NULL, 0);
if (!buf) {
av_freep(&par);
return NULL;
}
if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_VIDEO_ENC_PARAMS, buf)) {
av_buffer_unref(&buf);
return NULL;
}
return par;
}

Просмотреть файл

@ -0,0 +1,171 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVUTIL_VIDEO_ENC_PARAMS_H
#define AVUTIL_VIDEO_ENC_PARAMS_H
#include <stddef.h>
#include <stdint.h>
#include "libavutil/avassert.h"
#include "libavutil/frame.h"
enum AVVideoEncParamsType {
AV_VIDEO_ENC_PARAMS_NONE = -1,
/**
* VP9 stores:
* - per-frame base (luma AC) quantizer index, exported as AVVideoEncParams.qp
* - deltas for luma DC, chroma AC and chroma DC, exported in the
* corresponding entries in AVVideoEncParams.delta_qp
* - per-segment delta, exported as for each block as AVVideoBlockParams.delta_qp
*
* To compute the resulting quantizer index for a block:
* - for luma AC, add the base qp and the per-block delta_qp, saturating to
* unsigned 8-bit.
* - for luma DC and chroma AC/DC, add the corresponding
* AVVideoBlockParams.delta_qp to the luma AC index, again saturating to
* unsigned 8-bit.
*/
AV_VIDEO_ENC_PARAMS_VP9,
/**
* H.264 stores:
* - in PPS (per-picture):
* * initial QP_Y (luma) value, exported as AVVideoEncParams.qp
* * delta(s) for chroma QP values (same for both, or each separately),
* exported as in the corresponding entries in AVVideoEncParams.delta_qp
* - per-slice QP delta, not exported directly, added to the per-MB value
* - per-MB delta; not exported directly; the final per-MB quantizer
* parameter - QP_Y - minus the value in AVVideoEncParams.qp is exported
* as AVVideoBlockParams.qp_delta.
*/
AV_VIDEO_ENC_PARAMS_H264,
/*
* MPEG-2-compatible quantizer.
*
* Summing the frame-level qp with the per-block delta_qp gives the
* resulting quantizer for the block.
*/
AV_VIDEO_ENC_PARAMS_MPEG2,
};
/**
* Video encoding parameters for a given frame. This struct is allocated along
* with an optional array of per-block AVVideoBlockParams descriptors.
* Must be allocated with av_video_enc_params_alloc().
*/
typedef struct AVVideoEncParams {
/**
* Number of blocks in the array.
*
* May be 0, in which case no per-block information is present. In this case
* the values of blocks_offset / block_size are unspecified and should not
* be accessed.
*/
unsigned int nb_blocks;
/**
* Offset in bytes from the beginning of this structure at which the array
* of blocks starts.
*/
size_t blocks_offset;
/*
* Size of each block in bytes. May not match sizeof(AVVideoBlockParams).
*/
size_t block_size;
/**
* Type of the parameters (the codec they are used with).
*/
enum AVVideoEncParamsType type;
/**
* Base quantisation parameter for the frame. The final quantiser for a
* given block in a given plane is obtained from this value, possibly
* combined with {@code delta_qp} and the per-block delta in a manner
* documented for each type.
*/
int32_t qp;
/**
* Quantisation parameter offset from the base (per-frame) qp for a given
* plane (first index) and AC/DC coefficients (second index).
*/
int32_t delta_qp[4][2];
} AVVideoEncParams;
/**
* Data structure for storing block-level encoding information.
* It is allocated as a part of AVVideoEncParams and should be retrieved with
* av_video_enc_params_block().
*
* sizeof(AVVideoBlockParams) is not a part of the ABI and new fields may be
* added to it.
*/
typedef struct AVVideoBlockParams {
/**
* Distance in luma pixels from the top-left corner of the visible frame
* to the top-left corner of the block.
* Can be negative if top/right padding is present on the coded frame.
*/
int src_x, src_y;
/**
* Width and height of the block in luma pixels.
*/
int w, h;
/**
* Difference between this block's final quantization parameter and the
* corresponding per-frame value.
*/
int32_t delta_qp;
} AVVideoBlockParams;
/*
* Get the block at the specified {@code idx}. Must be between 0 and nb_blocks.
*/
static av_always_inline AVVideoBlockParams*
av_video_enc_params_block(AVVideoEncParams *par, unsigned int idx)
{
av_assert0(idx < par->nb_blocks);
return (AVVideoBlockParams *)((uint8_t *)par + par->blocks_offset +
idx * par->block_size);
}
/**
* Allocates memory for AVVideoEncParams of the given type, plus an array of
* {@code nb_blocks} AVVideoBlockParams and initializes the variables. Can be
* freed with a normal av_free() call.
*
* @param out_size if non-NULL, the size in bytes of the resulting data array is
* written here.
*/
AVVideoEncParams *av_video_enc_params_alloc(enum AVVideoEncParamsType type,
unsigned int nb_blocks, size_t *out_size);
/**
* Allocates memory for AVEncodeInfoFrame plus an array of
* {@code nb_blocks} AVEncodeInfoBlock in the given AVFrame {@code frame}
* as AVFrameSideData of type AV_FRAME_DATA_VIDEO_ENC_PARAMS
* and initializes the variables.
*/
AVVideoEncParams*
av_video_enc_params_create_side_data(AVFrame *frame, enum AVVideoEncParamsType type,
unsigned int nb_blocks);
#endif /* AVUTIL_VIDEO_ENC_PARAMS_H */

Просмотреть файл

@ -26,6 +26,7 @@
#include <stdint.h> #include <stdint.h>
#if defined(_MSC_VER) #if defined(_MSC_VER)
#include <stdlib.h>
#include <intrin.h> #include <intrin.h>
#endif #endif
#include "config.h" #include "config.h"

Просмотреть файл

@ -411,16 +411,6 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%endif %endif
%endmacro %endmacro
%macro DEFINE_ARGS_INTERNAL 3+
%ifnum %2
DEFINE_ARGS %3
%elif %1 == 4
DEFINE_ARGS %2
%elif %1 > 4
DEFINE_ARGS %2, %3
%endif
%endmacro
%if WIN64 ; Windows x64 ;================================================= %if WIN64 ; Windows x64 ;=================================================
DECLARE_REG 0, rcx DECLARE_REG 0, rcx
@ -439,7 +429,7 @@ DECLARE_REG 12, R15, 104
DECLARE_REG 13, R12, 112 DECLARE_REG 13, R12, 112
DECLARE_REG 14, R13, 120 DECLARE_REG 14, R13, 120
%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names...
%assign num_args %1 %assign num_args %1
%assign regs_used %2 %assign regs_used %2
ASSERT regs_used >= num_args ASSERT regs_used >= num_args
@ -451,7 +441,15 @@ DECLARE_REG 14, R13, 120
WIN64_SPILL_XMM %3 WIN64_SPILL_XMM %3
%endif %endif
LOAD_IF_USED 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 LOAD_IF_USED 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
DEFINE_ARGS_INTERNAL %0, %4, %5 %if %0 > 4
%ifnum %4
DEFINE_ARGS %5
%else
DEFINE_ARGS %4, %5
%endif
%elifnnum %4
DEFINE_ARGS %4
%endif
%endmacro %endmacro
%macro WIN64_PUSH_XMM 0 %macro WIN64_PUSH_XMM 0
@ -547,7 +545,7 @@ DECLARE_REG 12, R15, 56
DECLARE_REG 13, R12, 64 DECLARE_REG 13, R12, 64
DECLARE_REG 14, R13, 72 DECLARE_REG 14, R13, 72
%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names...
%assign num_args %1 %assign num_args %1
%assign regs_used %2 %assign regs_used %2
%assign xmm_regs_used %3 %assign xmm_regs_used %3
@ -557,7 +555,15 @@ DECLARE_REG 14, R13, 72
PUSH_IF_USED 9, 10, 11, 12, 13, 14 PUSH_IF_USED 9, 10, 11, 12, 13, 14
ALLOC_STACK %4 ALLOC_STACK %4
LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14 LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14
DEFINE_ARGS_INTERNAL %0, %4, %5 %if %0 > 4
%ifnum %4
DEFINE_ARGS %5
%else
DEFINE_ARGS %4, %5
%endif
%elifnnum %4
DEFINE_ARGS %4
%endif
%endmacro %endmacro
%define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required %define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required
@ -598,7 +604,7 @@ DECLARE_REG 6, ebp, 28
DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, [stack_size,] arg_names... %macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names...
%assign num_args %1 %assign num_args %1
%assign regs_used %2 %assign regs_used %2
ASSERT regs_used >= num_args ASSERT regs_used >= num_args
@ -613,7 +619,15 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
PUSH_IF_USED 3, 4, 5, 6 PUSH_IF_USED 3, 4, 5, 6
ALLOC_STACK %4 ALLOC_STACK %4
LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6 LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6
DEFINE_ARGS_INTERNAL %0, %4, %5 %if %0 > 4
%ifnum %4
DEFINE_ARGS %5
%else
DEFINE_ARGS %4, %5
%endif
%elifnnum %4
DEFINE_ARGS %4
%endif
%endmacro %endmacro
%define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required %define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required