зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
4d33553f15
Коммит
00194d2ef1
|
@ -32,6 +32,10 @@
|
|||
# define FUNC #
|
||||
#endif
|
||||
|
||||
#ifndef __has_feature
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
.macro function name, export=0, align=2
|
||||
.macro endfunc
|
||||
ELF .size \name, . - \name
|
||||
|
@ -63,6 +67,8 @@ ELF .size \name, . - \name
|
|||
.else
|
||||
.section .rodata
|
||||
.endif
|
||||
#elif defined(_WIN32)
|
||||
.section .rdata
|
||||
#elif !defined(__MACH__)
|
||||
.section .rodata
|
||||
#else
|
||||
|
@ -92,7 +98,11 @@ ELF .size \name, . - \name
|
|||
add \rd, \rd, :lo12:\val+(\offset)
|
||||
.endif
|
||||
#elif CONFIG_PIC
|
||||
# if __has_feature(hwaddress_sanitizer)
|
||||
adrp \rd, :pg_hi21_nc:\val+(\offset)
|
||||
# else
|
||||
adrp \rd, \val+(\offset)
|
||||
# endif
|
||||
add \rd, \rd, :lo12:\val+(\offset)
|
||||
#else
|
||||
ldr \rd, =\val+\offset
|
||||
|
@ -102,3 +112,6 @@ ELF .size \name, . - \name
|
|||
#define GLUE(a, b) a ## b
|
||||
#define JOIN(a, b) GLUE(a, b)
|
||||
#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 "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
|
||||
|
||||
|
|
|
@ -41,8 +41,12 @@
|
|||
#define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(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 int len)
|
||||
#else
|
||||
AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len)
|
||||
#endif
|
||||
{
|
||||
unsigned long s1 = adler & 0xffff;
|
||||
unsigned long s2 = adler >> 16;
|
||||
|
|
|
@ -27,8 +27,10 @@
|
|||
#ifndef AVUTIL_ADLER32_H
|
||||
#define AVUTIL_ADLER32_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "attributes.h"
|
||||
#include "version.h"
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
|
@ -50,8 +58,12 @@
|
|||
* @param len size of input buffer
|
||||
* @return updated checksum
|
||||
*/
|
||||
unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf,
|
||||
unsigned int len) av_pure;
|
||||
AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf,
|
||||
#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 "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
|
||||
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
# define AV_GCC_VERSION_AT_MOST(x,y) 0
|
||||
#endif
|
||||
|
||||
#ifdef __has_builtin
|
||||
# define AV_HAS_BUILTIN(x) __has_builtin(x)
|
||||
#else
|
||||
# define AV_HAS_BUILTIN(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef av_always_inline
|
||||
#if AV_GCC_VERSION_AT_LEAST(3,1)
|
||||
# define av_always_inline __attribute__((always_inline)) inline
|
||||
|
|
|
@ -136,6 +136,7 @@ end:
|
|||
return p;
|
||||
}
|
||||
|
||||
#if FF_API_D2STR
|
||||
char *av_d2str(double d)
|
||||
{
|
||||
char *str = av_malloc(16);
|
||||
|
@ -143,6 +144,7 @@ char *av_d2str(double d)
|
|||
snprintf(str, 16, "%f", d);
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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)
|
||||
{
|
||||
char *p = strrchr(path, '/');
|
||||
|
||||
char *p;
|
||||
#if HAVE_DOS_PATHS
|
||||
char *q = strrchr(path, '\\');
|
||||
char *d = strchr(path, ':');
|
||||
char *q, *d;
|
||||
#endif
|
||||
|
||||
if (!path || *path == '\0')
|
||||
return ".";
|
||||
|
||||
p = strrchr(path, '/');
|
||||
#if HAVE_DOS_PATHS
|
||||
q = strrchr(path, '\\');
|
||||
d = strchr(path, ':');
|
||||
p = FFMAX3(p, q, d);
|
||||
#endif
|
||||
|
||||
|
@ -274,11 +282,11 @@ const char *av_basename(const char *path)
|
|||
|
||||
const char *av_dirname(char *path)
|
||||
{
|
||||
char *p = strrchr(path, '/');
|
||||
char *p = path ? strrchr(path, '/') : NULL;
|
||||
|
||||
#if HAVE_DOS_PATHS
|
||||
char *q = strrchr(path, '\\');
|
||||
char *d = strchr(path, ':');
|
||||
char *q = path ? strrchr(path, '\\') : NULL;
|
||||
char *d = path ? strchr(path, ':') : NULL;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
if (!av_bprint_is_complete(&dstbuf)) {
|
||||
av_bprint_finalize(&dstbuf, NULL);
|
||||
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)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "attributes.h"
|
||||
#include "version.h"
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
#if FF_API_D2STR
|
||||
/**
|
||||
* 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);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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.
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Thread safe dirname.
|
||||
* @param path the path, on DOS both \ and / are considered separators.
|
||||
* @return the path with the separator replaced by the string terminator or ".".
|
||||
* @note the function may change the input string.
|
||||
* @param path the string to parse, on DOS both \ and / are considered separators.
|
||||
* @return A pointer to a string that's the parent directory of path.
|
||||
* 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);
|
||||
|
||||
|
@ -314,6 +324,7 @@ enum AVEscapeMode {
|
|||
AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode.
|
||||
AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash 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)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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_uninit
|
||||
av_buffer_realloc
|
||||
av_buffer_replace
|
||||
av_buffer_ref
|
||||
av_buffer_unref
|
||||
av_calloc
|
||||
|
@ -173,9 +174,11 @@ av_image_fill_arrays
|
|||
av_image_fill_linesizes
|
||||
av_image_fill_max_pixsteps
|
||||
av_image_fill_pointers
|
||||
av_image_fill_plane_sizes
|
||||
av_image_get_buffer_size
|
||||
av_image_get_linesize
|
||||
av_int_list_length_for_size
|
||||
av_film_grain_params_create_side_data
|
||||
av_log
|
||||
#ifndef MOZ_FFVPX_AUDIOONLY
|
||||
av_log2
|
||||
|
@ -303,6 +306,7 @@ av_utf8_decode
|
|||
av_util_ffversion
|
||||
av_vbprintf
|
||||
av_version_info
|
||||
av_video_enc_params_create_side_data
|
||||
av_vlog
|
||||
av_write_image_line
|
||||
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)
|
||||
{
|
||||
uint8_t *dst = out;
|
||||
uint8_t *end = out + out_size;
|
||||
uint8_t *end;
|
||||
// no sign extension
|
||||
const uint8_t *in = in_str;
|
||||
unsigned bits = 0xff;
|
||||
unsigned v;
|
||||
|
||||
if (!out)
|
||||
goto validity_check;
|
||||
|
||||
end = out + out_size;
|
||||
while (end - dst > 3) {
|
||||
BASE64_DEC_STEP(0);
|
||||
BASE64_DEC_STEP(1);
|
||||
|
@ -108,6 +112,7 @@ int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
|
|||
*dst++ = v;
|
||||
in += 4;
|
||||
}
|
||||
validity_check:
|
||||
while (1) {
|
||||
BASE64_DEC_STEP(0);
|
||||
in++;
|
||||
|
@ -126,7 +131,7 @@ out2:
|
|||
*dst++ = v >> 4;
|
||||
out1:
|
||||
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);
|
||||
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", "&"); break;
|
||||
case '<' : av_bprintf(dstbuf, "%s", "<"); break;
|
||||
case '>' : av_bprintf(dstbuf, "%s", ">"); break;
|
||||
case '\'':
|
||||
if (!(flags & AV_ESCAPE_FLAG_XML_SINGLE_QUOTES))
|
||||
goto XML_DEFAULT_HANDLING;
|
||||
|
||||
av_bprintf(dstbuf, "%s", "'");
|
||||
break;
|
||||
case '"' :
|
||||
if (!(flags & AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES))
|
||||
goto XML_DEFAULT_HANDLING;
|
||||
|
||||
av_bprintf(dstbuf, "%s", """);
|
||||
break;
|
||||
XML_DEFAULT_HANDLING:
|
||||
default: av_bprint_chars(dstbuf, *src, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */
|
||||
default:
|
||||
/* \-escape characters */
|
||||
|
|
|
@ -20,12 +20,13 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avassert.h"
|
||||
#include "buffer_internal.h"
|
||||
#include "common.h"
|
||||
#include "mem.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 *opaque, int flags)
|
||||
{
|
||||
|
@ -43,8 +44,7 @@ AVBufferRef *av_buffer_create(uint8_t *data, int size,
|
|||
|
||||
atomic_init(&buf->refcount, 1);
|
||||
|
||||
if (flags & AV_BUFFER_FLAG_READONLY)
|
||||
buf->flags |= BUFFER_FLAG_READONLY;
|
||||
buf->flags = flags;
|
||||
|
||||
ref = av_mallocz(sizeof(*ref));
|
||||
if (!ref) {
|
||||
|
@ -64,7 +64,7 @@ void av_buffer_default_free(void *opaque, uint8_t *data)
|
|||
av_free(data);
|
||||
}
|
||||
|
||||
AVBufferRef *av_buffer_alloc(int size)
|
||||
AVBufferRef *av_buffer_alloc(buffer_size_t size)
|
||||
{
|
||||
AVBufferRef *ret = NULL;
|
||||
uint8_t *data = NULL;
|
||||
|
@ -80,7 +80,7 @@ AVBufferRef *av_buffer_alloc(int size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
AVBufferRef *av_buffer_allocz(int size)
|
||||
AVBufferRef *av_buffer_allocz(buffer_size_t size)
|
||||
{
|
||||
AVBufferRef *ret = av_buffer_alloc(size);
|
||||
if (!ret)
|
||||
|
@ -116,7 +116,7 @@ static void buffer_replace(AVBufferRef **dst, AVBufferRef **src)
|
|||
} else
|
||||
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);
|
||||
av_freep(&b);
|
||||
}
|
||||
|
@ -166,10 +166,11 @@ int av_buffer_make_writable(AVBufferRef **pbuf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int av_buffer_realloc(AVBufferRef **pbuf, int size)
|
||||
int av_buffer_realloc(AVBufferRef **pbuf, buffer_size_t size)
|
||||
{
|
||||
AVBufferRef *buf = *pbuf;
|
||||
uint8_t *tmp;
|
||||
int ret;
|
||||
|
||||
if (!buf) {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
buf->buffer->flags |= BUFFER_FLAG_REALLOCATABLE;
|
||||
buf->buffer->flags_internal |= BUFFER_FLAG_REALLOCATABLE;
|
||||
*pbuf = buf;
|
||||
|
||||
return 0;
|
||||
} else if (buf->size == size)
|
||||
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) {
|
||||
/* cannot realloc, allocate a new reallocable buffer and copy data */
|
||||
AVBufferRef *new = NULL;
|
||||
|
||||
av_buffer_realloc(&new, size);
|
||||
if (!new)
|
||||
return AVERROR(ENOMEM);
|
||||
ret = av_buffer_realloc(&new, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memcpy(new->data, buf->data, FFMIN(size, buf->size));
|
||||
|
||||
|
@ -215,8 +216,34 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
|
||||
AVBufferRef* (*alloc)(void *opaque, int size),
|
||||
int av_buffer_replace(AVBufferRef **pdst, AVBufferRef *src)
|
||||
{
|
||||
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))
|
||||
{
|
||||
AVBufferPool *pool = av_mallocz(sizeof(*pool));
|
||||
|
@ -228,6 +255,7 @@ AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
|
|||
pool->size = size;
|
||||
pool->opaque = opaque;
|
||||
pool->alloc2 = alloc;
|
||||
pool->alloc = av_buffer_alloc; // fallback
|
||||
pool->pool_free = pool_free;
|
||||
|
||||
atomic_init(&pool->refcount, 1);
|
||||
|
@ -235,7 +263,7 @@ AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
|
|||
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));
|
||||
if (!pool)
|
||||
|
@ -251,11 +279,7 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size))
|
|||
return 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)
|
||||
static void buffer_pool_flush(AVBufferPool *pool)
|
||||
{
|
||||
while (pool->pool) {
|
||||
BufferPoolEntry *buf = pool->pool;
|
||||
|
@ -264,6 +288,15 @@ static void buffer_pool_free(AVBufferPool *pool)
|
|||
buf->free(buf->opaque, buf->data);
|
||||
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);
|
||||
|
||||
if (pool->pool_free)
|
||||
|
@ -281,7 +314,11 @@ void av_buffer_pool_uninit(AVBufferPool **ppool)
|
|||
pool = *ppool;
|
||||
*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);
|
||||
}
|
||||
|
||||
|
@ -298,7 +335,7 @@ static void pool_release_buffer(void *opaque, uint8_t *data)
|
|||
pool->pool = buf;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -309,6 +346,8 @@ static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool)
|
|||
BufferPoolEntry *buf;
|
||||
AVBufferRef *ret;
|
||||
|
||||
av_assert0(pool->alloc || pool->alloc2);
|
||||
|
||||
ret = pool->alloc2 ? pool->alloc2(pool->opaque, pool->size) :
|
||||
pool->alloc(pool->size);
|
||||
if (!ret)
|
||||
|
@ -355,3 +394,10 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool)
|
|||
|
||||
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
|
||||
#define AVUTIL_BUFFER_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "version.h"
|
||||
|
||||
/**
|
||||
* @defgroup lavu_buffer AVBuffer
|
||||
* @ingroup lavu_data
|
||||
|
@ -90,7 +93,11 @@ typedef struct AVBufferRef {
|
|||
/**
|
||||
* Size of data in bytes.
|
||||
*/
|
||||
#if FF_API_BUFFER_SIZE_T
|
||||
int size;
|
||||
#else
|
||||
size_t size;
|
||||
#endif
|
||||
} AVBufferRef;
|
||||
|
||||
/**
|
||||
|
@ -98,13 +105,21 @@ typedef struct AVBufferRef {
|
|||
*
|
||||
* @return an AVBufferRef of given size or NULL when out of memory
|
||||
*/
|
||||
#if FF_API_BUFFER_SIZE_T
|
||||
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
|
||||
* to zero.
|
||||
*/
|
||||
#if FF_API_BUFFER_SIZE_T
|
||||
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
|
||||
|
@ -127,7 +142,11 @@ AVBufferRef *av_buffer_allocz(int size);
|
|||
*
|
||||
* @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,
|
||||
#else
|
||||
AVBufferRef *av_buffer_create(uint8_t *data, size_t size,
|
||||
#endif
|
||||
void (*free)(void *opaque, uint8_t *data),
|
||||
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
|
||||
* a new buffer is allocated and the data is copied.
|
||||
*/
|
||||
#if FF_API_BUFFER_SIZE_T
|
||||
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()).
|
||||
* @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));
|
||||
#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.
|
||||
|
@ -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 opaque arbitrary user data used by the allocator
|
||||
* @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
|
||||
* is freed. I.e. after av_buffer_pool_uninit() is called
|
||||
* by the caller and all the frames are returned to the pool
|
||||
* 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.
|
||||
*/
|
||||
#if FF_API_BUFFER_SIZE_T
|
||||
AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
|
||||
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));
|
||||
|
||||
/**
|
||||
|
@ -284,6 +333,19 @@ void av_buffer_pool_uninit(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 <stdint.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "buffer.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.
|
||||
*/
|
||||
#define BUFFER_FLAG_REALLOCATABLE (1 << 1)
|
||||
#define BUFFER_FLAG_REALLOCATABLE (1 << 0)
|
||||
|
||||
struct AVBuffer {
|
||||
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
|
||||
|
@ -54,9 +51,14 @@ struct AVBuffer {
|
|||
void *opaque;
|
||||
|
||||
/**
|
||||
* A combination of BUFFER_FLAG_*
|
||||
* A combination of AV_BUFFER_FLAG_*
|
||||
*/
|
||||
int flags;
|
||||
|
||||
/**
|
||||
* A combination of BUFFER_FLAG_*
|
||||
*/
|
||||
int flags_internal;
|
||||
};
|
||||
|
||||
typedef struct BufferPoolEntry {
|
||||
|
@ -88,10 +90,10 @@ struct AVBufferPool {
|
|||
*/
|
||||
atomic_uint refcount;
|
||||
|
||||
int size;
|
||||
buffer_size_t size;
|
||||
void *opaque;
|
||||
AVBufferRef* (*alloc)(int size);
|
||||
AVBufferRef* (*alloc2)(void *opaque, int size);
|
||||
AVBufferRef* (*alloc)(buffer_size_t size);
|
||||
AVBufferRef* (*alloc2)(void *opaque, buffer_size_t size);
|
||||
void (*pool_free)(void *opaque);
|
||||
};
|
||||
|
||||
|
|
|
@ -62,6 +62,11 @@ static const struct channel_name channel_names[] = {
|
|||
[33] = { "SDL", "surround direct left" },
|
||||
[34] = { "SDR", "surround direct right" },
|
||||
[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)
|
||||
|
@ -104,6 +109,7 @@ static const struct {
|
|||
{ "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL },
|
||||
{ "hexadecagonal", 16, AV_CH_LAYOUT_HEXADECAGONAL },
|
||||
{ "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)
|
||||
|
|
|
@ -71,6 +71,11 @@
|
|||
#define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL
|
||||
#define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL
|
||||
#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
|
||||
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_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_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 {
|
||||
AV_MATRIX_ENCODING_NONE,
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
//rounded division & shift
|
||||
#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
|
||||
/* 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 */
|
||||
#define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \
|
||||
: ((a) + (1<<(b)) - 1) >> (b))
|
||||
|
@ -80,6 +80,15 @@
|
|||
*/
|
||||
#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.
|
||||
* 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"
|
||||
#endif
|
||||
|
||||
/* Pull in unguarded fallback defines at the end of this file. */
|
||||
#include "common.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_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
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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)
|
||||
{
|
||||
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.
|
||||
* Evaluated up to 7 times (4 for the currently
|
||||
* 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,
|
||||
* 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;\
|
||||
if ((val & 0xc0) == 0x80 || val >= 0xFE)\
|
||||
ERROR\
|
||||
{ERROR}\
|
||||
while (val & top) {\
|
||||
int tmp= (GET_BYTE) - 128;\
|
||||
unsigned int tmp = (GET_BYTE) - 128;\
|
||||
if(tmp>>6)\
|
||||
ERROR\
|
||||
{ERROR}\
|
||||
val= (val<<6) + tmp;\
|
||||
top <<= 5;\
|
||||
}\
|
||||
|
@ -408,13 +522,13 @@ static av_always_inline av_const int av_parity_c(uint32_t v)
|
|||
* typically a goto statement.
|
||||
*/
|
||||
#define GET_UTF16(val, GET_16BIT, ERROR)\
|
||||
val = GET_16BIT;\
|
||||
val = (GET_16BIT);\
|
||||
{\
|
||||
unsigned int hi = val - 0xD800;\
|
||||
if (hi < 0x800) {\
|
||||
val = GET_16BIT - 0xDC00;\
|
||||
val = (GET_16BIT) - 0xDC00;\
|
||||
if (val > 0x3FFU || hi > 0x3FFU)\
|
||||
ERROR\
|
||||
{ERROR}\
|
||||
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 /* 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)
|
||||
{
|
||||
if (ARCH_MIPS)
|
||||
return ff_get_cpu_flags_mips();
|
||||
if (ARCH_AARCH64)
|
||||
return ff_get_cpu_flags_aarch64();
|
||||
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" },
|
||||
{ "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" },
|
||||
#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
|
||||
{ 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" },
|
||||
{ "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" },
|
||||
#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
|
||||
{ NULL },
|
||||
};
|
||||
|
@ -283,6 +291,12 @@ int av_cpu_count(void)
|
|||
DWORD_PTR proc_aff, sys_aff;
|
||||
if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_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)
|
||||
int mib[2] = { CTL_HW, HW_NCPU };
|
||||
size_t len = sizeof(nb_cpus);
|
||||
|
@ -308,6 +322,8 @@ int av_cpu_count(void)
|
|||
|
||||
size_t av_cpu_max_align(void)
|
||||
{
|
||||
if (ARCH_MIPS)
|
||||
return ff_get_cpu_max_align_mips();
|
||||
if (ARCH_AARCH64)
|
||||
return ff_get_cpu_max_align_aarch64();
|
||||
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_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.
|
||||
* 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_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_arm(void);
|
||||
int ff_get_cpu_flags_ppc(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_arm(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);
|
||||
*tag = m->elems[--m->count];
|
||||
} else if (copy_value) {
|
||||
AVDictionaryEntry *tmp = av_realloc(m->elems,
|
||||
(m->count + 1) * sizeof(*m->elems));
|
||||
AVDictionaryEntry *tmp = av_realloc_array(m->elems,
|
||||
m->count + 1, sizeof(*m->elems));
|
||||
if (!tmp)
|
||||
goto err_out;
|
||||
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_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_sgn,
|
||||
} type;
|
||||
double value; // is sign in other types
|
||||
int const_index;
|
||||
union {
|
||||
int const_index;
|
||||
double (*func0)(double);
|
||||
double (*func1)(void *, double);
|
||||
double (*func2)(void *, double, double);
|
||||
|
@ -184,7 +185,7 @@ static double eval_expr(Parser *p, AVExpr *e)
|
|||
{
|
||||
switch (e->type) {
|
||||
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_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]));
|
||||
|
@ -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_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_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_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]) :
|
||||
|
@ -304,7 +306,7 @@ static double eval_expr(Parser *p, AVExpr *e)
|
|||
double d = eval_expr(p, e->param[0]);
|
||||
double d2 = eval_expr(p, e->param[1]);
|
||||
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_max: 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_pow: return e->value * pow(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_last:return e->value * 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])) {
|
||||
p->s+= strlen(p->const_names[i]);
|
||||
d->type = e_const;
|
||||
d->a.const_index = i;
|
||||
d->const_index = i;
|
||||
*e = d;
|
||||
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, "atan2" )) d->type = e_atan2;
|
||||
else if (strmatch(next, "lerp" )) d->type = e_lerp;
|
||||
else if (strmatch(next, "sgn" )) d->type = e_sgn;
|
||||
else {
|
||||
for (i=0; p->func1_names && p->func1_names[i]; i++) {
|
||||
if (strmatch(next, p->func1_names[i])) {
|
||||
d->a.func1 = p->funcs1[i];
|
||||
d->type = e_func1;
|
||||
d->const_index = i;
|
||||
*e = d;
|
||||
return 0;
|
||||
}
|
||||
|
@ -484,6 +488,7 @@ static int parse_primary(AVExpr **e, Parser *p)
|
|||
if (strmatch(next, p->func2_names[i])) {
|
||||
d->a.func2 = p->funcs2[i];
|
||||
d->type = e_func2;
|
||||
d->const_index = i;
|
||||
*e = d;
|
||||
return 0;
|
||||
}
|
||||
|
@ -657,6 +662,7 @@ static int verify_expr(AVExpr *e)
|
|||
case e_sqrt:
|
||||
case e_not:
|
||||
case e_random:
|
||||
case e_sgn:
|
||||
return verify_expr(e->param[0]) && !e->param[1];
|
||||
case e_print:
|
||||
return verify_expr(e->param[0])
|
||||
|
@ -731,6 +737,32 @@ end:
|
|||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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().
|
||||
*/
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define AVUTIL_TIME_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
static void butterflies_fixed_c(int *v1, int *v2, int len)
|
||||
static void butterflies_fixed_c(int *v1s, int *v2, int len)
|
||||
{
|
||||
int i;
|
||||
unsigned int *v1 = v1s;
|
||||
|
||||
for (i = 0; i < len; i++){
|
||||
int t = v1[i] - v2[i];
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "imgutils.h"
|
||||
#include "mem.h"
|
||||
#include "samplefmt.h"
|
||||
#include "hwcontext.h"
|
||||
|
||||
#if FF_API_FRAME_GET_SET
|
||||
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)
|
||||
{
|
||||
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);
|
||||
ptrdiff_t linesizes[4];
|
||||
size_t sizes[4];
|
||||
|
||||
if (!desc)
|
||||
return AVERROR(EINVAL);
|
||||
|
@ -237,12 +240,22 @@ static int get_video_buffer(AVFrame *frame, int 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);
|
||||
if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height,
|
||||
NULL, frame->linesize)) < 0)
|
||||
if ((ret = av_image_fill_plane_sizes(sizes, frame->format,
|
||||
padded_height, linesizes)) < 0)
|
||||
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]) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
int ret, i;
|
||||
|
||||
dst->key_frame = src->key_frame;
|
||||
dst->pict_type = src->pict_type;
|
||||
|
@ -413,31 +426,18 @@ FF_DISABLE_DEPRECATION_WARNINGS
|
|||
dst->qscale_table = NULL;
|
||||
dst->qstride = 0;
|
||||
dst->qscale_type = 0;
|
||||
av_buffer_unref(&dst->qp_table_buf);
|
||||
if (src->qp_table_buf) {
|
||||
dst->qp_table_buf = av_buffer_ref(src->qp_table_buf);
|
||||
if (dst->qp_table_buf) {
|
||||
dst->qscale_table = dst->qp_table_buf->data;
|
||||
dst->qstride = src->qstride;
|
||||
dst->qscale_type = src->qscale_type;
|
||||
}
|
||||
av_buffer_replace(&dst->qp_table_buf, src->qp_table_buf);
|
||||
if (dst->qp_table_buf) {
|
||||
dst->qscale_table = dst->qp_table_buf->data;
|
||||
dst->qstride = src->qstride;
|
||||
dst->qscale_type = src->qscale_type;
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
av_buffer_unref(&dst->opaque_ref);
|
||||
av_buffer_unref(&dst->private_ref);
|
||||
if (src->opaque_ref) {
|
||||
dst->opaque_ref = av_buffer_ref(src->opaque_ref);
|
||||
if (!dst->opaque_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if (src->private_ref) {
|
||||
dst->private_ref = av_buffer_ref(src->private_ref);
|
||||
if (!dst->private_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
return 0;
|
||||
ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
|
||||
ret |= av_buffer_replace(&dst->private_ref, src->private_ref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto fail;
|
||||
|
||||
/* duplicate the frame data if it's not refcounted */
|
||||
if (!src->buf[0]) {
|
||||
ret = av_frame_get_buffer(dst, 32);
|
||||
ret = av_frame_get_buffer(dst, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto fail;
|
||||
|
||||
ret = av_frame_copy(dst, src);
|
||||
if (ret < 0)
|
||||
av_frame_unref(dst);
|
||||
goto fail;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -626,7 +626,11 @@ int av_frame_make_writable(AVFrame *frame)
|
|||
tmp.channels = frame->channels;
|
||||
tmp.channel_layout = frame->channel_layout;
|
||||
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)
|
||||
return ret;
|
||||
|
||||
|
@ -721,7 +725,7 @@ AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
|
|||
|
||||
AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
|
||||
enum AVFrameSideDataType type,
|
||||
int size)
|
||||
buffer_size_t size)
|
||||
{
|
||||
AVFrameSideData *ret;
|
||||
AVBufferRef *buf = av_buffer_alloc(size);
|
||||
|
@ -752,6 +756,9 @@ static int frame_copy_video(AVFrame *dst, const AVFrame *src)
|
|||
dst->height < src->height)
|
||||
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);
|
||||
for (i = 0; i < planes; 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;
|
||||
|
||||
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];
|
||||
if (sd->type == type) {
|
||||
free_side_data(&frame->side_data[i]);
|
||||
|
@ -842,6 +849,9 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type)
|
|||
#endif
|
||||
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_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;
|
||||
}
|
||||
|
|
|
@ -162,8 +162,8 @@ enum AVFrameSideDataType {
|
|||
/**
|
||||
* 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.
|
||||
* The timecode format is described in the av_timecode_get_smpte_from_framenum()
|
||||
* function in libavutil/timecode.c.
|
||||
* The timecode format is described in the documentation of av_timecode_get_smpte_from_framenum()
|
||||
* function in libavutil/timecode.h.
|
||||
*/
|
||||
AV_FRAME_DATA_S12M_TIMECODE,
|
||||
|
||||
|
@ -179,6 +179,25 @@ enum AVFrameSideDataType {
|
|||
* array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size.
|
||||
*/
|
||||
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 {
|
||||
|
@ -201,7 +220,11 @@ enum AVActiveFormatDescription {
|
|||
typedef struct AVFrameSideData {
|
||||
enum AVFrameSideDataType type;
|
||||
uint8_t *data;
|
||||
#if FF_API_BUFFER_SIZE_T
|
||||
int size;
|
||||
#else
|
||||
size_t size;
|
||||
#endif
|
||||
AVDictionary *metadata;
|
||||
AVBufferRef *buf;
|
||||
} AVFrameSideData;
|
||||
|
@ -894,7 +917,11 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane);
|
|||
*/
|
||||
AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
|
||||
enum AVFrameSideDataType type,
|
||||
#if FF_API_BUFFER_SIZE_T
|
||||
int size);
|
||||
#else
|
||||
size_t size);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* If side data of the supplied type exists in the frame, free it and remove it
|
||||
* from the frame.
|
||||
* Remove and free all side data instances of the given type.
|
||||
*/
|
||||
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type);
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ static const HWContextType * const hw_table[] = {
|
|||
#endif
|
||||
#if CONFIG_MEDIACODEC
|
||||
&ff_hwcontext_type_mediacodec,
|
||||
#endif
|
||||
#if CONFIG_VULKAN
|
||||
&ff_hwcontext_type_vulkan,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
@ -73,6 +76,7 @@ static const char *const hw_type_names[] = {
|
|||
[AV_HWDEVICE_TYPE_VDPAU] = "vdpau",
|
||||
[AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox",
|
||||
[AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec",
|
||||
[AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
|
||||
};
|
||||
|
||||
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->height = ctx->height;
|
||||
|
||||
ret = av_frame_get_buffer(frame_tmp, 32);
|
||||
ret = av_frame_get_buffer(frame_tmp, 0);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -444,21 +448,54 @@ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
|
|||
if (!dst->buf[0])
|
||||
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)
|
||||
return ret;
|
||||
} else if (dst->hw_frames_ctx) {
|
||||
ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
|
||||
} else {
|
||||
if (src->hw_frames_ctx) {
|
||||
ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
|
||||
|
||||
ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else
|
||||
return AVERROR(ENOSYS);
|
||||
ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else if (dst->hw_frames_ctx) {
|
||||
ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
|
||||
|
||||
ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -520,6 +557,8 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
|
|||
return ret;
|
||||
}
|
||||
|
||||
frame->extended_data = frame->data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -604,9 +643,10 @@ fail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr,
|
||||
enum AVHWDeviceType type,
|
||||
AVBufferRef *src_ref, int flags)
|
||||
int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
|
||||
enum AVHWDeviceType type,
|
||||
AVBufferRef *src_ref,
|
||||
AVDictionary *options, int flags)
|
||||
{
|
||||
AVBufferRef *dst_ref = NULL, *tmp_ref;
|
||||
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) {
|
||||
ret = dst_ctx->internal->hw_type->device_derive(dst_ctx,
|
||||
tmp_ctx,
|
||||
options,
|
||||
flags);
|
||||
if (ret == 0) {
|
||||
dst_ctx->internal->source_device = av_buffer_ref(src_ref);
|
||||
|
@ -670,6 +711,14 @@ fail:
|
|||
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)
|
||||
{
|
||||
HWMapDescriptor *hwmap = (HWMapDescriptor*)data;
|
||||
|
|
|
@ -36,6 +36,7 @@ enum AVHWDeviceType {
|
|||
AV_HWDEVICE_TYPE_DRM,
|
||||
AV_HWDEVICE_TYPE_OPENCL,
|
||||
AV_HWDEVICE_TYPE_MEDIACODEC,
|
||||
AV_HWDEVICE_TYPE_VULKAN,
|
||||
};
|
||||
|
||||
typedef struct AVHWDeviceInternal AVHWDeviceInternal;
|
||||
|
@ -327,6 +328,26 @@ int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ctx,
|
|||
enum AVHWDeviceType type,
|
||||
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.
|
||||
|
|
|
@ -67,7 +67,8 @@ typedef struct HWContextType {
|
|||
int (*device_create)(AVHWDeviceContext *ctx, const char *device,
|
||||
AVDictionary *opts, int flags);
|
||||
int (*device_derive)(AVHWDeviceContext *dst_ctx,
|
||||
AVHWDeviceContext *src_ctx, int flags);
|
||||
AVHWDeviceContext *src_ctx,
|
||||
AVDictionary *opts, int flags);
|
||||
|
||||
int (*device_init)(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_videotoolbox;
|
||||
extern const HWContextType ff_hwcontext_type_mediacodec;
|
||||
extern const HWContextType ff_hwcontext_type_vulkan;
|
||||
|
||||
#endif /* AVUTIL_HWCONTEXT_INTERNAL_H */
|
||||
|
|
|
@ -118,6 +118,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = {
|
|||
#endif
|
||||
MAP(UYVY, YUV422, UYVY422, 0),
|
||||
MAP(YUY2, YUV422, YUYV422, 0),
|
||||
#ifdef VA_FOURCC_Y210
|
||||
MAP(Y210, YUV422_10, Y210, 0),
|
||||
#endif
|
||||
MAP(411P, YUV411, YUV411P, 0),
|
||||
MAP(422V, YUV422, YUV440P, 0),
|
||||
MAP(444P, YUV444, YUV444P, 0),
|
||||
|
@ -135,6 +138,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = {
|
|||
#endif
|
||||
MAP(ARGB, RGB32, ARGB, 0),
|
||||
MAP(XRGB, RGB32, 0RGB, 0),
|
||||
#ifdef VA_FOURCC_X2R10G10B10
|
||||
MAP(X2R10G10B10, RGB32_10, X2RGB10, 0),
|
||||
#endif
|
||||
};
|
||||
#undef MAP
|
||||
|
||||
|
@ -264,14 +270,24 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
|
|||
}
|
||||
|
||||
for (i = j = 0; i < attr_count; i++) {
|
||||
int k;
|
||||
|
||||
if (attr_list[i].type != VASurfaceAttribPixelFormat)
|
||||
continue;
|
||||
fourcc = attr_list[i].value.value.i;
|
||||
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;
|
||||
}
|
||||
av_assert0(j == pix_fmt_count);
|
||||
constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE;
|
||||
}
|
||||
} else {
|
||||
|
@ -283,9 +299,19 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
|
|||
err = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < ctx->nb_formats; i++)
|
||||
constraints->valid_sw_formats[i] = ctx->formats[i].pix_fmt;
|
||||
constraints->valid_sw_formats[i] = AV_PIX_FMT_NONE;
|
||||
for (i = j = 0; i < ctx->nb_formats; i++) {
|
||||
int k;
|
||||
|
||||
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));
|
||||
|
@ -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;
|
||||
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,
|
||||
AVHWDeviceContext *src_ctx, int flags)
|
||||
AVHWDeviceContext *src_ctx,
|
||||
AVDictionary *opts, int flags)
|
||||
{
|
||||
#if HAVE_VAAPI_DRM
|
||||
if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) {
|
||||
AVDRMDeviceContext *src_hwctx = src_ctx->hwctx;
|
||||
VADisplay *display;
|
||||
VAAPIDevicePriv *priv;
|
||||
int fd;
|
||||
|
||||
if (src_hwctx->fd < 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
priv = av_mallocz(sizeof(*priv));
|
||||
if (!priv)
|
||||
return AVERROR(ENOMEM);
|
||||
#if CONFIG_LIBDRM
|
||||
{
|
||||
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->drm_fd = -1;
|
||||
priv = av_mallocz(sizeof(*priv));
|
||||
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->free = &vaapi_device_free;
|
||||
|
||||
display = vaGetDisplayDRM(src_hwctx->fd);
|
||||
display = vaGetDisplayDRM(fd);
|
||||
if (!display) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from "
|
||||
"DRM device.\n");
|
||||
|
|
|
@ -108,45 +108,69 @@ int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int wi
|
|||
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 av_image_fill_plane_sizes(size_t sizes[4], enum AVPixelFormat pix_fmt,
|
||||
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);
|
||||
memset(data , 0, sizeof(data[0])*4);
|
||||
memset(sizes , 0, sizeof(sizes[0])*4);
|
||||
|
||||
if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
data[0] = ptr;
|
||||
if (linesizes[0] > (INT_MAX - 1024) / height)
|
||||
if (linesizes[0] > SIZE_MAX / height)
|
||||
return AVERROR(EINVAL);
|
||||
size[0] = linesizes[0] * height;
|
||||
sizes[0] = linesizes[0] * (size_t)height;
|
||||
|
||||
if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
|
||||
desc->flags & FF_PSEUDOPAL) {
|
||||
data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */
|
||||
return size[0] + 256 * 4;
|
||||
sizes[1] = 256 * 4; /* palette is stored here as 256 32 bits words */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
has_plane[desc->comp[i].plane] = 1;
|
||||
|
||||
total_size = size[0];
|
||||
for (i = 1; i < 4 && has_plane[i]; i++) {
|
||||
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;
|
||||
if (linesizes[i] > INT_MAX / h)
|
||||
if (linesizes[i] > SIZE_MAX / h)
|
||||
return AVERROR(EINVAL);
|
||||
size[i] = h * linesizes[i];
|
||||
if (total_size > INT_MAX - size[i])
|
||||
return AVERROR(EINVAL);
|
||||
total_size += size[i];
|
||||
sizes[i] = (size_t)h * linesizes[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)
|
||||
|
@ -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);
|
||||
int i, ret;
|
||||
ptrdiff_t linesizes1[4];
|
||||
size_t total_size, sizes[4];
|
||||
uint8_t *buf;
|
||||
|
||||
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)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < 4; i++) {
|
||||
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;
|
||||
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)
|
||||
return AVERROR(ENOMEM);
|
||||
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);
|
||||
if (align < 4) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Formats with a palette require a minimum alignment of 4\n");
|
||||
av_free(buf);
|
||||
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 width, int height, int align)
|
||||
{
|
||||
uint8_t *data[4];
|
||||
int ret, i;
|
||||
int linesize[4];
|
||||
int ret;
|
||||
ptrdiff_t aligned_linesize[4];
|
||||
size_t sizes[4];
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
|
||||
if (!desc)
|
||||
return AVERROR(EINVAL);
|
||||
|
@ -446,8 +482,24 @@ int av_image_get_buffer_size(enum AVPixelFormat pix_fmt,
|
|||
if (desc->flags & FF_PSEUDOPAL)
|
||||
return FFALIGN(width, align) * height;
|
||||
|
||||
return av_image_fill_arrays(data, linesize, NULL, pix_fmt,
|
||||
width, height, align);
|
||||
ret = av_image_fill_linesizes(linesize, pix_fmt, width);
|
||||
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,
|
||||
|
@ -519,7 +571,6 @@ static void memset_bytes(uint8_t *dst, size_t dst_size, uint8_t *clear,
|
|||
|
||||
if (clear_size == 1) {
|
||||
memset(dst, clear[0], dst_size);
|
||||
dst_size = 0;
|
||||
} else {
|
||||
if (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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* height height.
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "cpu.h"
|
||||
#include "dict.h"
|
||||
#include "macros.h"
|
||||
#include "mem.h"
|
||||
#include "pixfmt.h"
|
||||
#include "version.h"
|
||||
|
||||
|
@ -92,10 +91,6 @@
|
|||
type av_##name##_get_##field(const str *s) { return s->field; } \
|
||||
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.
|
||||
* Induce a compilation failure if not.
|
||||
*/
|
||||
|
@ -103,75 +98,11 @@
|
|||
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, ...) \
|
||||
DECLARE_ALIGNED(a, t, la_##v) s o; \
|
||||
t (*v) o = la_##v
|
||||
#define FF_ALLOC_TYPED_ARRAY(p, nelem) (p = av_malloc_array(nelem, sizeof(*p)))
|
||||
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem) (p = av_mallocz_array(nelem, sizeof(*p)))
|
||||
|
||||
#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
|
||||
|
||||
#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;\
|
||||
}\
|
||||
}
|
||||
#define FF_PTR_ADD(ptr, off) ((off) ? (ptr) + (off) : (ptr))
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
|
@ -353,7 +284,8 @@ void ff_check_pixfmt_descriptors(void);
|
|||
/**
|
||||
* 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 timestamp unix timestamp in microseconds
|
||||
* @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
|
||||
#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 */
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define AVUTIL_LLS_H
|
||||
|
||||
#include "macros.h"
|
||||
#include "mem.h"
|
||||
#include "mem_internal.h"
|
||||
#include "version.h"
|
||||
|
||||
#define MAX_VARS 32
|
||||
|
|
|
@ -55,7 +55,7 @@ static int av_log_level = AV_LOG_INFO;
|
|||
static int flags;
|
||||
|
||||
#define NB_LEVELS 8
|
||||
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE
|
||||
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
|
||||
#include <windows.h>
|
||||
static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = {
|
||||
[AV_LOG_PANIC /8] = 12,
|
||||
|
@ -120,50 +120,68 @@ static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = {
|
|||
#endif
|
||||
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)
|
||||
{
|
||||
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE
|
||||
char *term = getenv("TERM");
|
||||
|
||||
#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
|
||||
CONSOLE_SCREEN_BUFFER_INFO con_info;
|
||||
DWORD dummy;
|
||||
con = GetStdHandle(STD_ERROR_HANDLE);
|
||||
use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") &&
|
||||
!getenv("AV_LOG_FORCE_NOCOLOR");
|
||||
if (use_color) {
|
||||
if (con != INVALID_HANDLE_VALUE && !GetConsoleMode(con, &dummy))
|
||||
con = INVALID_HANDLE_VALUE;
|
||||
if (con != INVALID_HANDLE_VALUE) {
|
||||
GetConsoleScreenBufferInfo(con, &con_info);
|
||||
attr_orig = con_info.wAttributes;
|
||||
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
|
||||
|
||||
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) {
|
||||
fprintf(stderr,
|
||||
"\033[%"PRIu32";3%"PRIu32"m%s\033[0m",
|
||||
|
@ -184,6 +202,32 @@ static void colored_fputs(int level, int tint, const char *str)
|
|||
str);
|
||||
} else
|
||||
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
|
||||
|
||||
}
|
||||
|
@ -226,6 +270,8 @@ static const char *get_level_str(int level)
|
|||
return "quiet";
|
||||
case AV_LOG_DEBUG:
|
||||
return "debug";
|
||||
case AV_LOG_TRACE:
|
||||
return "trace";
|
||||
case AV_LOG_VERBOSE:
|
||||
return "verbose";
|
||||
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, ...)
|
||||
{
|
||||
AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
|
||||
va_list vl;
|
||||
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);
|
||||
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)
|
||||
{
|
||||
AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
|
||||
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)
|
||||
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");
|
||||
if (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");
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ typedef struct AVClass {
|
|||
*/
|
||||
void* (*child_next)(void *obj, void *prev);
|
||||
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
/**
|
||||
* Return an AVClass corresponding to the next potential
|
||||
* AVOptions-enabled child.
|
||||
|
@ -120,7 +121,9 @@ typedef struct AVClass {
|
|||
* child_next iterates over _already existing_ objects, while
|
||||
* child_class_next iterates over _all possible_ children.
|
||||
*/
|
||||
attribute_deprecated
|
||||
const struct AVClass* (*child_class_next)(const struct AVClass *prev);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Category used for visualization (like color)
|
||||
|
@ -140,6 +143,21 @@ typedef struct AVClass {
|
|||
* available since version (52.12)
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -233,6 +251,27 @@ typedef struct AVClass {
|
|||
*/
|
||||
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
|
||||
|
|
|
@ -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 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);
|
||||
if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b)
|
||||
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;
|
||||
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;
|
||||
if (m < d)
|
||||
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_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
|
||||
* 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()
|
||||
*/
|
||||
|
|
|
@ -78,8 +78,7 @@ void *av_malloc(size_t size)
|
|||
{
|
||||
void *ptr = NULL;
|
||||
|
||||
/* let's disallow possibly ambiguous cases */
|
||||
if (size > (max_alloc_size - 32))
|
||||
if (size > max_alloc_size)
|
||||
return NULL;
|
||||
|
||||
#if HAVE_POSIX_MEMALIGN
|
||||
|
@ -134,8 +133,7 @@ void *av_malloc(size_t size)
|
|||
|
||||
void *av_realloc(void *ptr, size_t size)
|
||||
{
|
||||
/* let's disallow possibly ambiguous cases */
|
||||
if (size > (max_alloc_size - 32))
|
||||
if (size > max_alloc_size)
|
||||
return NULL;
|
||||
|
||||
#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)
|
||||
{
|
||||
if (!size || nmemb >= INT_MAX / size)
|
||||
size_t result;
|
||||
if (av_size_mult(nmemb, size, &result) < 0)
|
||||
return NULL;
|
||||
return av_malloc(nmemb * size);
|
||||
return av_malloc(result);
|
||||
}
|
||||
|
||||
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 av_mallocz(nmemb * size);
|
||||
return av_mallocz(result);
|
||||
}
|
||||
|
||||
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 av_realloc(ptr, nmemb * size);
|
||||
return av_realloc(ptr, result);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (size <= 0 || nmemb >= INT_MAX / size)
|
||||
size_t result;
|
||||
if (av_size_mult(nmemb, size, &result) < 0)
|
||||
return NULL;
|
||||
return av_mallocz(nmemb * size);
|
||||
return av_mallocz(result);
|
||||
}
|
||||
|
||||
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)
|
||||
return ptr;
|
||||
|
||||
if (min_size > max_alloc_size - 32) {
|
||||
if (min_size > max_alloc_size) {
|
||||
*size = 0;
|
||||
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);
|
||||
/* we could set this to the unmodified min_size but this is safer
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "attributes.h"
|
||||
#include "error.h"
|
||||
#include "avutil.h"
|
||||
#include "version.h"
|
||||
|
||||
/**
|
||||
* @addtogroup lavu_mem
|
||||
|
@ -49,6 +50,10 @@
|
|||
* dealing with memory consistently possible on all platforms.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if FF_API_DECLARE_ALIGNED
|
||||
/**
|
||||
*
|
||||
* @defgroup lavu_mem_macros Alignment Macros
|
||||
* Helper macros for declaring aligned variables.
|
||||
|
@ -125,6 +130,7 @@
|
|||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup lavu_mem_attrs Function Attributes
|
||||
|
|
|
@ -21,8 +21,120 @@
|
|||
#ifndef AVUTIL_MEM_INTERNAL_H
|
||||
#define AVUTIL_MEM_INTERNAL_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "avassert.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)
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ SOURCES += [
|
|||
]
|
||||
if CONFIG['MOZ_WAYLAND']:
|
||||
SOURCES += [
|
||||
'hwcontext_vaapi.c',
|
||||
'hwcontext_vaapi.c'
|
||||
]
|
||||
USE_LIBS += ['mozva']
|
||||
|
||||
|
@ -56,12 +56,14 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
|
|||
'adler32.c',
|
||||
'base64.c',
|
||||
'color_utils.c',
|
||||
'film_grain_params.c',
|
||||
'integer.c',
|
||||
'intmath.c',
|
||||
'lls.c',
|
||||
'pixelutils.c',
|
||||
'threadmessage.c',
|
||||
'timecode.c'
|
||||
'timecode.c',
|
||||
'video_enc_params.c'
|
||||
]
|
||||
|
||||
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)
|
||||
{
|
||||
int ret = 0;
|
||||
int num, den;
|
||||
char c;
|
||||
|
||||
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;
|
||||
if (o->type == AV_OPT_TYPE_RATIONAL || o->type == AV_OPT_TYPE_VIDEO_RATE) {
|
||||
int num, den;
|
||||
char c;
|
||||
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 (;;) {
|
||||
|
@ -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 ci = 0;
|
||||
double const_values[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)
|
||||
d = DEFAULT_NUMVAL(o_named);
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
if (!val) {
|
||||
ret = AVERROR(EINVAL);
|
||||
} else {
|
||||
ret = av_parse_video_rate(dst, val);
|
||||
}
|
||||
int ret = av_parse_video_rate(dst, val);
|
||||
if (ret < 0)
|
||||
av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
|
||||
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");
|
||||
}
|
||||
|
||||
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 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;
|
||||
if (!val && (o->type != AV_OPT_TYPE_STRING &&
|
||||
o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
|
||||
o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_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_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL))
|
||||
return AVERROR(EINVAL);
|
||||
|
@ -527,6 +543,8 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
|
|||
return ret;
|
||||
}
|
||||
break;
|
||||
case AV_OPT_TYPE_DICT:
|
||||
return set_string_dict(obj, o, val, dst);
|
||||
}
|
||||
|
||||
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;
|
||||
ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
|
||||
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:
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
||||
int req_flags, int rej_flags)
|
||||
int req_flags, int rej_flags, enum AVOptionType parent_type)
|
||||
{
|
||||
const AVOption *opt = NULL;
|
||||
AVOptionRanges *r;
|
||||
|
@ -1157,6 +1198,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
|
|||
case AV_OPT_TYPE_BINARY:
|
||||
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
|
||||
break;
|
||||
case AV_OPT_TYPE_DICT:
|
||||
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<dictionary>");
|
||||
break;
|
||||
case AV_OPT_TYPE_IMAGE_SIZE:
|
||||
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
|
||||
break;
|
||||
|
@ -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>");
|
||||
break;
|
||||
case AV_OPT_TYPE_CONST:
|
||||
if (parent_type == AV_OPT_TYPE_INT)
|
||||
av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", opt->default_val.i64);
|
||||
else
|
||||
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
|
||||
break;
|
||||
default:
|
||||
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
|
||||
break;
|
||||
|
@ -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_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_RUNTIME_PARAM) ? 'T' : '.');
|
||||
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DEPRECATED) ? 'P' : '.');
|
||||
|
||||
if (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_IMAGE_SIZE ||
|
||||
opt->type == AV_OPT_TYPE_STRING ||
|
||||
opt->type == AV_OPT_TYPE_DICT ||
|
||||
opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
|
||||
!opt->default_val.str)) {
|
||||
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)
|
||||
av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
|
||||
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;
|
||||
}
|
||||
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_IMAGE_SIZE:
|
||||
case AV_OPT_TYPE_STRING:
|
||||
case AV_OPT_TYPE_DICT:
|
||||
case AV_OPT_TYPE_VIDEO_RATE:
|
||||
av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
|
||||
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");
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
break;
|
||||
case AV_OPT_TYPE_DICT:
|
||||
/* Cannot set defaults for these types */
|
||||
break;
|
||||
set_string_dict(s, opt, opt->default_val.str, dst);
|
||||
break;
|
||||
default:
|
||||
av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n",
|
||||
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_FAKE_OBJ) {
|
||||
const AVClass *child = NULL;
|
||||
while (child = av_opt_child_class_next(c, child))
|
||||
void *iter = NULL;
|
||||
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))
|
||||
return o;
|
||||
} else {
|
||||
|
@ -1663,12 +1717,31 @@ void *av_opt_child_next(void *obj, void *prev)
|
|||
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)
|
||||
{
|
||||
if (parent->child_class_next)
|
||||
return parent->child_class_next(prev);
|
||||
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)
|
||||
{
|
||||
|
@ -1948,9 +2021,23 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o)
|
|||
av_free(tmp.data);
|
||||
return ret;
|
||||
}
|
||||
case AV_OPT_TYPE_DICT:
|
||||
/* Binary and dict have not default support yet. Any pointer is not default. */
|
||||
return !!(*(void **)dst);
|
||||
case AV_OPT_TYPE_DICT: {
|
||||
AVDictionary *dict1 = NULL;
|
||||
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:
|
||||
if (!o->default_val.str || !strcmp(o->default_val.str, "none"))
|
||||
w = h = 0;
|
||||
|
@ -2034,6 +2121,8 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
|
|||
av_freep(&buf);
|
||||
}
|
||||
}
|
||||
av_bprint_finalize(&bprint, buffer);
|
||||
ret = av_bprint_finalize(&bprint, buffer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
* libavcodec exports generic options, while its priv_data field exports
|
||||
* 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
|
||||
* 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.
|
||||
* Assuming that the test_struct from above now also contains a
|
||||
* child_struct field:
|
||||
|
@ -143,23 +143,25 @@
|
|||
* return t->child_struct;
|
||||
* 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
|
||||
* 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_struct (again, proper setup as described above needs to be done on
|
||||
* child_struct right after it is created).
|
||||
*
|
||||
* 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()
|
||||
* iterates over actually existing objects, while child_class_next()
|
||||
* and child_class_iterate() are needed. The distinction is that child_next()
|
||||
* iterates over actually existing objects, while child_class_iterate()
|
||||
* iterates over all possible child classes. E.g. if an AVCodecContext
|
||||
* was initialized to use a codec which has private options, then its
|
||||
* 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.
|
||||
*
|
||||
* @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
|
||||
* get all options that may potentially exist on the struct and its children
|
||||
* (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
|
||||
* 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
|
||||
|
@ -288,8 +290,10 @@ typedef struct AVOption {
|
|||
*/
|
||||
#define AV_OPT_FLAG_READONLY 128
|
||||
#define AV_OPT_FLAG_BSF_PARAM (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering
|
||||
#define AV_OPT_FLAG_RUNTIME_PARAM (1<<15) ///< a generic parameter which can be set by the user at runtime
|
||||
#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
|
||||
#define AV_OPT_FLAG_DEPRECATED (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information
|
||||
#define AV_OPT_FLAG_CHILD_CONSTS (1<<18) ///< set if option constants can also reside in child objects
|
||||
//FIXME think about enc-audio, ... style flags
|
||||
|
||||
/**
|
||||
|
@ -644,13 +648,26 @@ const AVOption *av_opt_next(const void *obj, const AVOption *prev);
|
|||
*/
|
||||
void *av_opt_child_next(void *obj, void *prev);
|
||||
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
/**
|
||||
* Iterate over potential AVOptions-enabled children of parent.
|
||||
*
|
||||
* @param prev result of a previous call to this function 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);
|
||||
#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
|
||||
|
@ -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
|
||||
* with '+' causes it to be set without affecting the other flags;
|
||||
* 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
|
||||
* 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 if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the option has
|
||||
* AV_OPT_TYPE_STRING or AV_OPT_TYPE_BINARY and is set to NULL, *out_val will be set
|
||||
* to NULL instead of an allocated empty string.
|
||||
* @note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the
|
||||
* option is of type AV_OPT_TYPE_STRING, AV_OPT_TYPE_BINARY or AV_OPT_TYPE_DICT
|
||||
* 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_int (void *obj, const char *name, int search_flags, int64_t *out_val);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "common.h"
|
||||
#include "eval.h"
|
||||
#include "log.h"
|
||||
/* #include "random_seed.h" */
|
||||
//#include "random_seed.h"
|
||||
#include "time_internal.h"
|
||||
#include "parseutils.h"
|
||||
#include "fftime.h"
|
||||
|
@ -736,12 +736,14 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
|
|||
if (*q)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
if (INT64_MAX / suffix < t)
|
||||
if (INT64_MAX / suffix < t || t < INT64_MIN / suffix)
|
||||
return AVERROR(ERANGE);
|
||||
t *= suffix;
|
||||
if (INT64_MAX - microseconds < t)
|
||||
return AVERROR(ERANGE);
|
||||
t += microseconds;
|
||||
if (t == INT64_MIN && negative)
|
||||
return AVERROR(ERANGE);
|
||||
*timeval = negative ? -t : t;
|
||||
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 */
|
||||
},
|
||||
},
|
||||
[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] = {
|
||||
.name = "rgb24",
|
||||
.nb_components = 3,
|
||||
|
@ -229,6 +252,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
|
|||
},
|
||||
.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] = {
|
||||
.name = "yuv422p",
|
||||
.nb_components = 3,
|
||||
|
@ -2344,6 +2391,10 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
|
|||
},
|
||||
.flags = AV_PIX_FMT_FLAG_PLANAR,
|
||||
},
|
||||
[AV_PIX_FMT_VULKAN] = {
|
||||
.name = "vulkan",
|
||||
.flags = AV_PIX_FMT_FLAG_HWACCEL,
|
||||
},
|
||||
};
|
||||
#if FF_API_PLUS1_MINUS1
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
|
@ -2369,7 +2420,7 @@ static const char * const color_primaries_names[AVCOL_PRI_NB] = {
|
|||
[AVCOL_PRI_SMPTE428] = "smpte428",
|
||||
[AVCOL_PRI_SMPTE431] = "smpte431",
|
||||
[AVCOL_PRI_SMPTE432] = "smpte432",
|
||||
[AVCOL_PRI_JEDEC_P22] = "jedec-p22",
|
||||
[AVCOL_PRI_EBU3213] = "ebu3213",
|
||||
};
|
||||
|
||||
static const char * const color_transfer_names[] = {
|
||||
|
@ -2608,7 +2659,7 @@ void ff_check_pixfmt_descriptors(void){
|
|||
continue;
|
||||
av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 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);
|
||||
}
|
||||
}
|
||||
|
@ -2651,11 +2702,13 @@ static int get_color_type(const AVPixFmtDescriptor *desc) {
|
|||
if(desc->nb_components == 1 || desc->nb_components == 2)
|
||||
return FF_COLOR_GRAY;
|
||||
|
||||
if(desc->name && !strncmp(desc->name, "yuvj", 4))
|
||||
return FF_COLOR_YUV_JPEG;
|
||||
if (desc->name) {
|
||||
if (av_strstart(desc->name, "yuvj", NULL))
|
||||
return FF_COLOR_YUV_JPEG;
|
||||
|
||||
if(desc->name && !strncmp(desc->name, "xyz", 3))
|
||||
return FF_COLOR_XYZ;
|
||||
if (av_strstart(desc->name, "xyz", NULL))
|
||||
return FF_COLOR_XYZ;
|
||||
}
|
||||
|
||||
if(desc->flags & AV_PIX_FMT_FLAG_RGB)
|
||||
return FF_COLOR_RGB;
|
||||
|
@ -2856,8 +2909,7 @@ int av_color_range_from_name(const char *name)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(color_range_names); i++) {
|
||||
size_t len = strlen(color_range_names[i]);
|
||||
if (!strncmp(color_range_names[i], name, len))
|
||||
if (av_strstart(name, color_range_names[i], NULL))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -2875,13 +2927,10 @@ int av_color_primaries_from_name(const char *name)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(color_primaries_names); i++) {
|
||||
size_t len;
|
||||
|
||||
if (!color_primaries_names[i])
|
||||
continue;
|
||||
|
||||
len = strlen(color_primaries_names[i]);
|
||||
if (!strncmp(color_primaries_names[i], name, len))
|
||||
if (av_strstart(name, color_primaries_names[i], NULL))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -2899,13 +2948,10 @@ int av_color_transfer_from_name(const char *name)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(color_transfer_names); i++) {
|
||||
size_t len;
|
||||
|
||||
if (!color_transfer_names[i])
|
||||
continue;
|
||||
|
||||
len = strlen(color_transfer_names[i]);
|
||||
if (!strncmp(color_transfer_names[i], name, len))
|
||||
if (av_strstart(name, color_transfer_names[i], NULL))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -2923,13 +2969,10 @@ int av_color_space_from_name(const char *name)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(color_space_names); i++) {
|
||||
size_t len;
|
||||
|
||||
if (!color_space_names[i])
|
||||
continue;
|
||||
|
||||
len = strlen(color_space_names[i]);
|
||||
if (!strncmp(color_space_names[i], name, len))
|
||||
if (av_strstart(name, color_space_names[i], NULL))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -2947,13 +2990,10 @@ int av_chroma_location_from_name(const char *name)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(chroma_location_names); i++) {
|
||||
size_t len;
|
||||
|
||||
if (!chroma_location_names[i])
|
||||
continue;
|
||||
|
||||
len = strlen(chroma_location_names[i]);
|
||||
if (!strncmp(chroma_location_names[i], name, len))
|
||||
if (av_strstart(name, chroma_location_names[i], NULL))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,7 @@ typedef struct AVPixFmtDescriptor {
|
|||
*/
|
||||
#define AV_PIX_FMT_FLAG_RGB (1 << 5)
|
||||
|
||||
#if FF_API_PSEUDOPAL
|
||||
/**
|
||||
* 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
|
||||
|
@ -164,6 +165,7 @@ typedef struct AVPixFmtDescriptor {
|
|||
* before the deprecation, though).
|
||||
*/
|
||||
#define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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_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_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_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_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_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_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian */
|
||||
AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian */
|
||||
AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian */
|
||||
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_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_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_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_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_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_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_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
|
||||
};
|
||||
|
||||
|
@ -436,6 +448,9 @@ enum AVPixelFormat {
|
|||
#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_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE)
|
||||
#define AV_PIX_FMT_X2RGB10 AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE)
|
||||
|
||||
/**
|
||||
* Chromaticity coordinates of the source primaries.
|
||||
* 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_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI 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
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
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
|
||||
};
|
||||
|
||||
|
|
|
@ -182,3 +182,12 @@ uint32_t av_q2intfloat(AVRational q) {
|
|||
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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"
|
||||
|
||||
#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 { \
|
||||
int ret = func(__VA_ARGS__); \
|
||||
if (ret) { \
|
||||
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(); \
|
||||
} \
|
||||
if (ret) \
|
||||
ASSERT_PTHREAD_ABORT(func, ret); \
|
||||
} while (0)
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
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_broadcast strict_pthread_cond_broadcast
|
||||
#define pthread_cond_wait strict_pthread_cond_wait
|
||||
#define pthread_cond_timedwait strict_pthread_cond_timedwait
|
||||
#define pthread_once strict_pthread_once
|
||||
#endif
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "fftime.h"
|
||||
#include "time.h"
|
||||
#include "error.h"
|
||||
|
||||
int64_t av_gettime(void)
|
||||
|
@ -57,7 +57,7 @@ int64_t av_gettime_relative(void)
|
|||
{
|
||||
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
|
||||
#ifdef __APPLE__
|
||||
if (clock_gettime)
|
||||
if (&clock_gettime)
|
||||
#endif
|
||||
{
|
||||
struct timespec ts;
|
||||
|
@ -72,7 +72,7 @@ int av_gettime_relative_is_monotonic(void)
|
|||
{
|
||||
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
|
||||
#ifdef __APPLE__
|
||||
if (!clock_gettime)
|
||||
if (!&clock_gettime)
|
||||
return 0;
|
||||
#endif
|
||||
return 1;
|
||||
|
|
|
@ -33,23 +33,20 @@
|
|||
|
||||
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 d, m, frames_per_10mins;
|
||||
|
||||
if (fps == 30) {
|
||||
drop_frames = 2;
|
||||
frames_per_10mins = 17982;
|
||||
} else if (fps == 60) {
|
||||
drop_frames = 4;
|
||||
frames_per_10mins = 35964;
|
||||
if (fps && fps % 30 == 0) {
|
||||
drop_frames = fps / 30 * 2;
|
||||
frames_per_10mins = fps / 30 * 17982;
|
||||
} else
|
||||
return framenum;
|
||||
|
||||
d = 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)
|
||||
|
@ -65,20 +62,41 @@ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum)
|
|||
ss = framenum / fps % 60;
|
||||
mm = framenum / (fps*60) % 60;
|
||||
hh = framenum / (fps*3600) % 24;
|
||||
return 0 << 31 | // color frame flag (0: unsync mode, 1: sync mode)
|
||||
drop << 30 | // drop frame flag (0: non drop, 1: drop)
|
||||
(ff / 10) << 28 | // tens of frames
|
||||
(ff % 10) << 24 | // units of frames
|
||||
0 << 23 | // PC (NTSC) or BGF0 (PAL)
|
||||
(ss / 10) << 20 | // tens of seconds
|
||||
(ss % 10) << 16 | // units of seconds
|
||||
0 << 15 | // BGF0 (NTSC) or BGF2 (PAL)
|
||||
(mm / 10) << 12 | // tens of minutes
|
||||
(mm % 10) << 8 | // units of minutes
|
||||
0 << 7 | // BGF2 (NTSC) or PC (PAL)
|
||||
0 << 6 | // BGF1
|
||||
(hh / 10) << 4 | // tens of hours
|
||||
(hh % 10); // units of hours
|
||||
return av_timecode_get_smpte(tc->rate, drop, hh, mm, ss, ff);
|
||||
}
|
||||
|
||||
uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff)
|
||||
{
|
||||
uint32_t tc = 0;
|
||||
|
||||
/* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS.
|
||||
See SMPTE ST 12-1:2014 Sec 12.1 for more info. */
|
||||
if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) {
|
||||
if (ff % 2 == 1) {
|
||||
if (av_cmp_q(rate, (AVRational) {50, 1}) == 0)
|
||||
tc |= (1 << 7);
|
||||
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)
|
||||
|
@ -96,8 +114,8 @@ char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
|
|||
}
|
||||
ff = framenum % fps;
|
||||
ss = framenum / fps % 60;
|
||||
mm = framenum / (fps*60) % 60;
|
||||
hh = framenum / (fps*3600);
|
||||
mm = framenum / (fps*60LL) % 60;
|
||||
hh = framenum / (fps*3600LL);
|
||||
if (tc->flags & AV_TIMECODE_FLAG_24HOURSMAX)
|
||||
hh = hh % 24;
|
||||
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;
|
||||
}
|
||||
|
||||
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 mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes
|
||||
unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds
|
||||
unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames
|
||||
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",
|
||||
hh, mm, ss, drop ? ';' : ':', ff);
|
||||
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)
|
||||
|
@ -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");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps != 30 && tc->fps != 60) {
|
||||
av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 or 60000/1001 FPS\n");
|
||||
if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps % 30 != 0) {
|
||||
av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with multiples of 30000/1001 FPS\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
int ret;
|
||||
|
||||
memset(tc, 0, sizeof(*tc));
|
||||
tc->flags = c != ':' ? AV_TIMECODE_FLAG_DROPFRAME : 0; // drop if ';', '.', ...
|
||||
tc->flags = flags;
|
||||
tc->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;
|
||||
if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* @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
|
||||
* @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);
|
||||
|
||||
|
@ -62,14 +62,39 @@ int av_timecode_adjust_ntsc_framenum2(int framenum, int fps);
|
|||
* @param framenum frame number
|
||||
* @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,
|
||||
* you do NOT have to call av_timecode_adjust_ntsc_framenum2().
|
||||
* @note The frame number is relative to tc->start.
|
||||
* @note Color frame (CF), binary group flags (BGF) and biphase mark polarity
|
||||
* correction (PC) bits are set to zero.
|
||||
* @note Color frame (CF) and binary group flags (BGF) bits are set to zero.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \
|
||||
int i; \
|
||||
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); \
|
||||
for (i = 0; i < 32; 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)
|
||||
{
|
||||
#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)
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
*/
|
||||
|
||||
#define LIBAVUTIL_VERSION_MAJOR 56
|
||||
#define LIBAVUTIL_VERSION_MINOR 31
|
||||
#define LIBAVUTIL_VERSION_MINOR 70
|
||||
#define LIBAVUTIL_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
|
||||
|
@ -129,7 +129,18 @@
|
|||
#ifndef FF_API_PSEUDOPAL
|
||||
#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57)
|
||||
#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>
|
||||
#if defined(_MSC_VER)
|
||||
#include <stdlib.h>
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#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
|
||||
%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 ;=================================================
|
||||
|
||||
DECLARE_REG 0, rcx
|
||||
|
@ -439,7 +429,7 @@ DECLARE_REG 12, R15, 104
|
|||
DECLARE_REG 13, R12, 112
|
||||
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 regs_used %2
|
||||
ASSERT regs_used >= num_args
|
||||
|
@ -451,7 +441,15 @@ DECLARE_REG 14, R13, 120
|
|||
WIN64_SPILL_XMM %3
|
||||
%endif
|
||||
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
|
||||
|
||||
%macro WIN64_PUSH_XMM 0
|
||||
|
@ -547,7 +545,7 @@ DECLARE_REG 12, R15, 56
|
|||
DECLARE_REG 13, R12, 64
|
||||
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 regs_used %2
|
||||
%assign xmm_regs_used %3
|
||||
|
@ -557,7 +555,15 @@ DECLARE_REG 14, R13, 72
|
|||
PUSH_IF_USED 9, 10, 11, 12, 13, 14
|
||||
ALLOC_STACK %4
|
||||
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
|
||||
|
||||
%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
|
||||
|
||||
%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 regs_used %2
|
||||
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
|
||||
ALLOC_STACK %4
|
||||
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
|
||||
|
||||
%define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required
|
||||
|
|
Загрузка…
Ссылка в новой задаче