Bug 1831931 - Update libdav1d to 8b419c16bf1e37bc98044089da58f06824462cb9 r=media-playback-reviewers,padenot

Update to 8b419c16bf1e37bc98044089da58f06824462cb9 by running `./mach
vendor media/libdav1d/moz.yaml`

Differential Revision: https://phabricator.services.mozilla.com/D180024
This commit is contained in:
Chun-Min Chang 2023-06-08 19:53:09 +00:00
Родитель b24fc21cd7
Коммит 283fc7df62
43 изменённых файлов: 7619 добавлений и 624 удалений

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

@ -20,11 +20,11 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: 5aa3b38f9871859e14e55f18ab5e38318fe86305 (2023-04-08T11:47:31.000+00:00).
release: 8b419c16bf1e37bc98044089da58f06824462cb9 (2023-06-02T00:00:12.000+02:00).
# Revision to pull in
# Must be a long or short commit SHA (long preferred)
revision: 5aa3b38f9871859e14e55f18ab5e38318fe86305
revision: 8b419c16bf1e37bc98044089da58f06824462cb9
# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/

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

@ -1,2 +1,2 @@
/* auto-generated, do not edit */
#define DAV1D_VERSION "5aa3b38f9871859e14e55f18ab5e38318fe86305"
#define DAV1D_VERSION "8b419c16bf1e37bc98044089da58f06824462cb9"

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

@ -28,7 +28,7 @@
#define DAV1D_VERSION_H
#define DAV1D_API_VERSION_MAJOR 6
#define DAV1D_API_VERSION_MINOR 8
#define DAV1D_API_VERSION_MINOR 9
#define DAV1D_API_VERSION_PATCH 0
#endif /* DAV1D_VERSION_H */

29
third_party/dav1d/NEWS поставляемый
Просмотреть файл

@ -1,3 +1,32 @@
Changes for 1.2.1 'Arctic Peregrine Falcon':
-------------------------------------------
1.2.1 is a small release of dav1d, adding more SIMD and fixes
- Fix a threading race on task_thread.init_done
- NEON z2 8bpc and high bit-depth optimizations
- SSSE3 z2 high bit-depth optimziations
- Fix a desynced luma/chroma planes issue with Film Grain
- Reduce memory consumption
- Improve dav1d_parse_sequence_header() speed
- OBU: Improve header parsing and fix potential overflows
- OBU: Improve ITU-T T.35 parsing speed
- Misc buildsystems, CI and headers fixes
Changes for 1.2.0 'Arctic Peregrine Falcon':
-------------------------------------------
1.2.0 is a small release of dav1d, adding more SIMD and fixes
- Improvements on attachments of props and T.35 entries on output pictures
- NEON z1/z3 high bit-depth optimizations and improvements for 8bpc
- SSSE3 z2/z3 8bpc and SSSE3 z1/z3 high bit-depth optimziations
- refmvs.save_tmvs optimizations in SSSE3/AVX2/AVX-512
- AVX-512 optimizations for high bit-depth itx (16x64, 32x64, 64x16, 64x32, 64x64)
- AVX2 optimizations for 12bpc for 16x32, 32x16, 32x32 itx
Changes for 1.1.0 'Arctic Peregrine Falcon':
-------------------------------------------

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

@ -43,7 +43,11 @@
#ifdef __GNUC__
#define ATTR_ALIAS __attribute__((may_alias))
#if defined(__MINGW32__) && !defined(__clang__)
#define ATTR_FORMAT_PRINTF(fmt, attr) __attribute__((__format__(__gnu_printf__, fmt, attr)))
#else
#define ATTR_FORMAT_PRINTF(fmt, attr) __attribute__((__format__(__printf__, fmt, attr)))
#endif
#define COLD __attribute__((cold))
#else
#define ATTR_ALIAS

8
third_party/dav1d/include/dav1d/common.h поставляемый
Просмотреть файл

@ -32,6 +32,10 @@
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DAV1D_API
#if defined _WIN32
#if defined DAV1D_BUILDING_DLL
@ -83,4 +87,8 @@ typedef struct Dav1dDataProps {
*/
DAV1D_API void dav1d_data_props_unref(Dav1dDataProps *props);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* DAV1D_COMMON_H */

8
third_party/dav1d/include/dav1d/data.h поставляемый
Просмотреть файл

@ -33,6 +33,10 @@
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Dav1dData {
const uint8_t *data; ///< data pointer
size_t sz; ///< data size
@ -106,4 +110,8 @@ DAV1D_API int dav1d_data_wrap_user_data(Dav1dData *data,
*/
DAV1D_API void dav1d_data_unref(Dav1dData *data);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* DAV1D_DATA_H */

14
third_party/dav1d/include/dav1d/dav1d.h поставляемый
Просмотреть файл

@ -28,10 +28,6 @@
#ifndef DAV1D_H
#define DAV1D_H
#ifdef __cplusplus
extern "C" {
#endif
#include <errno.h>
#include <stdarg.h>
@ -40,6 +36,10 @@ extern "C" {
#include "data.h"
#include "version.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Dav1dContext Dav1dContext;
typedef struct Dav1dRef Dav1dRef;
@ -313,8 +313,8 @@ DAV1D_API int dav1d_get_decode_error_data_props(Dav1dContext *c, Dav1dDataProps
*/
DAV1D_API int dav1d_get_frame_delay(const Dav1dSettings *s);
# ifdef __cplusplus
}
# endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* DAV1D_H */

8
third_party/dav1d/include/dav1d/headers.h поставляемый
Просмотреть файл

@ -31,6 +31,10 @@
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
// Constants from Section 3. "Symbols and abbreviated terms"
#define DAV1D_MAX_CDEF_STRENGTHS 8
#define DAV1D_MAX_OPERATING_POINTS 32
@ -432,4 +436,8 @@ typedef struct Dav1dFrameHeader {
Dav1dWarpedMotionParams gmv[DAV1D_REFS_PER_FRAME];
} Dav1dFrameHeader;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* DAV1D_HEADERS_H */

17
third_party/dav1d/include/dav1d/picture.h поставляемый
Просмотреть файл

@ -34,6 +34,10 @@
#include "common.h"
#include "headers.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Number of bytes to align AND pad picture memory buffers by, so that SIMD
* implementations can over-read by a few bytes, and use aligned read/write
* instructions. */
@ -78,11 +82,16 @@ typedef struct Dav1dPicture {
*/
Dav1dMasteringDisplay *mastering_display;
/**
* ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
* Array of ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
*/
Dav1dITUTT35 *itut_t35;
uintptr_t reserved[4]; ///< reserved for future use
/**
* Number of ITU-T T35 metadata entries in the array
*/
size_t n_itut_t35;
uintptr_t reserved[3]; ///< reserved for future use
struct Dav1dRef *frame_hdr_ref; ///< Dav1dFrameHeader allocation origin
struct Dav1dRef *seq_hdr_ref; ///< Dav1dSequenceHeader allocation origin
@ -141,4 +150,8 @@ typedef struct Dav1dPicAllocator {
*/
DAV1D_API void dav1d_picture_unref(Dav1dPicture *p);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* DAV1D_PICTURE_H */

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

@ -27,8 +27,16 @@
#ifndef DAV1D_VERSION_H
#define DAV1D_VERSION_H
#ifdef __cplusplus
extern "C" {
#endif
#define DAV1D_API_VERSION_MAJOR @DAV1D_API_VERSION_MAJOR@
#define DAV1D_API_VERSION_MINOR @DAV1D_API_VERSION_MINOR@
#define DAV1D_API_VERSION_PATCH @DAV1D_API_VERSION_PATCH@
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* DAV1D_VERSION_H */

4
third_party/dav1d/meson.build поставляемый
Просмотреть файл

@ -23,14 +23,14 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
project('dav1d', ['c'],
version: '1.1.0',
version: '1.2.1',
default_options: ['c_std=c99',
'warning_level=2',
'buildtype=release',
'b_ndebug=if-release'],
meson_version: '>= 0.49.0')
dav1d_soname_version = '6.8.0'
dav1d_soname_version = '6.9.0'
dav1d_api_version_array = dav1d_soname_version.split('.')
dav1d_api_version_major = dav1d_api_version_array[0]
dav1d_api_version_minor = dav1d_api_version_array[1]

1260
third_party/dav1d/src/arm/64/ipred.S поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1435
third_party/dav1d/src/arm/64/ipred16.S поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

110
third_party/dav1d/src/arm/ipred.h поставляемый
Просмотреть файл

@ -115,6 +115,112 @@ static void ipred_z1_neon(pixel *dst, const ptrdiff_t stride,
dx, max_base_x);
}
void BF(dav1d_ipred_reverse, neon)(pixel *dst, const pixel *const src,
const int n);
void BF(dav1d_ipred_z2_upsample_edge, neon)(pixel *out, const int sz,
const pixel *const in
HIGHBD_DECL_SUFFIX);
void BF(dav1d_ipred_z2_fill1, neon)(pixel *dst, ptrdiff_t stride,
const pixel *const top,
const pixel *const left,
const int width, const int height,
const int dx, const int dy);
void BF(dav1d_ipred_z2_fill2, neon)(pixel *dst, ptrdiff_t stride,
const pixel *const top,
const pixel *const left,
const int width, const int height,
const int dx, const int dy);
void BF(dav1d_ipred_z2_fill3, neon)(pixel *dst, ptrdiff_t stride,
const pixel *const top,
const pixel *const left,
const int width, const int height,
const int dx, const int dy);
static void ipred_z2_neon(pixel *dst, const ptrdiff_t stride,
const pixel *const topleft_in,
const int width, const int height, int angle,
const int max_width, const int max_height
HIGHBD_DECL_SUFFIX)
{
const int is_sm = (angle >> 9) & 0x1;
const int enable_intra_edge_filter = angle >> 10;
angle &= 511;
assert(angle > 90 && angle < 180);
int dy = dav1d_dr_intra_derivative[(angle - 90) >> 1];
int dx = dav1d_dr_intra_derivative[(180 - angle) >> 1];
const int upsample_left = enable_intra_edge_filter ?
get_upsample(width + height, 180 - angle, is_sm) : 0;
const int upsample_above = enable_intra_edge_filter ?
get_upsample(width + height, angle - 90, is_sm) : 0;
pixel buf[3*(64+1)];
pixel *left = &buf[2*(64+1)];
// The asm can underread below the start of top[] and left[]; to avoid
// surprising behaviour, make sure this is within the allocated stack space.
pixel *top = &buf[1*(64+1)];
pixel *flipped = &buf[0*(64+1)];
if (upsample_above) {
BF(dav1d_ipred_z2_upsample_edge, neon)(top, width, topleft_in
HIGHBD_TAIL_SUFFIX);
dx <<= 1;
} else {
const int filter_strength = enable_intra_edge_filter ?
get_filter_strength(width + height, angle - 90, is_sm) : 0;
if (filter_strength) {
BF(dav1d_ipred_z1_filter_edge, neon)(&top[1], imin(max_width, width),
topleft_in, width,
filter_strength);
if (max_width < width)
memcpy(&top[1 + max_width], &topleft_in[1 + max_width],
(width - max_width) * sizeof(pixel));
} else {
pixel_copy(&top[1], &topleft_in[1], width);
}
}
if (upsample_left) {
flipped[0] = topleft_in[0];
BF(dav1d_ipred_reverse, neon)(&flipped[1], &topleft_in[0],
height);
BF(dav1d_ipred_z2_upsample_edge, neon)(left, height, flipped
HIGHBD_TAIL_SUFFIX);
dy <<= 1;
} else {
const int filter_strength = enable_intra_edge_filter ?
get_filter_strength(width + height, 180 - angle, is_sm) : 0;
if (filter_strength) {
flipped[0] = topleft_in[0];
BF(dav1d_ipred_reverse, neon)(&flipped[1], &topleft_in[0],
height);
BF(dav1d_ipred_z1_filter_edge, neon)(&left[1], imin(max_height, height),
flipped, height,
filter_strength);
if (max_height < height)
memcpy(&left[1 + max_height], &flipped[1 + max_height],
(height - max_height) * sizeof(pixel));
} else {
BF(dav1d_ipred_reverse, neon)(&left[1], &topleft_in[0],
height);
}
}
top[0] = left[0] = *topleft_in;
assert(!(upsample_above && upsample_left));
if (!upsample_above && !upsample_left) {
BF(dav1d_ipred_z2_fill1, neon)(dst, stride, top, left, width, height,
dx, dy);
} else if (upsample_above) {
BF(dav1d_ipred_z2_fill2, neon)(dst, stride, top, left, width, height,
dx, dy);
} else /*if (upsample_left)*/ {
BF(dav1d_ipred_z2_fill3, neon)(dst, stride, top, left, width, height,
dx, dy);
}
}
void BF(dav1d_ipred_z3_fill1, neon)(pixel *dst, ptrdiff_t stride,
const pixel *const left, const int width,
const int height, const int dy,
@ -124,9 +230,6 @@ void BF(dav1d_ipred_z3_fill2, neon)(pixel *dst, ptrdiff_t stride,
const int height, const int dy,
const int max_base_y);
void BF(dav1d_ipred_reverse, neon)(pixel *dst, const pixel *const src,
const int n);
static void ipred_z3_neon(pixel *dst, const ptrdiff_t stride,
const pixel *const topleft_in,
const int width, const int height, int angle,
@ -205,6 +308,7 @@ static ALWAYS_INLINE void intra_pred_dsp_init_arm(Dav1dIntraPredDSPContext *cons
c->intra_pred[SMOOTH_H_PRED] = BF(dav1d_ipred_smooth_h, neon);
#if ARCH_AARCH64
c->intra_pred[Z1_PRED] = ipred_z1_neon;
c->intra_pred[Z2_PRED] = ipred_z2_neon;
c->intra_pred[Z3_PRED] = ipred_z3_neon;
#endif
c->intra_pred[FILTER_PRED] = BF(dav1d_ipred_filter, neon);

13
third_party/dav1d/src/data.c поставляемый
Просмотреть файл

@ -64,8 +64,11 @@ int dav1d_data_wrap_internal(Dav1dData *const buf, const uint8_t *const ptr,
validate_input_or_ret(ptr != NULL, DAV1D_ERR(EINVAL));
validate_input_or_ret(free_callback != NULL, DAV1D_ERR(EINVAL));
buf->ref = dav1d_ref_wrap(ptr, free_callback, cookie);
if (!buf->ref) return DAV1D_ERR(ENOMEM);
if (sz > SIZE_MAX / 2) return DAV1D_ERR(EINVAL);
Dav1dRef *const ref = malloc(sizeof(Dav1dRef));
if (!ref) return DAV1D_ERR(ENOMEM);
buf->ref = dav1d_ref_init(ref, ptr, free_callback, cookie, 1);
buf->data = ptr;
buf->sz = sz;
dav1d_data_props_set_defaults(&buf->m);
@ -83,8 +86,10 @@ int dav1d_data_wrap_user_data_internal(Dav1dData *const buf,
validate_input_or_ret(buf != NULL, DAV1D_ERR(EINVAL));
validate_input_or_ret(free_callback != NULL, DAV1D_ERR(EINVAL));
buf->m.user_data.ref = dav1d_ref_wrap(user_data, free_callback, cookie);
if (!buf->m.user_data.ref) return DAV1D_ERR(ENOMEM);
Dav1dRef *const ref = malloc(sizeof(Dav1dRef));
if (!ref) return DAV1D_ERR(ENOMEM);
buf->m.user_data.ref = dav1d_ref_init(ref, user_data, free_callback, cookie, 1);
buf->m.user_data.data = user_data;
return 0;

86
third_party/dav1d/src/decode.c поставляемый
Просмотреть файл

@ -2329,7 +2329,7 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl,
if (!have_h_split && !have_v_split) {
assert(bl < BL_8X8);
return decode_sb(t, bl + 1, ((const EdgeBranch *) node)->split[0]);
return decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0));
}
uint16_t *pc;
@ -2390,19 +2390,19 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl,
if (bl == BL_8X8) {
const EdgeTip *const tip = (const EdgeTip *) node;
assert(hsz == 1);
if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[0]))
if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, EDGE_ALL_TR_AND_BL))
return -1;
const enum Filter2d tl_filter = t->tl_4x4_filter;
t->bx++;
if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[1]))
if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[0]))
return -1;
t->bx--;
t->by++;
if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[2]))
if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[1]))
return -1;
t->bx++;
t->tl_4x4_filter = tl_filter;
if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[3]))
if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[2]))
return -1;
t->bx--;
t->by--;
@ -2417,74 +2417,69 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl,
}
#endif
} else {
const EdgeBranch *const branch = (const EdgeBranch *) node;
if (decode_sb(t, bl + 1, branch->split[0]))
if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0)))
return 1;
t->bx += hsz;
if (decode_sb(t, bl + 1, branch->split[1]))
if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 1)))
return 1;
t->bx -= hsz;
t->by += hsz;
if (decode_sb(t, bl + 1, branch->split[2]))
if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 2)))
return 1;
t->bx += hsz;
if (decode_sb(t, bl + 1, branch->split[3]))
if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 3)))
return 1;
t->bx -= hsz;
t->by -= hsz;
}
break;
case PARTITION_T_TOP_SPLIT: {
const EdgeBranch *const branch = (const EdgeBranch *) node;
if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, branch->tts[0]))
if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, EDGE_ALL_TR_AND_BL))
return -1;
t->bx += hsz;
if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, branch->tts[1]))
if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, node->v[1]))
return -1;
t->bx -= hsz;
t->by += hsz;
if (decode_b(t, bl, b[1], PARTITION_T_TOP_SPLIT, branch->tts[2]))
if (decode_b(t, bl, b[1], PARTITION_T_TOP_SPLIT, node->h[1]))
return -1;
t->by -= hsz;
break;
}
case PARTITION_T_BOTTOM_SPLIT: {
const EdgeBranch *const branch = (const EdgeBranch *) node;
if (decode_b(t, bl, b[0], PARTITION_T_BOTTOM_SPLIT, branch->tbs[0]))
if (decode_b(t, bl, b[0], PARTITION_T_BOTTOM_SPLIT, node->h[0]))
return -1;
t->by += hsz;
if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, branch->tbs[1]))
if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, node->v[0]))
return -1;
t->bx += hsz;
if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, branch->tbs[2]))
if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, 0))
return -1;
t->bx -= hsz;
t->by -= hsz;
break;
}
case PARTITION_T_LEFT_SPLIT: {
const EdgeBranch *const branch = (const EdgeBranch *) node;
if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, branch->tls[0]))
if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, EDGE_ALL_TR_AND_BL))
return -1;
t->by += hsz;
if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, branch->tls[1]))
if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, node->h[1]))
return -1;
t->by -= hsz;
t->bx += hsz;
if (decode_b(t, bl, b[1], PARTITION_T_LEFT_SPLIT, branch->tls[2]))
if (decode_b(t, bl, b[1], PARTITION_T_LEFT_SPLIT, node->v[1]))
return -1;
t->bx -= hsz;
break;
}
case PARTITION_T_RIGHT_SPLIT: {
const EdgeBranch *const branch = (const EdgeBranch *) node;
if (decode_b(t, bl, b[0], PARTITION_T_RIGHT_SPLIT, branch->trs[0]))
if (decode_b(t, bl, b[0], PARTITION_T_RIGHT_SPLIT, node->v[0]))
return -1;
t->bx += hsz;
if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, branch->trs[1]))
if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, node->h[0]))
return -1;
t->by += hsz;
if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, branch->trs[2]))
if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, 0))
return -1;
t->by -= hsz;
t->bx -= hsz;
@ -2492,34 +2487,34 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl,
}
case PARTITION_H4: {
const EdgeBranch *const branch = (const EdgeBranch *) node;
if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4[0]))
if (decode_b(t, bl, b[0], PARTITION_H4, node->h[0]))
return -1;
t->by += hsz >> 1;
if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4[1]))
if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4))
return -1;
t->by += hsz >> 1;
if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4[2]))
if (decode_b(t, bl, b[0], PARTITION_H4, EDGE_ALL_LEFT_HAS_BOTTOM))
return -1;
t->by += hsz >> 1;
if (t->by < f->bh)
if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4[3]))
if (decode_b(t, bl, b[0], PARTITION_H4, node->h[1]))
return -1;
t->by -= hsz * 3 >> 1;
break;
}
case PARTITION_V4: {
const EdgeBranch *const branch = (const EdgeBranch *) node;
if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4[0]))
if (decode_b(t, bl, b[0], PARTITION_V4, node->v[0]))
return -1;
t->bx += hsz >> 1;
if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4[1]))
if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4))
return -1;
t->bx += hsz >> 1;
if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4[2]))
if (decode_b(t, bl, b[0], PARTITION_V4, EDGE_ALL_TOP_HAS_RIGHT))
return -1;
t->bx += hsz >> 1;
if (t->bx < f->bw)
if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4[3]))
if (decode_b(t, bl, b[0], PARTITION_V4, node->v[1]))
return -1;
t->bx -= hsz * 3 >> 1;
break;
@ -2542,11 +2537,10 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl,
assert(bl < BL_8X8);
if (is_split) {
const EdgeBranch *const branch = (const EdgeBranch *) node;
bp = PARTITION_SPLIT;
if (decode_sb(t, bl + 1, branch->split[0])) return 1;
if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0))) return 1;
t->bx += hsz;
if (decode_sb(t, bl + 1, branch->split[1])) return 1;
if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 1))) return 1;
t->bx -= hsz;
} else {
bp = PARTITION_H;
@ -2573,11 +2567,10 @@ static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl,
assert(bl < BL_8X8);
if (is_split) {
const EdgeBranch *const branch = (const EdgeBranch *) node;
bp = PARTITION_SPLIT;
if (decode_sb(t, bl + 1, branch->split[0])) return 1;
if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0))) return 1;
t->by += hsz;
if (decode_sb(t, bl + 1, branch->split[2])) return 1;
if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 2))) return 1;
t->by -= hsz;
} else {
bp = PARTITION_V;
@ -2726,9 +2719,7 @@ static void read_restoration_info(Dav1dTaskContext *const t,
if (frame_type == DAV1D_RESTORATION_SWITCHABLE) {
const int filter = dav1d_msac_decode_symbol_adapt4(&ts->msac,
ts->cdf.m.restore_switchable, 2);
lr->type = filter ? filter == 2 ? DAV1D_RESTORATION_SGRPROJ :
DAV1D_RESTORATION_WIENER :
DAV1D_RESTORATION_NONE;
lr->type = filter + !!filter; /* NONE/WIENER/SGRPROJ */
} else {
const unsigned type =
dav1d_msac_decode_bool_adapt(&ts->msac,
@ -2767,7 +2758,7 @@ static void read_restoration_info(Dav1dTaskContext *const t,
} else if (lr->type == DAV1D_RESTORATION_SGRPROJ) {
const unsigned idx = dav1d_msac_decode_bools(&ts->msac, 4);
const uint16_t *const sgr_params = dav1d_sgr_params[idx];
lr->sgr_idx = idx;
lr->type += idx;
lr->sgr_weights[0] = sgr_params[0] ? dav1d_msac_decode_subexp(&ts->msac,
ts->lr_ref[p]->sgr_weights[0] + 96, 128, 4) - 96 : 0;
lr->sgr_weights[1] = sgr_params[1] ? dav1d_msac_decode_subexp(&ts->msac,
@ -2777,7 +2768,7 @@ static void read_restoration_info(Dav1dTaskContext *const t,
ts->lr_ref[p] = lr;
if (DEBUG_BLOCK_INFO)
printf("Post-lr_sgrproj[pl=%d,idx=%d,w[%d,%d]]: r=%d\n",
p, lr->sgr_idx, lr->sgr_weights[0],
p, idx, lr->sgr_weights[0],
lr->sgr_weights[1], ts->msac.rng);
}
}
@ -2816,7 +2807,7 @@ int dav1d_decode_tile_sbrow(Dav1dTaskContext *const t) {
{
if (atomic_load_explicit(c->flush, memory_order_acquire))
return 1;
if (decode_sb(t, root_bl, c->intra_edge.root[root_bl]))
if (decode_sb(t, root_bl, dav1d_intra_edge_tree[root_bl]))
return 1;
if (t->bx & 16 || f->seq_hdr->sb128)
t->a++;
@ -2905,7 +2896,7 @@ int dav1d_decode_tile_sbrow(Dav1dTaskContext *const t) {
read_restoration_info(t, lr, p, frame_type);
}
}
if (decode_sb(t, root_bl, c->intra_edge.root[root_bl]))
if (decode_sb(t, root_bl, dav1d_intra_edge_tree[root_bl]))
return 1;
if (t->bx & 16 || f->seq_hdr->sb128) {
t->a++;
@ -3303,7 +3294,6 @@ int dav1d_decode_frame_init(Dav1dFrameContext *const f) {
* dereference those pointers so it doesn't really matter what they
* point at, as long as the pointers are valid. */
const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400;
f->lf.mask_ptr = f->lf.mask;
f->lf.p[0] = f->cur.data[0];
f->lf.p[1] = f->cur.data[has_chroma ? 1 : 0];
f->lf.p[2] = f->cur.data[has_chroma ? 2 : 0];

44
third_party/dav1d/src/fg_apply_tmpl.c поставляемый
Просмотреть файл

@ -37,7 +37,6 @@
#include "common/bitdepth.h"
#include "src/fg_apply.h"
#include "src/ref.h"
static void generate_scaling(const int bitdepth,
const uint8_t points[][2], const int num,
@ -126,32 +125,35 @@ void bitfn(dav1d_prep_grain)(const Dav1dFilmGrainDSPContext *const dsp,
if (data->num_uv_points[1])
generate_scaling(in->p.bpc, data->uv_points[1], data->num_uv_points[1], scaling[2]);
// Create new references for the non-modified planes
// Copy over the non-modified planes
assert(out->stride[0] == in->stride[0]);
if (!data->num_y_points) {
struct Dav1dRef **out_plane_ref = out->ref->user_data;
struct Dav1dRef **in_plane_ref = in->ref->user_data;
dav1d_ref_dec(&out_plane_ref[0]);
out_plane_ref[0] = in_plane_ref[0];
dav1d_ref_inc(out_plane_ref[0]);
out->data[0] = in->data[0];
const ptrdiff_t stride = out->stride[0];
const ptrdiff_t sz = out->p.h * stride;
if (sz < 0)
memcpy((uint8_t*) out->data[0] + sz - stride,
(uint8_t*) in->data[0] + sz - stride, -sz);
else
memcpy(out->data[0], in->data[0], sz);
}
if (in->p.layout != DAV1D_PIXEL_LAYOUT_I400 && !data->chroma_scaling_from_luma) {
assert(out->stride[1] == in->stride[1]);
struct Dav1dRef **out_plane_ref = out->ref->user_data;
struct Dav1dRef **in_plane_ref = in->ref->user_data;
if (!data->num_uv_points[0]) {
dav1d_ref_dec(&out_plane_ref[1]);
out_plane_ref[1] = in_plane_ref[1];
dav1d_ref_inc(out_plane_ref[1]);
out->data[1] = in->data[1];
}
if (!data->num_uv_points[1]) {
dav1d_ref_dec(&out_plane_ref[2]);
out_plane_ref[2] = in_plane_ref[2];
dav1d_ref_inc(out_plane_ref[2]);
out->data[2] = in->data[2];
const int ss_ver = in->p.layout == DAV1D_PIXEL_LAYOUT_I420;
const ptrdiff_t stride = out->stride[1];
const ptrdiff_t sz = ((out->p.h + ss_ver) >> ss_ver) * stride;
if (sz < 0) {
if (!data->num_uv_points[0])
memcpy((uint8_t*) out->data[1] + sz - stride,
(uint8_t*) in->data[1] + sz - stride, -sz);
if (!data->num_uv_points[1])
memcpy((uint8_t*) out->data[2] + sz - stride,
(uint8_t*) in->data[2] + sz - stride, -sz);
} else {
if (!data->num_uv_points[0])
memcpy(out->data[1], in->data[1], sz);
if (!data->num_uv_points[1])
memcpy(out->data[2], in->data[2], sz);
}
}
}

14
third_party/dav1d/src/getbits.c поставляемый
Просмотреть файл

@ -162,17 +162,3 @@ static unsigned get_bits_subexp_u(GetBits *const c, const unsigned ref,
int dav1d_get_bits_subexp(GetBits *const c, const int ref, const unsigned n) {
return (int) get_bits_subexp_u(c, ref + (1 << n), 2 << n) - (1 << n);
}
void dav1d_bytealign_get_bits(GetBits *c) {
// bits_left is never more than 7, because it is only incremented
// by refill(), called by dav1d_get_bits and that never reads more
// than 7 bits more than it needs.
//
// If this wasn't true, we would need to work out how many bits to
// discard (bits_left % 8), subtract that from bits_left and then
// shift state right by that amount.
assert(c->bits_left <= 7);
c->bits_left = 0;
c->state = 0;
}

14
third_party/dav1d/src/getbits.h поставляемый
Просмотреть файл

@ -49,7 +49,19 @@ unsigned dav1d_get_vlc(GetBits *c);
int dav1d_get_bits_subexp(GetBits *c, int ref, unsigned n);
// Discard bits from the buffer until we're next byte-aligned.
void dav1d_bytealign_get_bits(GetBits *c);
static inline void dav1d_bytealign_get_bits(GetBits *c) {
// bits_left is never more than 7, because it is only incremented
// by refill(), called by dav1d_get_bits and that never reads more
// than 7 bits more than it needs.
//
// If this wasn't true, we would need to work out how many bits to
// discard (bits_left % 8), subtract that from bits_left and then
// shift state right by that amount.
assert(c->bits_left <= 7);
c->bits_left = 0;
c->state = 0;
}
// Return the current bit position relative to the start of the buffer.
static inline unsigned dav1d_get_bits_pos(const GetBits *c) {

23
third_party/dav1d/src/internal.h поставляемый
Просмотреть файл

@ -115,6 +115,7 @@ struct Dav1dContext {
Dav1dMasteringDisplay *mastering_display;
Dav1dRef *itut_t35_ref;
Dav1dITUTT35 *itut_t35;
int n_itut_t35;
// decoded output picture queue
Dav1dData in;
@ -175,15 +176,6 @@ struct Dav1dContext {
Dav1dDSPContext dsp[3 /* 8, 10, 12 bits/component */];
Dav1dRefmvsDSPContext refmvs_dsp;
// tree to keep track of which edges are available
struct {
EdgeNode *root[2 /* BL_128X128 vs. BL_64X64 */];
EdgeBranch branch_sb128[1 + 4 + 16 + 64];
EdgeBranch branch_sb64[1 + 4 + 16];
EdgeTip tip_sb128[256];
EdgeTip tip_sb64[64];
} intra_edge;
Dav1dPicAllocator allocator;
int apply_grain;
int operating_point;
@ -204,6 +196,7 @@ struct Dav1dContext {
Dav1dLogger logger;
Dav1dMemPool *picture_pool;
Dav1dMemPool *pic_ctx_pool;
};
struct Dav1dTask {
@ -281,10 +274,7 @@ struct Dav1dFrameContext {
atomic_uint *frame_progress, *copy_lpf_progress;
// indexed using t->by * f->b4_stride + t->bx
Av1Block *b;
struct CodedBlockInfo {
int16_t eob[3 /* plane */];
uint8_t txtp[3 /* plane */];
} *cbi;
int16_t (*cbi)[3 /* plane */]; /* bits 0-4: txtp, bits 5-15: eob */
// indexed using (t->by >> 1) * (f->b4_stride >> 1) + (t->bx >> 1)
uint16_t (*pal)[3 /* plane */][8 /* idx */];
// iterated over inside tile state
@ -320,7 +310,6 @@ struct Dav1dFrameContext {
int start_of_tile_row_sz;
int need_cdef_lpf_copy;
pixel *p[3], *sr_p[3];
Av1Filter *mask_ptr, *prev_mask_ptr;
int restore_planes; // enum LrRestorePlanes
} lf;
@ -402,7 +391,6 @@ struct Dav1dTaskContext {
// which would make copy/assign operations slightly faster?
uint16_t al_pal[2 /* a/l */][32 /* bx/y4 */][3 /* plane */][8 /* palette_idx */];
uint8_t pal_sz_uv[2 /* a/l */][32 /* bx4/by4 */];
uint8_t txtp_map[32 * 32]; // inter-only
ALIGN(union, 64) {
struct {
union {
@ -427,7 +415,10 @@ struct Dav1dTaskContext {
uint8_t pal_ctx[64];
};
};
int16_t ac[32 * 32];
union {
int16_t ac[32 * 32]; // intra-only
uint8_t txtp_map[32 * 32]; // inter-only
};
uint8_t pal_idx[2 * 64 * 64];
uint16_t pal[3 /* plane */][8 /* palette_idx */];
ALIGN(union, 64) {

151
third_party/dav1d/src/intra_edge.c поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
/*
* Copyright © 2018, VideoLAN and dav1d authors
* Copyright © 2018, Two Orioles, LLC
* Copyright © 2018-2023, VideoLAN and dav1d authors
* Copyright © 2018-2023, Two Orioles, LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -39,97 +39,83 @@ struct ModeSelMem {
EdgeTip *nt;
};
static void init_edges(EdgeNode *const node,
const enum BlockLevel bl,
const enum EdgeFlags edge_flags)
/* Because we're using 16-bit offsets to refer to other nodes those arrays
* are placed in a struct to ensure they're consecutive in memory. */
static struct {
EdgeBranch branch_sb128[1 + 4 + 16 + 64];
EdgeTip tip_sb128[256];
EdgeBranch branch_sb64[1 + 4 + 16];
EdgeTip tip_sb64[64];
} ALIGN(nodes, 16);
const EdgeNode *dav1d_intra_edge_tree[2] = {
(EdgeNode*)nodes.branch_sb128, (EdgeNode*)nodes.branch_sb64
};
static COLD void init_edges(EdgeNode *const node,
const enum BlockLevel bl,
const enum EdgeFlags edge_flags)
{
node->o = edge_flags;
node->h[0] = edge_flags | EDGE_ALL_LEFT_HAS_BOTTOM;
node->v[0] = edge_flags | EDGE_ALL_TOP_HAS_RIGHT;
#define ALL_FL(t) (EDGE_I444_##t | EDGE_I422_##t | EDGE_I420_##t)
if (bl == BL_8X8) {
EdgeTip *const nt = (EdgeTip *) node;
node->h[0] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM);
node->h[1] = edge_flags & (ALL_FL(LEFT_HAS_BOTTOM) |
node->h[1] = edge_flags & (EDGE_ALL_LEFT_HAS_BOTTOM |
EDGE_I420_TOP_HAS_RIGHT);
node->v[0] = edge_flags | ALL_FL(TOP_HAS_RIGHT);
node->v[1] = edge_flags & (ALL_FL(TOP_HAS_RIGHT) |
node->v[1] = edge_flags & (EDGE_ALL_TOP_HAS_RIGHT |
EDGE_I420_LEFT_HAS_BOTTOM |
EDGE_I422_LEFT_HAS_BOTTOM);
nt->split[0] = ALL_FL(TOP_HAS_RIGHT) | ALL_FL(LEFT_HAS_BOTTOM);
nt->split[1] = (edge_flags & ALL_FL(TOP_HAS_RIGHT)) |
nt->split[0] = (edge_flags & EDGE_ALL_TOP_HAS_RIGHT) |
EDGE_I422_LEFT_HAS_BOTTOM;
nt->split[2] = edge_flags | EDGE_I444_TOP_HAS_RIGHT;
nt->split[3] = edge_flags & (EDGE_I420_TOP_HAS_RIGHT |
nt->split[1] = edge_flags | EDGE_I444_TOP_HAS_RIGHT;
nt->split[2] = edge_flags & (EDGE_I420_TOP_HAS_RIGHT |
EDGE_I420_LEFT_HAS_BOTTOM |
EDGE_I422_LEFT_HAS_BOTTOM);
} else {
EdgeBranch *const nwc = (EdgeBranch *) node;
node->h[0] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM);
node->h[1] = edge_flags & ALL_FL(LEFT_HAS_BOTTOM);
node->h[1] = edge_flags & EDGE_ALL_LEFT_HAS_BOTTOM;
node->v[1] = edge_flags & EDGE_ALL_TOP_HAS_RIGHT;
node->v[0] = edge_flags | ALL_FL(TOP_HAS_RIGHT);
node->v[1] = edge_flags & ALL_FL(TOP_HAS_RIGHT);
nwc->h4[0] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM);
nwc->h4[1] =
nwc->h4[2] = ALL_FL(LEFT_HAS_BOTTOM);
nwc->h4[3] = edge_flags & ALL_FL(LEFT_HAS_BOTTOM);
if (bl == BL_16X16)
nwc->h4[1] |= edge_flags & EDGE_I420_TOP_HAS_RIGHT;
nwc->v4[0] = edge_flags | ALL_FL(TOP_HAS_RIGHT);
nwc->v4[1] =
nwc->v4[2] = ALL_FL(TOP_HAS_RIGHT);
nwc->v4[3] = edge_flags & ALL_FL(TOP_HAS_RIGHT);
if (bl == BL_16X16)
nwc->v4[1] |= edge_flags & (EDGE_I420_LEFT_HAS_BOTTOM |
EDGE_I422_LEFT_HAS_BOTTOM);
nwc->tls[0] = ALL_FL(TOP_HAS_RIGHT) | ALL_FL(LEFT_HAS_BOTTOM);
nwc->tls[1] = edge_flags & ALL_FL(LEFT_HAS_BOTTOM);
nwc->tls[2] = edge_flags & ALL_FL(TOP_HAS_RIGHT);
nwc->trs[0] = edge_flags | ALL_FL(TOP_HAS_RIGHT);
nwc->trs[1] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM);
nwc->trs[2] = 0;
nwc->tts[0] = ALL_FL(TOP_HAS_RIGHT) | ALL_FL(LEFT_HAS_BOTTOM);
nwc->tts[1] = edge_flags & ALL_FL(TOP_HAS_RIGHT);
nwc->tts[2] = edge_flags & ALL_FL(LEFT_HAS_BOTTOM);
nwc->tbs[0] = edge_flags | ALL_FL(LEFT_HAS_BOTTOM);
nwc->tbs[1] = edge_flags | ALL_FL(TOP_HAS_RIGHT);
nwc->tbs[2] = 0;
nwc->h4 = EDGE_ALL_LEFT_HAS_BOTTOM;
nwc->v4 = EDGE_ALL_TOP_HAS_RIGHT;
if (bl == BL_16X16) {
nwc->h4 |= edge_flags & EDGE_I420_TOP_HAS_RIGHT;
nwc->v4 |= edge_flags & (EDGE_I420_LEFT_HAS_BOTTOM |
EDGE_I422_LEFT_HAS_BOTTOM);
}
}
}
static void init_mode_node(EdgeBranch *const nwc,
const enum BlockLevel bl,
struct ModeSelMem *const mem,
const int top_has_right,
const int left_has_bottom)
#define PTR_OFFSET(a, b) ((uint16_t)((uintptr_t)(b) - (uintptr_t)(a)))
static COLD void init_mode_node(EdgeBranch *const nwc,
const enum BlockLevel bl,
struct ModeSelMem *const mem,
const int top_has_right,
const int left_has_bottom)
{
init_edges(&nwc->node, bl,
(top_has_right ? ALL_FL(TOP_HAS_RIGHT) : 0) |
(left_has_bottom ? ALL_FL(LEFT_HAS_BOTTOM) : 0));
(top_has_right ? EDGE_ALL_TOP_HAS_RIGHT : 0) |
(left_has_bottom ? EDGE_ALL_LEFT_HAS_BOTTOM : 0));
if (bl == BL_16X16) {
for (int n = 0; n < 4; n++) {
EdgeTip *const nt = mem->nt++;
nwc->split[n] = &nt->node;
nwc->split_offset[n] = PTR_OFFSET(nwc, nt);
init_edges(&nt->node, bl + 1,
((n == 3 || (n == 1 && !top_has_right)) ? 0 :
ALL_FL(TOP_HAS_RIGHT)) |
EDGE_ALL_TOP_HAS_RIGHT) |
(!(n == 0 || (n == 2 && left_has_bottom)) ? 0 :
ALL_FL(LEFT_HAS_BOTTOM)));
EDGE_ALL_LEFT_HAS_BOTTOM));
}
} else {
for (int n = 0; n < 4; n++) {
EdgeBranch *const nwc_child = mem->nwc[bl]++;
nwc->split[n] = &nwc_child->node;
nwc->split_offset[n] = PTR_OFFSET(nwc, nwc_child);
init_mode_node(nwc_child, bl + 1, mem,
!(n == 3 || (n == 1 && !top_has_right)),
n == 0 || (n == 2 && left_has_bottom));
@ -137,29 +123,26 @@ static void init_mode_node(EdgeBranch *const nwc,
}
}
void dav1d_init_mode_tree(EdgeNode *const root_node, EdgeTip *const nt,
const int allow_sb128)
{
EdgeBranch *const root = (EdgeBranch *) root_node;
COLD void dav1d_init_intra_edge_tree(void) {
// This function is guaranteed to be called only once
struct ModeSelMem mem;
mem.nt = nt;
if (allow_sb128) {
mem.nwc[BL_128X128] = &root[1];
mem.nwc[BL_64X64] = &root[1 + 4];
mem.nwc[BL_32X32] = &root[1 + 4 + 16];
init_mode_node(root, BL_128X128, &mem, 1, 0);
assert(mem.nwc[BL_128X128] == &root[1 + 4]);
assert(mem.nwc[BL_64X64] == &root[1 + 4 + 16]);
assert(mem.nwc[BL_32X32] == &root[1 + 4 + 16 + 64]);
assert(mem.nt == &nt[256]);
} else {
mem.nwc[BL_128X128] = NULL;
mem.nwc[BL_64X64] = &root[1];
mem.nwc[BL_32X32] = &root[1 + 4];
init_mode_node(root, BL_64X64, &mem, 1, 0);
assert(mem.nwc[BL_64X64] == &root[1 + 4]);
assert(mem.nwc[BL_32X32] == &root[1 + 4 + 16]);
assert(mem.nt == &nt[64]);
}
mem.nwc[BL_128X128] = &nodes.branch_sb128[1];
mem.nwc[BL_64X64] = &nodes.branch_sb128[1 + 4];
mem.nwc[BL_32X32] = &nodes.branch_sb128[1 + 4 + 16];
mem.nt = nodes.tip_sb128;
init_mode_node(nodes.branch_sb128, BL_128X128, &mem, 1, 0);
assert(mem.nwc[BL_128X128] == &nodes.branch_sb128[1 + 4]);
assert(mem.nwc[BL_64X64] == &nodes.branch_sb128[1 + 4 + 16]);
assert(mem.nwc[BL_32X32] == &nodes.branch_sb128[1 + 4 + 16 + 64]);
assert(mem.nt == &nodes.tip_sb128[256]);
mem.nwc[BL_128X128] = NULL;
mem.nwc[BL_64X64] = &nodes.branch_sb64[1];
mem.nwc[BL_32X32] = &nodes.branch_sb64[1 + 4];
mem.nt = nodes.tip_sb64;
init_mode_node(nodes.branch_sb64, BL_64X64, &mem, 1, 0);
assert(mem.nwc[BL_64X64] == &nodes.branch_sb64[1 + 4]);
assert(mem.nwc[BL_32X32] == &nodes.branch_sb64[1 + 4 + 16]);
assert(mem.nt == &nodes.tip_sb64[64]);
}

44
third_party/dav1d/src/intra_edge.h поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
/*
* Copyright © 2018, VideoLAN and dav1d authors
* Copyright © 2018, Two Orioles, LLC
* Copyright © 2018-2023, VideoLAN and dav1d authors
* Copyright © 2018-2023, Two Orioles, LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -28,30 +28,46 @@
#ifndef DAV1D_SRC_INTRA_EDGE_H
#define DAV1D_SRC_INTRA_EDGE_H
#include <stdint.h>
enum EdgeFlags {
EDGE_I444_TOP_HAS_RIGHT = 1 << 0,
EDGE_I422_TOP_HAS_RIGHT = 1 << 1,
EDGE_I420_TOP_HAS_RIGHT = 1 << 2,
EDGE_I444_TOP_HAS_RIGHT = 1 << 0,
EDGE_I422_TOP_HAS_RIGHT = 1 << 1,
EDGE_I420_TOP_HAS_RIGHT = 1 << 2,
EDGE_I444_LEFT_HAS_BOTTOM = 1 << 3,
EDGE_I422_LEFT_HAS_BOTTOM = 1 << 4,
EDGE_I420_LEFT_HAS_BOTTOM = 1 << 5,
EDGE_ALL_TOP_HAS_RIGHT = EDGE_I444_TOP_HAS_RIGHT |
EDGE_I422_TOP_HAS_RIGHT |
EDGE_I420_TOP_HAS_RIGHT,
EDGE_ALL_LEFT_HAS_BOTTOM = EDGE_I444_LEFT_HAS_BOTTOM |
EDGE_I422_LEFT_HAS_BOTTOM |
EDGE_I420_LEFT_HAS_BOTTOM,
EDGE_ALL_TR_AND_BL = EDGE_ALL_TOP_HAS_RIGHT |
EDGE_ALL_LEFT_HAS_BOTTOM,
};
typedef struct EdgeNode EdgeNode;
struct EdgeNode {
enum EdgeFlags o, h[2], v[2];
};
#define INTRA_EDGE_SPLIT(n, i) \
((const EdgeNode*)((uintptr_t)(n) + ((const EdgeBranch*)(n))->split_offset[i]))
typedef struct EdgeNode {
uint8_t /* enum EdgeFlags */ o, h[2], v[2];
} EdgeNode;
typedef struct EdgeTip {
EdgeNode node;
enum EdgeFlags split[4];
uint8_t /* enum EdgeFlags */ split[3];
} EdgeTip;
typedef struct EdgeBranch {
EdgeNode node;
enum EdgeFlags tts[3], tbs[3], tls[3], trs[3], h4[4], v4[4];
EdgeNode *split[4];
uint8_t /* enum EdgeFlags */ h4, v4;
uint16_t split_offset[4]; /* relative to the address of this node */
} EdgeBranch;
void dav1d_init_mode_tree(EdgeNode *const root, EdgeTip *const nt,
const int allow_sb128);
/* Tree to keep track of which edges are available. */
EXTERN const EdgeNode *dav1d_intra_edge_tree[2 /* BL_128X128, BL_64X64 */];
void dav1d_init_intra_edge_tree(void);
#endif /* DAV1D_SRC_INTRA_EDGE_H */

4
third_party/dav1d/src/lf_mask.c поставляемый
Просмотреть файл

@ -301,6 +301,7 @@ void dav1d_create_lf_mask_intra(Av1Filter *const lflvl,
const int bh4 = imin(ih - by, b_dim[1]);
const int bx4 = bx & 31;
const int by4 = by & 31;
assert(bw4 >= 0 && bh4 >= 0);
if (bw4 && bh4) {
uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
@ -323,6 +324,7 @@ void dav1d_create_lf_mask_intra(Av1Filter *const lflvl,
(b_dim[0] + ss_hor) >> ss_hor);
const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
(b_dim[1] + ss_ver) >> ss_ver);
assert(cbw4 >= 0 && cbh4 >= 0);
if (!cbw4 || !cbh4) return;
@ -362,6 +364,7 @@ void dav1d_create_lf_mask_inter(Av1Filter *const lflvl,
const int bh4 = imin(ih - by, b_dim[1]);
const int bx4 = bx & 31;
const int by4 = by & 31;
assert(bw4 >= 0 && bh4 >= 0);
if (bw4 && bh4) {
uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
@ -385,6 +388,7 @@ void dav1d_create_lf_mask_inter(Av1Filter *const lflvl,
(b_dim[0] + ss_hor) >> ss_hor);
const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
(b_dim[1] + ss_ver) >> ss_ver);
assert(cbw4 >= 0 && cbh4 >= 0);
if (!cbw4 || !cbh4) return;

2
third_party/dav1d/src/lf_mask.h поставляемый
Просмотреть файл

@ -40,10 +40,10 @@ typedef struct Av1FilterLUT {
} Av1FilterLUT;
typedef struct Av1RestorationUnit {
/* SGR: type = DAV1D_RESTORATION_SGRPROJ + sgr_idx */
uint8_t /* enum Dav1dRestorationType */ type;
int8_t filter_h[3];
int8_t filter_v[3];
uint8_t sgr_idx;
int8_t sgr_weights[2];
} Av1RestorationUnit;

70
third_party/dav1d/src/lib.c поставляемый
Просмотреть файл

@ -53,6 +53,7 @@
static COLD void init_internal(void) {
dav1d_init_cpu();
dav1d_init_interintra_masks();
dav1d_init_intra_edge_tree();
dav1d_init_qm_tables();
dav1d_init_thread();
dav1d_init_wedge_masks();
@ -175,6 +176,7 @@ COLD int dav1d_open(Dav1dContext **const c_out, const Dav1dSettings *const s) {
dav1d_mem_pool_init(&c->frame_hdr_pool) ||
dav1d_mem_pool_init(&c->segmap_pool) ||
dav1d_mem_pool_init(&c->refmvs_pool) ||
dav1d_mem_pool_init(&c->pic_ctx_pool) ||
dav1d_mem_pool_init(&c->cdf_pool))
{
goto error;
@ -279,12 +281,6 @@ COLD int dav1d_open(Dav1dContext **const c_out, const Dav1dSettings *const s) {
}
dav1d_refmvs_dsp_init(&c->refmvs_dsp);
// intra edge tree
c->intra_edge.root[BL_128X128] = &c->intra_edge.branch_sb128[0].node;
dav1d_init_mode_tree(c->intra_edge.root[BL_128X128], c->intra_edge.tip_sb128, 1);
c->intra_edge.root[BL_64X64] = &c->intra_edge.branch_sb64[0].node;
dav1d_init_mode_tree(c->intra_edge.root[BL_64X64], c->intra_edge.tip_sb64, 0);
pthread_attr_destroy(&thread_attr);
return 0;
@ -295,56 +291,6 @@ error:
return DAV1D_ERR(ENOMEM);
}
static void dummy_free(const uint8_t *const data, void *const user_data) {
assert(data && !user_data);
}
int dav1d_parse_sequence_header(Dav1dSequenceHeader *const out,
const uint8_t *const ptr, const size_t sz)
{
Dav1dData buf = { 0 };
int res;
validate_input_or_ret(out != NULL, DAV1D_ERR(EINVAL));
Dav1dSettings s;
dav1d_default_settings(&s);
s.n_threads = 1;
s.logger.callback = NULL;
Dav1dContext *c;
res = dav1d_open(&c, &s);
if (res < 0) return res;
if (ptr) {
res = dav1d_data_wrap_internal(&buf, ptr, sz, dummy_free, NULL);
if (res < 0) goto error;
}
while (buf.sz > 0) {
res = dav1d_parse_obus(c, &buf, 1);
if (res < 0) goto error;
assert((size_t)res <= buf.sz);
buf.sz -= res;
buf.data += res;
}
if (!c->seq_hdr) {
res = DAV1D_ERR(ENOENT);
goto error;
}
memcpy(out, c->seq_hdr, sizeof(*out));
res = 0;
error:
dav1d_data_unref_internal(&buf);
dav1d_close(&c);
return res;
}
static int has_grain(const Dav1dPicture *const pic)
{
const Dav1dFilmGrainData *fgdata = &pic->frame_hdr->film_grain.data;
@ -456,14 +402,13 @@ static int drain_picture(Dav1dContext *const c, Dav1dPicture *const out) {
static int gen_picture(Dav1dContext *const c)
{
int res;
Dav1dData *const in = &c->in;
if (output_picture_ready(c, 0))
return 0;
while (in->sz > 0) {
res = dav1d_parse_obus(c, in, 0);
const ptrdiff_t res = dav1d_parse_obus(c, in);
if (res < 0) {
dav1d_data_unref_internal(in);
} else {
@ -475,7 +420,7 @@ static int gen_picture(Dav1dContext *const c)
if (output_picture_ready(c, 0))
break;
if (res < 0)
return res;
return (int)res;
}
return 0;
@ -485,10 +430,11 @@ int dav1d_send_data(Dav1dContext *const c, Dav1dData *const in)
{
validate_input_or_ret(c != NULL, DAV1D_ERR(EINVAL));
validate_input_or_ret(in != NULL, DAV1D_ERR(EINVAL));
validate_input_or_ret(in->data == NULL || in->sz, DAV1D_ERR(EINVAL));
if (in->data)
if (in->data) {
validate_input_or_ret(in->sz > 0 && in->sz <= SIZE_MAX / 2, DAV1D_ERR(EINVAL));
c->drain = 0;
}
if (c->in.data)
return DAV1D_ERR(EAGAIN);
dav1d_data_ref(&c->in, in);
@ -592,6 +538,7 @@ void dav1d_flush(Dav1dContext *const c) {
c->mastering_display = NULL;
c->content_light = NULL;
c->itut_t35 = NULL;
c->n_itut_t35 = 0;
dav1d_ref_dec(&c->mastering_display_ref);
dav1d_ref_dec(&c->content_light_ref);
dav1d_ref_dec(&c->itut_t35_ref);
@ -740,6 +687,7 @@ static COLD void close_internal(Dav1dContext **const c_out, int flush) {
dav1d_mem_pool_end(c->refmvs_pool);
dav1d_mem_pool_end(c->cdf_pool);
dav1d_mem_pool_end(c->picture_pool);
dav1d_mem_pool_end(c->pic_ctx_pool);
dav1d_freep_aligned(c_out);
}

5
third_party/dav1d/src/lr_apply_tmpl.c поставляемый
Просмотреть файл

@ -71,8 +71,9 @@ static void lr_stripe(const Dav1dFrameContext *const f, pixel *p,
lr_fn = dsp->lr.wiener[!(filter[0][0] | filter[1][0])];
} else {
assert(lr->type == DAV1D_RESTORATION_SGRPROJ);
const uint16_t *const sgr_params = dav1d_sgr_params[lr->sgr_idx];
assert(lr->type >= DAV1D_RESTORATION_SGRPROJ);
const int sgr_idx = lr->type - DAV1D_RESTORATION_SGRPROJ;
const uint16_t *const sgr_params = dav1d_sgr_params[sgr_idx];
params.sgr.s0 = sgr_params[0];
params.sgr.s1 = sgr_params[1];
params.sgr.w0 = lr->sgr_weights[0];

251
third_party/dav1d/src/obu.c поставляемый
Просмотреть файл

@ -35,6 +35,7 @@
#include "common/frame.h"
#include "common/intops.h"
#include "common/validate.h"
#include "src/decode.h"
#include "src/getbits.h"
@ -44,8 +45,33 @@
#include "src/ref.h"
#include "src/thread_task.h"
static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
Dav1dSequenceHeader *const hdr)
static int check_trailing_bits(GetBits *const gb,
const int strict_std_compliance)
{
const int trailing_one_bit = dav1d_get_bit(gb);
if (gb->error)
return DAV1D_ERR(EINVAL);
if (!strict_std_compliance)
return 0;
if (!trailing_one_bit || gb->state)
return DAV1D_ERR(EINVAL);
ptrdiff_t size = gb->ptr_end - gb->ptr;
while (size > 0 && gb->ptr[size - 1] == 0)
size--;
if (size)
return DAV1D_ERR(EINVAL);
return 0;
}
static NOINLINE int parse_seq_hdr(Dav1dSequenceHeader *const hdr,
GetBits *const gb,
const int strict_std_compliance)
{
#define DEBUG_SEQ_HDR 0
@ -79,6 +105,8 @@ static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
if (hdr->timing_info_present) {
hdr->num_units_in_tick = dav1d_get_bits(gb, 32);
hdr->time_scale = dav1d_get_bits(gb, 32);
if (strict_std_compliance && (!hdr->num_units_in_tick || !hdr->time_scale))
goto error;
hdr->equal_picture_interval = dav1d_get_bit(gb);
if (hdr->equal_picture_interval) {
const unsigned num_ticks_per_picture = dav1d_get_vlc(gb);
@ -91,6 +119,8 @@ static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
if (hdr->decoder_model_info_present) {
hdr->encoder_decoder_buffer_delay_length = dav1d_get_bits(gb, 5) + 1;
hdr->num_units_in_decoding_tick = dav1d_get_bits(gb, 32);
if (strict_std_compliance && !hdr->num_units_in_decoding_tick)
goto error;
hdr->buffer_removal_delay_length = dav1d_get_bits(gb, 5) + 1;
hdr->frame_presentation_delay_length = dav1d_get_bits(gb, 5) + 1;
}
@ -135,12 +165,6 @@ static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
#endif
}
const int op_idx =
c->operating_point < hdr->num_operating_points ? c->operating_point : 0;
c->operating_point_idc = hdr->operating_points[op_idx].idc;
const unsigned spatial_mask = c->operating_point_idc >> 8;
c->max_spatial_id = spatial_mask ? ulog2(spatial_mask) : 0;
hdr->width_n_bits = dav1d_get_bits(gb, 4) + 1;
hdr->height_n_bits = dav1d_get_bits(gb, 4) + 1;
hdr->max_width = dav1d_get_bits(gb, hdr->width_n_bits) + 1;
@ -247,7 +271,7 @@ static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
hdr->chr = (hdr->ss_hor & hdr->ss_ver) ?
dav1d_get_bits(gb, 2) : DAV1D_CHR_UNKNOWN;
}
if (c->strict_std_compliance &&
if (strict_std_compliance &&
hdr->mtrx == DAV1D_MC_IDENTITY && hdr->layout != DAV1D_PIXEL_LAYOUT_I444)
{
goto error;
@ -265,19 +289,55 @@ static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
dav1d_get_bits_pos(gb) - init_bit_pos);
#endif
dav1d_get_bit(gb); // dummy bit
// We needn't bother flushing the OBU here: we'll check we didn't
// overrun in the caller and will then discard gb, so there's no
// point in setting its position properly.
return 0;
return check_trailing_bits(gb, strict_std_compliance);
error:
dav1d_log(c, "Error parsing sequence header\n");
return DAV1D_ERR(EINVAL);
}
int dav1d_parse_sequence_header(Dav1dSequenceHeader *const out,
const uint8_t *const ptr, const size_t sz)
{
validate_input_or_ret(out != NULL, DAV1D_ERR(EINVAL));
validate_input_or_ret(ptr != NULL, DAV1D_ERR(EINVAL));
validate_input_or_ret(sz > 0, DAV1D_ERR(EINVAL));
GetBits gb;
dav1d_init_get_bits(&gb, ptr, sz);
int res = DAV1D_ERR(ENOENT);
do {
dav1d_get_bit(&gb); // obu_forbidden_bit
const enum Dav1dObuType type = dav1d_get_bits(&gb, 4);
const int has_extension = dav1d_get_bit(&gb);
const int has_length_field = dav1d_get_bit(&gb);
dav1d_get_bits(&gb, 1 + 8 * has_extension); // ignore
const uint8_t *obu_end = gb.ptr_end;
if (has_length_field) {
const size_t len = dav1d_get_uleb128(&gb);
if (len > (size_t)(obu_end - gb.ptr)) return DAV1D_ERR(EINVAL);
obu_end = gb.ptr + len;
}
if (type == DAV1D_OBU_SEQ_HDR) {
if ((res = parse_seq_hdr(out, &gb, 0)) < 0) return res;
if (gb.ptr > obu_end) return DAV1D_ERR(EINVAL);
dav1d_bytealign_get_bits(&gb);
}
if (gb.error) return DAV1D_ERR(EINVAL);
assert(gb.state == 0 && gb.bits_left == 0);
gb.ptr = obu_end;
} while (gb.ptr < gb.ptr_end);
return res;
}
static int read_frame_size(Dav1dContext *const c, GetBits *const gb,
const int use_ref)
{
@ -1149,40 +1209,15 @@ static void parse_tile_hdr(Dav1dContext *const c, GetBits *const gb) {
}
}
// Check that we haven't read more than obu_len bytes from the buffer
// since init_bit_pos.
static int check_for_overrun(Dav1dContext *const c, GetBits *const gb,
const unsigned init_bit_pos,
const unsigned obu_len)
{
// Make sure we haven't actually read past the end of the gb buffer
if (gb->error) {
dav1d_log(c, "Overrun in OBU bit buffer\n");
return 1;
}
const unsigned pos = dav1d_get_bits_pos(gb);
// We assume that init_bit_pos was the bit position of the buffer
// at some point in the past, so cannot be smaller than pos.
assert (init_bit_pos <= pos);
if (pos - init_bit_pos > 8 * obu_len) {
dav1d_log(c, "Overrun in OBU bit buffer into next OBU\n");
return 1;
}
return 0;
}
int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int global) {
ptrdiff_t dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
GetBits gb;
int res;
dav1d_init_get_bits(&gb, in->data, in->sz);
// obu header
dav1d_get_bit(&gb); // obu_forbidden_bit
const int obu_forbidden_bit = dav1d_get_bit(&gb);
if (c->strict_std_compliance && obu_forbidden_bit) goto error;
const enum Dav1dObuType type = dav1d_get_bits(&gb, 4);
const int has_extension = dav1d_get_bit(&gb);
const int has_length_field = dav1d_get_bit(&gb);
@ -1195,27 +1230,17 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
dav1d_get_bits(&gb, 3); // reserved
}
// obu length field
const unsigned len = has_length_field ?
dav1d_get_uleb128(&gb) : (unsigned) in->sz - 1 - has_extension;
if (has_length_field) {
const size_t len = dav1d_get_uleb128(&gb);
if (len > (size_t)(gb.ptr_end - gb.ptr)) goto error;
gb.ptr_end = gb.ptr + len;
}
if (gb.error) goto error;
const unsigned init_bit_pos = dav1d_get_bits_pos(&gb);
const unsigned init_byte_pos = init_bit_pos >> 3;
// We must have read a whole number of bytes at this point (1 byte
// for the header and whole bytes at a time when reading the
// leb128 length field).
assert((init_bit_pos & 7) == 0);
// We also know that we haven't tried to read more than in->sz
// bytes yet (otherwise the error flag would have been set by the
// code in getbits.c)
assert(in->sz >= init_byte_pos);
// Make sure that there are enough bits left in the buffer for the
// rest of the OBU.
if (len > in->sz - init_byte_pos) goto error;
assert(gb.bits_left == 0);
// skip obu not belonging to the selected temporal/spatial layer
if (type != DAV1D_OBU_SEQ_HDR && type != DAV1D_OBU_TD &&
@ -1224,7 +1249,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
const int in_temporal_layer = (c->operating_point_idc >> temporal_id) & 1;
const int in_spatial_layer = (c->operating_point_idc >> (spatial_id + 8)) & 1;
if (!in_temporal_layer || !in_spatial_layer)
return len + init_byte_pos;
return gb.ptr_end - gb.ptr_start;
}
switch (type) {
@ -1233,14 +1258,18 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
sizeof(Dav1dSequenceHeader));
if (!ref) return DAV1D_ERR(ENOMEM);
Dav1dSequenceHeader *seq_hdr = ref->data;
if ((res = parse_seq_hdr(c, &gb, seq_hdr)) < 0) {
dav1d_ref_dec(&ref);
goto error;
}
if (check_for_overrun(c, &gb, init_bit_pos, len)) {
if ((res = parse_seq_hdr(seq_hdr, &gb, c->strict_std_compliance)) < 0) {
dav1d_log(c, "Error parsing sequence header\n");
dav1d_ref_dec(&ref);
goto error;
}
const int op_idx =
c->operating_point < seq_hdr->num_operating_points ? c->operating_point : 0;
c->operating_point_idc = seq_hdr->operating_points[op_idx].idc;
const unsigned spatial_mask = c->operating_point_idc >> 8;
c->max_spatial_id = spatial_mask ? ulog2(spatial_mask) : 0;
// If we have read a sequence header which is different from
// the old one, this is a new video sequence and can't use any
// previous state. Free that state.
@ -1280,7 +1309,6 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
// fall-through
case DAV1D_OBU_FRAME:
case DAV1D_OBU_FRAME_HDR:
if (global) break;
if (!c->seq_hdr) goto error;
if (!c->frame_hdr_ref) {
c->frame_hdr_ref = dav1d_ref_create_using_pool(c->frame_hdr_pool,
@ -1306,8 +1334,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
if (type != DAV1D_OBU_FRAME) {
// This is actually a frame header OBU so read the
// trailing bit and check for overrun.
dav1d_get_bit(&gb);
if (check_for_overrun(c, &gb, init_bit_pos, len)) {
if (check_trailing_bits(&gb, c->strict_std_compliance) < 0) {
c->frame_hdr = NULL;
goto error;
}
@ -1336,7 +1363,6 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
dav1d_bytealign_get_bits(&gb);
// fall-through
case DAV1D_OBU_TILE_GRP: {
if (global) break;
if (!c->frame_hdr) goto error;
if (c->n_tile_data_alloc < c->n_tile_data + 1) {
if ((c->n_tile_data + 1) > INT_MAX / (int)sizeof(*c->tile)) goto error;
@ -1349,18 +1375,11 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
parse_tile_hdr(c, &gb);
// Align to the next byte boundary and check for overrun.
dav1d_bytealign_get_bits(&gb);
if (check_for_overrun(c, &gb, init_bit_pos, len))
goto error;
// The current bit position is a multiple of 8 (because we
// just aligned it) and less than 8*pkt_bytelen because
// otherwise the overrun check would have fired.
const unsigned pkt_bytelen = init_byte_pos + len;
const unsigned bit_pos = dav1d_get_bits_pos(&gb);
assert((bit_pos & 7) == 0);
assert(pkt_bytelen >= (bit_pos >> 3));
if (gb.error) goto error;
dav1d_data_ref(&c->tile[c->n_tile_data].data, in);
c->tile[c->n_tile_data].data.data += bit_pos >> 3;
c->tile[c->n_tile_data].data.sz = pkt_bytelen - (bit_pos >> 3);
c->tile[c->n_tile_data].data.data = gb.ptr;
c->tile[c->n_tile_data].data.sz = (size_t)(gb.ptr_end - gb.ptr);
// ensure tile groups are in order and sane, see 6.10.1
if (c->tile[c->n_tile_data].start > c->tile[c->n_tile_data].end ||
c->tile[c->n_tile_data].start != c->n_tiles)
@ -1383,7 +1402,6 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
#endif
// obu metadta type field
const enum ObuMetaType meta_type = dav1d_get_uleb128(&gb);
const int meta_type_len = (dav1d_get_bits_pos(&gb) - init_bit_pos) >> 3;
if (gb.error) goto error;
switch (meta_type) {
@ -1405,10 +1423,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
(gb.ptr - init_ptr) * 8 - gb.bits_left);
#endif
// Skip the trailing bit, align to the next byte boundary and check for overrun.
dav1d_get_bit(&gb);
dav1d_bytealign_get_bits(&gb);
if (check_for_overrun(c, &gb, init_bit_pos, len)) {
if (check_trailing_bits(&gb, c->strict_std_compliance) < 0) {
dav1d_ref_dec(&ref);
goto error;
}
@ -1457,10 +1472,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
mastering_display->min_luminance,
(gb.ptr - init_ptr) * 8 - gb.bits_left);
#endif
// Skip the trailing bit, align to the next byte boundary and check for overrun.
dav1d_get_bit(&gb);
dav1d_bytealign_get_bits(&gb);
if (check_for_overrun(c, &gb, init_bit_pos, len)) {
if (check_trailing_bits(&gb, c->strict_std_compliance) < 0) {
dav1d_ref_dec(&ref);
goto error;
}
@ -1471,15 +1483,12 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
break;
}
case OBU_META_ITUT_T35: {
int payload_size = len;
ptrdiff_t payload_size = gb.ptr_end - gb.ptr;
// Don't take into account all the trailing bits for payload_size
while (payload_size > 0 && !in->data[init_byte_pos + payload_size - 1])
while (payload_size > 0 && !gb.ptr[payload_size - 1])
payload_size--; // trailing_zero_bit x 8
payload_size--; // trailing_one_bit + trailing_zero_bit x 7
// Don't take into account meta_type bytes
payload_size -= meta_type_len;
int country_code_extension_byte = 0;
const int country_code = dav1d_get_bits(&gb, 8);
payload_size--;
@ -1488,27 +1497,46 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
payload_size--;
}
if (payload_size <= 0) {
if (payload_size <= 0 || gb.ptr[payload_size] != 0x80) {
dav1d_log(c, "Malformed ITU-T T.35 metadata message format\n");
break;
}
Dav1dRef *ref = dav1d_ref_create(sizeof(Dav1dITUTT35) + payload_size * sizeof(uint8_t));
if (!ref) return DAV1D_ERR(ENOMEM);
Dav1dITUTT35 *const itut_t35_metadata = ref->data;
if ((c->n_itut_t35 + 1) > INT_MAX / (int)sizeof(*c->itut_t35)) goto error;
struct Dav1dITUTT35 *itut_t35 = realloc(c->itut_t35, (c->n_itut_t35 + 1) * sizeof(*c->itut_t35));
if (!itut_t35) goto error;
c->itut_t35 = itut_t35;
memset(c->itut_t35 + c->n_itut_t35, 0, sizeof(*c->itut_t35));
struct itut_t35_ctx_context *itut_t35_ctx;
if (!c->n_itut_t35) {
assert(!c->itut_t35_ref);
itut_t35_ctx = malloc(sizeof(struct itut_t35_ctx_context));
if (!itut_t35_ctx) goto error;
c->itut_t35_ref = dav1d_ref_init(&itut_t35_ctx->ref, c->itut_t35,
dav1d_picture_free_itut_t35, itut_t35_ctx, 0);
} else {
assert(c->itut_t35_ref && atomic_load(&c->itut_t35_ref->ref_cnt) == 1);
itut_t35_ctx = c->itut_t35_ref->user_data;
c->itut_t35_ref->const_data = (uint8_t *)c->itut_t35;
}
itut_t35_ctx->itut_t35 = c->itut_t35;
itut_t35_ctx->n_itut_t35 = c->n_itut_t35 + 1;
Dav1dITUTT35 *const itut_t35_metadata = &c->itut_t35[c->n_itut_t35];
itut_t35_metadata->payload = malloc(payload_size);
if (!itut_t35_metadata->payload) goto error;
// We need our public headers to be C++ compatible, so payload can't be
// a flexible array member
itut_t35_metadata->payload = (uint8_t *) &itut_t35_metadata[1];
itut_t35_metadata->country_code = country_code;
itut_t35_metadata->country_code_extension_byte = country_code_extension_byte;
for (int i = 0; i < payload_size; i++)
itut_t35_metadata->payload[i] = dav1d_get_bits(&gb, 8);
itut_t35_metadata->payload_size = payload_size;
dav1d_ref_dec(&c->itut_t35_ref);
c->itut_t35 = itut_t35_metadata;
c->itut_t35_ref = ref;
// We know that we've read a whole number of bytes and that the
// payload is within the OBU boundaries, so just use memcpy()
assert(gb.bits_left == 0);
memcpy(itut_t35_metadata->payload, gb.ptr, payload_size);
c->n_itut_t35++;
break;
}
case OBU_META_SCALABILITY:
@ -1531,7 +1559,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
break;
default:
// print a warning but don't fail for unknown types
dav1d_log(c, "Unknown OBU type %d of size %u\n", type, len);
dav1d_log(c, "Unknown OBU type %d of size %td\n", type, gb.ptr_end - gb.ptr);
break;
}
@ -1563,11 +1591,12 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
dav1d_picture_copy_props(&c->out.p,
c->content_light, c->content_light_ref,
c->mastering_display, c->mastering_display_ref,
c->itut_t35, c->itut_t35_ref,
c->itut_t35, c->itut_t35_ref, c->n_itut_t35,
&in->m);
// Must be removed from the context after being attached to the frame
dav1d_ref_dec(&c->itut_t35_ref);
c->itut_t35 = NULL;
c->n_itut_t35 = 0;
c->event_flags |= dav1d_picture_get_event_flags(&c->refs[c->frame_hdr->existing_frame_idx].p);
} else {
pthread_mutex_lock(&c->task_thread.lock);
@ -1616,11 +1645,12 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
dav1d_picture_copy_props(&out_delayed->p,
c->content_light, c->content_light_ref,
c->mastering_display, c->mastering_display_ref,
c->itut_t35, c->itut_t35_ref,
c->itut_t35, c->itut_t35_ref, c->n_itut_t35,
&in->m);
// Must be removed from the context after being attached to the frame
dav1d_ref_dec(&c->itut_t35_ref);
c->itut_t35 = NULL;
c->n_itut_t35 = 0;
pthread_mutex_unlock(&c->task_thread.lock);
}
@ -1673,7 +1703,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa
}
}
return len + init_byte_pos;
return gb.ptr_end - gb.ptr_start;
skip:
// update refs with only the headers in case we skip the frame
@ -1693,10 +1723,11 @@ skip:
c->frame_hdr = NULL;
c->n_tiles = 0;
return len + init_byte_pos;
return gb.ptr_end - gb.ptr_start;
error:
dav1d_data_props_copy(&c->cached_error_props, &in->m);
dav1d_log(c, "Error parsing OBU data\n");
dav1d_log(c, gb.error ? "Overrun in OBU bit buffer\n" :
"Error parsing OBU data\n");
return DAV1D_ERR(EINVAL);
}

2
third_party/dav1d/src/obu.h поставляемый
Просмотреть файл

@ -31,6 +31,6 @@
#include "dav1d/data.h"
#include "src/internal.h"
int dav1d_parse_obus(Dav1dContext *c, Dav1dData *in, int global);
ptrdiff_t dav1d_parse_obus(Dav1dContext *c, Dav1dData *in);
#endif /* DAV1D_SRC_OBU_H */

123
third_party/dav1d/src/picture.c поставляемый
Просмотреть файл

@ -87,31 +87,28 @@ void dav1d_default_picture_release(Dav1dPicture *const p, void *const cookie) {
}
struct pic_ctx_context {
struct Dav1dRef *plane_ref[3]; /* MUST BE FIRST */
enum Dav1dPixelLayout layout;
void *extra_ptr; /* MUST BE AT THE END */
};
struct plane_ctx_context {
Dav1dPicAllocator allocator;
Dav1dPicture pic;
Dav1dRef ref;
void *extra_data[];
};
static void free_buffer(const uint8_t *const data, void *const user_data) {
struct pic_ctx_context *pic_ctx = user_data;
const int planes = pic_ctx->layout != DAV1D_PIXEL_LAYOUT_I400 ? 3 : 1;
Dav1dMemPoolBuffer *buf = (Dav1dMemPoolBuffer *)data;
struct pic_ctx_context *pic_ctx = buf->data;
for (int i = 0; i < planes; i++)
dav1d_ref_dec(&pic_ctx->plane_ref[i]);
free(pic_ctx);
pic_ctx->allocator.release_picture_callback(&pic_ctx->pic,
pic_ctx->allocator.cookie);
dav1d_mem_pool_push(user_data, buf);
}
static void free_plane_buffer(const uint8_t *const data, void *const user_data) {
struct plane_ctx_context *plane_ctx = user_data;
void dav1d_picture_free_itut_t35(const uint8_t *const data, void *const user_data) {
struct itut_t35_ctx_context *itut_t35_ctx = user_data;
plane_ctx->allocator.release_picture_callback(&plane_ctx->pic,
plane_ctx->allocator.cookie);
free(plane_ctx);
for (size_t i = 0; i < itut_t35_ctx->n_itut_t35; i++)
free(itut_t35_ctx->itut_t35[i].payload);
free(itut_t35_ctx->itut_t35);
free(itut_t35_ctx);
}
static int picture_alloc_with_edges(Dav1dContext *const c,
@ -119,13 +116,10 @@ static int picture_alloc_with_edges(Dav1dContext *const c,
const int w, const int h,
Dav1dSequenceHeader *const seq_hdr, Dav1dRef *const seq_hdr_ref,
Dav1dFrameHeader *const frame_hdr, Dav1dRef *const frame_hdr_ref,
Dav1dContentLightLevel *const content_light, Dav1dRef *const content_light_ref,
Dav1dMasteringDisplay *const mastering_display, Dav1dRef *const mastering_display_ref,
Dav1dITUTT35 *const itut_t35, Dav1dRef *const itut_t35_ref,
const int bpc,
const Dav1dDataProps *const props,
Dav1dPicAllocator *const p_allocator,
const size_t extra, void **const extra_ptr)
void **const extra_ptr)
{
if (p->data[0]) {
dav1d_log(c, "Picture already allocated!\n");
@ -133,10 +127,13 @@ static int picture_alloc_with_edges(Dav1dContext *const c,
}
assert(bpc > 0 && bpc <= 16);
struct pic_ctx_context *pic_ctx = malloc(extra + sizeof(struct pic_ctx_context));
if (pic_ctx == NULL)
size_t extra = c->n_fc > 1 ? sizeof(atomic_int) * 2 : 0;
Dav1dMemPoolBuffer *buf = dav1d_mem_pool_pop(c->pic_ctx_pool,
extra + sizeof(struct pic_ctx_context));
if (buf == NULL)
return DAV1D_ERR(ENOMEM);
memset(pic_ctx, 0, sizeof(struct pic_ctx_context));
struct pic_ctx_context *pic_ctx = buf->data;
p->p.w = w;
p->p.h = h;
@ -147,43 +144,13 @@ static int picture_alloc_with_edges(Dav1dContext *const c,
dav1d_data_props_set_defaults(&p->m);
const int res = p_allocator->alloc_picture_callback(p, p_allocator->cookie);
if (res < 0) {
free(pic_ctx);
dav1d_mem_pool_push(c->pic_ctx_pool, buf);
return res;
}
pic_ctx->layout = p->p.layout;
if (!(p->ref = dav1d_ref_wrap(p->data[0], free_buffer, pic_ctx))) {
p_allocator->release_picture_callback(p, p_allocator->cookie);
free(pic_ctx);
dav1d_log(c, "Failed to wrap picture: %s\n", strerror(errno));
return DAV1D_ERR(ENOMEM);
}
struct plane_ctx_context *plane_ctx = malloc(sizeof(struct plane_ctx_context));
if (plane_ctx == NULL){
dav1d_ref_dec(&p->ref);
p_allocator->release_picture_callback(p, p_allocator->cookie);
return DAV1D_ERR(ENOMEM);
}
plane_ctx->allocator = *p_allocator;
plane_ctx->pic = *p;
pic_ctx->plane_ref[0] = dav1d_ref_wrap(p->data[0], free_plane_buffer, plane_ctx);
if (!pic_ctx->plane_ref[0]) {
dav1d_ref_dec(&p->ref);
p_allocator->release_picture_callback(p, p_allocator->cookie);
free(plane_ctx);
dav1d_log(c, "Failed to wrap picture plane: %s\n", strerror(errno));
return DAV1D_ERR(ENOMEM);
}
const int planes = p->p.layout != DAV1D_PIXEL_LAYOUT_I400 ? 3 : 1;
for (int i = 1; i < planes; i++) {
pic_ctx->plane_ref[i] = pic_ctx->plane_ref[0];
dav1d_ref_inc(pic_ctx->plane_ref[i]);
}
pic_ctx->allocator = *p_allocator;
pic_ctx->pic = *p;
p->ref = dav1d_ref_init(&pic_ctx->ref, buf, free_buffer, c->pic_ctx_pool, 0);
p->seq_hdr_ref = seq_hdr_ref;
if (seq_hdr_ref) dav1d_ref_inc(seq_hdr_ref);
@ -191,12 +158,8 @@ static int picture_alloc_with_edges(Dav1dContext *const c,
p->frame_hdr_ref = frame_hdr_ref;
if (frame_hdr_ref) dav1d_ref_inc(frame_hdr_ref);
dav1d_picture_copy_props(p, content_light, content_light_ref,
mastering_display, mastering_display_ref,
itut_t35, itut_t35_ref, props);
if (extra && extra_ptr)
*extra_ptr = &pic_ctx->extra_ptr;
*extra_ptr = &pic_ctx->extra_data;
return 0;
}
@ -204,7 +167,7 @@ static int picture_alloc_with_edges(Dav1dContext *const c,
void dav1d_picture_copy_props(Dav1dPicture *const p,
Dav1dContentLightLevel *const content_light, Dav1dRef *const content_light_ref,
Dav1dMasteringDisplay *const mastering_display, Dav1dRef *const mastering_display_ref,
Dav1dITUTT35 *const itut_t35, Dav1dRef *const itut_t35_ref,
Dav1dITUTT35 *const itut_t35, Dav1dRef *itut_t35_ref, size_t n_itut_t35,
const Dav1dDataProps *const props)
{
dav1d_data_props_copy(&p->m, props);
@ -222,6 +185,7 @@ void dav1d_picture_copy_props(Dav1dPicture *const p,
dav1d_ref_dec(&p->itut_t35_ref);
p->itut_t35_ref = itut_t35_ref;
p->itut_t35 = itut_t35;
p->n_itut_t35 = n_itut_t35;
if (itut_t35_ref) dav1d_ref_inc(itut_t35_ref);
}
@ -229,23 +193,24 @@ int dav1d_thread_picture_alloc(Dav1dContext *const c, Dav1dFrameContext *const f
const int bpc)
{
Dav1dThreadPicture *const p = &f->sr_cur;
const int have_frame_mt = c->n_fc > 1;
const int res =
picture_alloc_with_edges(c, &p->p, f->frame_hdr->width[1], f->frame_hdr->height,
f->seq_hdr, f->seq_hdr_ref,
f->frame_hdr, f->frame_hdr_ref,
c->content_light, c->content_light_ref,
c->mastering_display, c->mastering_display_ref,
c->itut_t35, c->itut_t35_ref,
bpc, &f->tile[0].data.m, &c->allocator,
have_frame_mt ? sizeof(atomic_int) * 2 : 0,
(void **) &p->progress);
if (res) return res;
dav1d_picture_copy_props(&p->p, c->content_light, c->content_light_ref,
c->mastering_display, c->mastering_display_ref,
c->itut_t35, c->itut_t35_ref, c->n_itut_t35,
&f->tile[0].data.m);
// Must be removed from the context after being attached to the frame
dav1d_ref_dec(&c->itut_t35_ref);
c->itut_t35 = NULL;
c->n_itut_t35 = 0;
// Don't clear these flags from c->frame_flags if the frame is not visible.
// This way they will be added to the next visible frame too.
@ -256,7 +221,7 @@ int dav1d_thread_picture_alloc(Dav1dContext *const c, Dav1dFrameContext *const f
p->visible = f->frame_hdr->show_frame;
p->showable = f->frame_hdr->showable_frame;
if (have_frame_mt) {
if (c->n_fc > 1) {
atomic_init(&p->progress[0], 0);
atomic_init(&p->progress[1], 0);
}
@ -266,17 +231,21 @@ int dav1d_thread_picture_alloc(Dav1dContext *const c, Dav1dFrameContext *const f
int dav1d_picture_alloc_copy(Dav1dContext *const c, Dav1dPicture *const dst, const int w,
const Dav1dPicture *const src)
{
struct pic_ctx_context *const pic_ctx = src->ref->user_data;
struct plane_ctx_context *const plane_ctx = pic_ctx->plane_ref[0]->user_data;
Dav1dMemPoolBuffer *const buf = (Dav1dMemPoolBuffer *)src->ref->const_data;
struct pic_ctx_context *const pic_ctx = buf->data;
const int res = picture_alloc_with_edges(c, dst, w, src->p.h,
src->seq_hdr, src->seq_hdr_ref,
src->frame_hdr, src->frame_hdr_ref,
src->content_light, src->content_light_ref,
src->mastering_display, src->mastering_display_ref,
src->itut_t35, src->itut_t35_ref,
src->p.bpc, &src->m, &plane_ctx->allocator,
0, NULL);
return res;
src->p.bpc, &src->m, &pic_ctx->allocator,
NULL);
if (res) return res;
dav1d_picture_copy_props(dst, src->content_light, src->content_light_ref,
src->mastering_display, src->mastering_display_ref,
src->itut_t35, src->itut_t35_ref, src->n_itut_t35,
&src->m);
return 0;
}
void dav1d_picture_ref(Dav1dPicture *const dst, const Dav1dPicture *const src) {

9
third_party/dav1d/src/picture.h поставляемый
Просмотреть файл

@ -101,10 +101,17 @@ int dav1d_default_picture_alloc(Dav1dPicture *p, void *cookie);
void dav1d_default_picture_release(Dav1dPicture *p, void *cookie);
void dav1d_picture_unref_internal(Dav1dPicture *p);
struct itut_t35_ctx_context {
Dav1dITUTT35 *itut_t35;
size_t n_itut_t35;
Dav1dRef ref;
};
void dav1d_picture_free_itut_t35(const uint8_t *data, void *user_data);
void dav1d_picture_copy_props(Dav1dPicture *p,
Dav1dContentLightLevel *content_light, Dav1dRef *content_light_ref,
Dav1dMasteringDisplay *mastering_display, Dav1dRef *mastering_display_ref,
Dav1dITUTT35 *itut_t35, Dav1dRef *itut_t35_ref,
Dav1dITUTT35 *itut_t35, Dav1dRef *itut_t35_ref, size_t n_itut_t35,
const Dav1dDataProps *props);
/**

60
third_party/dav1d/src/recon_tmpl.c поставляемый
Просмотреть файл

@ -770,14 +770,14 @@ static void read_coef_tree(Dav1dTaskContext *const t,
uint8_t cf_ctx;
int eob;
coef *cf;
struct CodedBlockInfo *cbi;
int16_t *cbi;
if (t->frame_thread.pass) {
const int p = t->frame_thread.pass & 1;
assert(ts->frame_thread[p].cf);
cf = ts->frame_thread[p].cf;
ts->frame_thread[p].cf += imin(t_dim->w, 8) * imin(t_dim->h, 8) * 16;
cbi = &f->frame_thread.cbi[t->by * f->b4_stride + t->bx];
cbi = f->frame_thread.cbi[t->by * f->b4_stride + t->bx];
} else {
cf = bitfn(t->cf);
}
@ -800,16 +800,14 @@ static void read_coef_tree(Dav1dTaskContext *const t,
rep_macro(type, txtp_map, 0, mul * txtp); \
txtp_map += 32; \
}
uint8_t *txtp_map = &t->txtp_map[by4 * 32 + bx4];
uint8_t *txtp_map = &t->scratch.txtp_map[by4 * 32 + bx4];
case_set_upto16(txw,,,);
#undef set_ctx
if (t->frame_thread.pass == 1) {
cbi->eob[0] = eob;
cbi->txtp[0] = txtp;
}
if (t->frame_thread.pass == 1)
cbi[0] = eob * (1 << 5) + txtp;
} else {
eob = cbi->eob[0];
txtp = cbi->txtp[0];
eob = cbi[0] >> 5;
txtp = cbi[0] & 0x1f;
}
if (!(t->frame_thread.pass & 1)) {
assert(dst);
@ -874,7 +872,7 @@ void bytefn(dav1d_read_coef_blocks)(Dav1dTaskContext *const t,
for (y = init_y, t->by += init_y; y < sub_h4;
y += t_dim->h, t->by += t_dim->h, y_off++)
{
struct CodedBlockInfo *const cbi =
int16_t (*const cbi)[3] =
&f->frame_thread.cbi[t->by * f->b4_stride];
int x_off = !!init_x;
for (x = init_x, t->bx += init_x; x < sub_w4;
@ -886,14 +884,14 @@ void bytefn(dav1d_read_coef_blocks)(Dav1dTaskContext *const t,
} else {
uint8_t cf_ctx = 0x40;
enum TxfmType txtp;
const int eob = cbi[t->bx].eob[0] =
const int eob =
decode_coefs(t, &t->a->lcoef[bx4 + x],
&t->l.lcoef[by4 + y], b->tx, bs, b, 1,
0, ts->frame_thread[1].cf, &txtp, &cf_ctx);
if (DEBUG_BLOCK_INFO)
printf("Post-y-cf-blk[tx=%d,txtp=%d,eob=%d]: r=%d\n",
b->tx, txtp, eob, ts->msac.rng);
cbi[t->bx].txtp[0] = txtp;
cbi[t->bx][0] = eob * (1 << 5) + txtp;
ts->frame_thread[1].cf += imin(t_dim->w, 8) * imin(t_dim->h, 8) * 16;
#define set_ctx(type, dir, diridx, off, mul, rep_macro) \
rep_macro(type, t->dir lcoef, off, mul * cf_ctx)
@ -919,7 +917,7 @@ void bytefn(dav1d_read_coef_blocks)(Dav1dTaskContext *const t,
for (y = init_y >> ss_ver, t->by += init_y; y < sub_ch4;
y += uv_t_dim->h, t->by += uv_t_dim->h << ss_ver)
{
struct CodedBlockInfo *const cbi =
int16_t (*const cbi)[3] =
&f->frame_thread.cbi[t->by * f->b4_stride];
for (x = init_x >> ss_hor, t->bx += init_x; x < sub_cw4;
x += uv_t_dim->w, t->bx += uv_t_dim->w << ss_hor)
@ -927,9 +925,9 @@ void bytefn(dav1d_read_coef_blocks)(Dav1dTaskContext *const t,
uint8_t cf_ctx = 0x40;
enum TxfmType txtp;
if (!b->intra)
txtp = t->txtp_map[(by4 + (y << ss_ver)) * 32 +
bx4 + (x << ss_hor)];
const int eob = cbi[t->bx].eob[1 + pl] =
txtp = t->scratch.txtp_map[(by4 + (y << ss_ver)) * 32 +
bx4 + (x << ss_hor)];
const int eob =
decode_coefs(t, &t->a->ccoef[pl][cbx4 + x],
&t->l.ccoef[pl][cby4 + y], b->uvtx, bs,
b, b->intra, 1 + pl, ts->frame_thread[1].cf,
@ -938,7 +936,7 @@ void bytefn(dav1d_read_coef_blocks)(Dav1dTaskContext *const t,
printf("Post-uv-cf-blk[pl=%d,tx=%d,"
"txtp=%d,eob=%d]: r=%d\n",
pl, b->uvtx, txtp, eob, ts->msac.rng);
cbi[t->bx].txtp[1 + pl] = txtp;
cbi[t->bx][pl + 1] = eob * (1 << 5) + txtp;
ts->frame_thread[1].cf += uv_t_dim->w * uv_t_dim->h * 16;
#define set_ctx(type, dir, diridx, off, mul, rep_macro) \
rep_macro(type, t->dir ccoef[pl], off, mul * cf_ctx)
@ -1323,10 +1321,10 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTaskContext *const t, const enum BlockSize
const int p = t->frame_thread.pass & 1;
cf = ts->frame_thread[p].cf;
ts->frame_thread[p].cf += imin(t_dim->w, 8) * imin(t_dim->h, 8) * 16;
const struct CodedBlockInfo *const cbi =
&f->frame_thread.cbi[t->by * f->b4_stride + t->bx];
eob = cbi->eob[0];
txtp = cbi->txtp[0];
const int cbi =
f->frame_thread.cbi[t->by * f->b4_stride + t->bx][0];
eob = cbi >> 5;
txtp = cbi & 0x1f;
} else {
uint8_t cf_ctx;
cf = bitfn(t->cf);
@ -1547,10 +1545,10 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTaskContext *const t, const enum BlockSize
const int p = t->frame_thread.pass & 1;
cf = ts->frame_thread[p].cf;
ts->frame_thread[p].cf += uv_t_dim->w * uv_t_dim->h * 16;
const struct CodedBlockInfo *const cbi =
&f->frame_thread.cbi[t->by * f->b4_stride + t->bx];
eob = cbi->eob[pl + 1];
txtp = cbi->txtp[pl + 1];
const int cbi =
f->frame_thread.cbi[t->by * f->b4_stride + t->bx][pl + 1];
eob = cbi >> 5;
txtp = cbi & 0x1f;
} else {
uint8_t cf_ctx;
cf = bitfn(t->cf);
@ -1997,15 +1995,15 @@ int bytefn(dav1d_recon_b_inter)(Dav1dTaskContext *const t, const enum BlockSize
const int p = t->frame_thread.pass & 1;
cf = ts->frame_thread[p].cf;
ts->frame_thread[p].cf += uvtx->w * uvtx->h * 16;
const struct CodedBlockInfo *const cbi =
&f->frame_thread.cbi[t->by * f->b4_stride + t->bx];
eob = cbi->eob[1 + pl];
txtp = cbi->txtp[1 + pl];
const int cbi =
f->frame_thread.cbi[t->by * f->b4_stride + t->bx][pl + 1];
eob = cbi >> 5;
txtp = cbi & 0x1f;
} else {
uint8_t cf_ctx;
cf = bitfn(t->cf);
txtp = t->txtp_map[(by4 + (y << ss_ver)) * 32 +
bx4 + (x << ss_hor)];
txtp = t->scratch.txtp_map[(by4 + (y << ss_ver)) * 32 +
bx4 + (x << ss_hor)];
eob = decode_coefs(t, &t->a->ccoef[pl][cbx4 + x],
&t->l.ccoef[pl][cby4 + y],
b->uvtx, bs, b, 0, 1 + pl,

21
third_party/dav1d/src/ref.c поставляемый
Просмотреть файл

@ -71,23 +71,6 @@ Dav1dRef *dav1d_ref_create_using_pool(Dav1dMemPool *const pool, size_t size) {
return res;
}
Dav1dRef *dav1d_ref_wrap(const uint8_t *const ptr,
void (*free_callback)(const uint8_t *data, void *user_data),
void *const user_data)
{
Dav1dRef *res = malloc(sizeof(Dav1dRef));
if (!res) return NULL;
res->data = NULL;
res->const_data = ptr;
atomic_init(&res->ref_cnt, 1);
res->free_ref = 1;
res->free_callback = free_callback;
res->user_data = user_data;
return res;
}
void dav1d_ref_dec(Dav1dRef **const pref) {
assert(pref != NULL);
@ -101,7 +84,3 @@ void dav1d_ref_dec(Dav1dRef **const pref) {
if (free_ref) free(ref);
}
}
int dav1d_ref_is_writable(Dav1dRef *const ref) {
return atomic_load(&ref->ref_cnt) == 1 && ref->data;
}

21
third_party/dav1d/src/ref.h поставляемый
Просмотреть файл

@ -47,14 +47,27 @@ struct Dav1dRef {
Dav1dRef *dav1d_ref_create(size_t size);
Dav1dRef *dav1d_ref_create_using_pool(Dav1dMemPool *pool, size_t size);
Dav1dRef *dav1d_ref_wrap(const uint8_t *ptr,
void (*free_callback)(const uint8_t *data, void *user_data),
void *user_data);
void dav1d_ref_dec(Dav1dRef **ref);
int dav1d_ref_is_writable(Dav1dRef *ref);
static inline Dav1dRef *dav1d_ref_init(Dav1dRef *const ref, const void *const ptr,
void (*const free_callback)(const uint8_t *data, void *user_data),
void *const user_data, const int free_ref)
{
ref->data = NULL;
ref->const_data = ptr;
atomic_init(&ref->ref_cnt, 1);
ref->free_ref = free_ref;
ref->free_callback = free_callback;
ref->user_data = user_data;
return ref;
}
static inline void dav1d_ref_inc(Dav1dRef *const ref) {
atomic_fetch_add_explicit(&ref->ref_cnt, 1, memory_order_relaxed);
}
static inline int dav1d_ref_is_writable(Dav1dRef *const ref) {
return atomic_load(&ref->ref_cnt) == 1 && ref->data;
}
#endif /* DAV1D_SRC_REF_H */

4
third_party/dav1d/src/thread_task.c поставляемый
Просмотреть файл

@ -327,6 +327,7 @@ int dav1d_task_create_tile_sbrow(Dav1dFrameContext *const f, const int pass,
f->task_thread.pending_tasks.tail->next = &tasks[0];
f->task_thread.pending_tasks.tail = prev_t;
atomic_store(&f->task_thread.pending_tasks.merge, 1);
atomic_store(&f->task_thread.init_done, 1);
pthread_mutex_unlock(&f->task_thread.pending_tasks.lock);
return 0;
@ -730,14 +731,11 @@ void *dav1d_worker_task(void *data) {
dav1d_decode_frame_exit(f, DAV1D_ERR(ENOMEM));
f->n_tile_data = 0;
pthread_cond_signal(&f->task_thread.cond);
atomic_store(&f->task_thread.init_done, 1);
continue;
} else {
pthread_mutex_unlock(&ttd->lock);
}
}
}
atomic_store(&f->task_thread.init_done, 1);
pthread_mutex_lock(&ttd->lock);
} else {
pthread_mutex_lock(&ttd->lock);

2
third_party/dav1d/src/x86/ipred.h поставляемый
Просмотреть файл

@ -83,11 +83,9 @@ static ALWAYS_INLINE void intra_pred_dsp_init_x86(Dav1dIntraPredDSPContext *cons
init_angular_ipred_fn(SMOOTH_PRED, ipred_smooth, ssse3);
init_angular_ipred_fn(SMOOTH_H_PRED, ipred_smooth_h, ssse3);
init_angular_ipred_fn(SMOOTH_V_PRED, ipred_smooth_v, ssse3);
#if BITDEPTH == 8
init_angular_ipred_fn(Z1_PRED, ipred_z1, ssse3);
init_angular_ipred_fn(Z2_PRED, ipred_z2, ssse3);
init_angular_ipred_fn(Z3_PRED, ipred_z3, ssse3);
#endif
init_angular_ipred_fn(FILTER_PRED, ipred_filter, ssse3);
init_cfl_pred_fn(DC_PRED, ipred_cfl, ssse3);

2171
third_party/dav1d/src/x86/ipred16_sse.asm поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

49
third_party/dav1d/src/x86/ipred_sse.asm поставляемый
Просмотреть файл

@ -1579,10 +1579,10 @@ cglobal ipred_z1_8bpc, 3, 7, 8, -16*13, dst, _, tl, w, h, angle, dx
pshufb m0, m1
pshufb m2, m1
movq m3, [base+z_filter_t_w16+angleq*4]
pcmpeqb m1, m0, [base+z_filter_wh16]
pand m1, m2
pcmpgtb m1, m3
pmovmskb r5d, m1
pcmpeqb m0, [base+z_filter_wh16]
pand m0, m2
pcmpgtb m0, m3
pmovmskb r5d, m0
test r5d, r5d
jz .w16_main ; filter_strength == 0
movd m4, [tlq-1]
@ -2007,7 +2007,6 @@ cglobal ipred_z2_8bpc, 4, 7, 8, -16*20, dst, _, tl, w, h, angle, dx
%define m10 [base+pw_512]
%define m11 [rsp+16*16]
%define m12 [rsp+16*17]
%define r8 [rsp+16*6+4*1]
%define r9b byte [rsp+16*18+4*0]
%define r9d dword [rsp+16*18+4*0]
%define r10d dword [rsp+16*18+4*1]
@ -2203,19 +2202,14 @@ cglobal ipred_z2_8bpc, 4, 7, 8, -16*20, dst, _, tl, w, h, angle, dx
pmullw m4, m5
pshuflw m3, m3, q1111
paddw m6, m0
mov r2d, r10d
pshuflw m0, m4, q3333
psubw m4, [rsp+16*15]
movq [rsp+16*6+8*1], m3
movq [rsp+8*1], m0 ; dy*4
%if ARCH_X86_64
mov r8, dstq
%endif
mov r5, dstq
.w4_loop0:
%if ARCH_X86_32
mov r8, dstq
%endif
mova [rsp+16*12], m6
mov r2d, r10d
movq [rsp+8*0], m4
pand m0, m4, m8
psraw m4, 6
@ -2302,14 +2296,14 @@ cglobal ipred_z2_8bpc, 4, 7, 8, -16*20, dst, _, tl, w, h, angle, dx
jge .w4_loop
movddup m5, [rsp+8*3]
.w4_leftonly_loop:
movzx r3d, byte [rsp+8*2+0] ; base_y0
movq m1, [rsp+r3]
movzx r3d, byte [rsp+8*2+2] ; base_y1
movhps m1, [rsp+r3]
movzx r3d, byte [rsp+8*2+4] ; base_y2
movq m2, [rsp+r3]
movzx r3d, byte [rsp+8*2+6] ; base_y3
movhps m2, [rsp+r3]
movzx r2d, byte [rsp+8*2+0] ; base_y0
movq m1, [rsp+r2]
movzx r2d, byte [rsp+8*2+2] ; base_y1
movhps m1, [rsp+r2]
movzx r2d, byte [rsp+8*2+4] ; base_y2
movq m2, [rsp+r2]
movzx r2d, byte [rsp+8*2+6] ; base_y3
movhps m2, [rsp+r2]
psubw m4, m3
pshufb m1, m12
pshufb m2, m12
@ -2318,7 +2312,6 @@ cglobal ipred_z2_8bpc, 4, 7, 8, -16*20, dst, _, tl, w, h, angle, dx
punpckhdq m1, m2
pmaddubsw m0, m5
pmaddubsw m1, m5
movifnidn strideq, stridemp
pmulhrsw m0, m10
pmulhrsw m1, m10
packuswb m0, m1
@ -2337,18 +2330,14 @@ cglobal ipred_z2_8bpc, 4, 7, 8, -16*20, dst, _, tl, w, h, angle, dx
sub r9d, 1<<8
jl .w4_ret
movq m4, [rsp+8*1]
%if ARCH_X86_64
add r8, 4
mov dstq, r8
%else
mov dstq, r8
add dstq, 4
%endif
add r5, 4
mov dstq, r5
paddw m4, [rsp+8*0] ; base_y += 4*dy
movzx r3d, word [rsp+16*15+8*1]
add r10d, r3d
movzx r2d, word [rsp+16*15+8*1]
movddup m6, [rsp+16*15+8*1]
paddw m6, [rsp+16*12] ; base_x += (4 << upsample_above)
add r2d, r10d
mov r10d, r2d
jmp .w4_loop0
.w4_ret:
RET

4
third_party/dav1d/src/x86/itx.h поставляемый
Просмотреть файл

@ -357,6 +357,10 @@ static ALWAYS_INLINE void itx_dsp_init_x86(Dav1dInvTxfmDSPContext *const c, cons
assign_itx2_bpc_fn (R, 32, 16, 10, avx512icl);
assign_itx2_bpc_fn ( , 32, 32, 10, avx512icl);
assign_itx1_bpc_fn (R, 16, 64, 10, avx512icl);
assign_itx1_bpc_fn (R, 32, 64, 10, avx512icl);
assign_itx1_bpc_fn (R, 64, 16, 10, avx512icl);
assign_itx1_bpc_fn (R, 64, 32, 10, avx512icl);
assign_itx1_bpc_fn ( , 64, 64, 10, avx512icl);
}
#endif
#endif

2
third_party/dav1d/src/x86/itx16_avx2.asm поставляемый
Просмотреть файл

@ -98,7 +98,7 @@ clip_18b_max: dd 0x1ffff
clip_20b_min: dd -0x80000
clip_20b_max: dd 0x7ffff
idct64_mul_16bpc:
const idct64_mul_16bpc
dd 4095, 101, 2967, -2824, 3745, 1660, 3822, -1474, 401, 4076, 799, 4017
dd -700, 4036, 2359, 3349, -2191, 3461, 897, 3996, -2598, -3166, -4017, -799
dd 4065, 501, 3229, -2520, 3564, 2019, 3948, -1092, 1931, 3612, 3406, 2276

2007
third_party/dav1d/src/x86/itx16_avx512.asm поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

132
third_party/dav1d/src/x86/itx_avx512.asm поставляемый
Просмотреть файл

@ -3899,6 +3899,47 @@ ALIGN function_align
sar r6d, 8+1
jmp m(inv_txfm_add_dct_dct_32x8_8bpc).dconly3
ALIGN function_align
cglobal_label .main_oddhalf_fast3 ; bottom seven-eights are zero
vpbroadcastd m8, [o(pw_2896x8)]
vpbroadcastd m4, [o(pw_4076x8)]
vpbroadcastd m3, [o(pw_401x8)]
pmulhrsw m8, m0 ; t0
pmulhrsw m4, m14 ; t15a
pmulhrsw m3, m14 ; t8a
punpcklwd m9, m3, m4
punpckhwd m5, m3, m4
mova m2, m10
vpdpwssd m2, m9, [o(pw_m3784_1567)] {bcstd}
mova m1, m10
vpdpwssd m1, m5, [o(pw_m3784_1567)] {bcstd}
mova m6, m10
vpdpwssd m6, m5, [o(pw_1567_3784)] {bcstd}
mova m5, m10
vpdpwssd m5, m9, [o(pw_1567_3784)] {bcstd}
vpbroadcastd m11, [o(pw_2896_2896)]
vpbroadcastd m12, [o(pw_m2896_2896)]
psubsw m21, m8, m4 ; out15
paddsw m0, m8, m4 ; out0
psubsw m14, m8, m3 ; out8
paddsw m7, m8, m3 ; out7
REPX {psrad x, 12}, m2, m1, m6, m5
packssdw m2, m1 ; t9a
packssdw m5, m6 ; t14a
ITX_MULSUB_2W 4, 3, 16, 17, 10, 11, 12 ; t11, t12
psubsw m20, m8, m5 ; out14
paddsw m1, m8, m5 ; out1
psubsw m15, m8, m2 ; out9
paddsw m6, m8, m2 ; out6
ITX_MULSUB_2W 5, 2, 16, 17, 10, 11, 12 ; t10a, t13a
psubsw m18, m8, m3 ; out12
paddsw m3, m8 ; out3
psubsw m17, m8, m4 ; out11
paddsw m4, m8 ; out4
psubsw m19, m8, m2 ; out13
paddsw m2, m8 ; out2
psubsw m16, m8, m5 ; out10
paddsw m5, m8 ; out5
ret
cglobal_label .main_oddhalf_fast2 ; bottom three-quarters are zero
vpbroadcastd m9, [o(pw_2896x8)]
vpbroadcastd m2, [o(pw_4017x8)]
@ -4675,6 +4716,55 @@ cglobal inv_txfm_add_dct_dct_32x32_8bpc, 4, 6, 0, dst, stride, c, eob
or r3d, 32
jmp m(inv_txfm_add_dct_dct_32x8_8bpc).dconly2
ALIGN function_align
cglobal_label .main_oddhalf_fast3 ; bottom seven-eights are zero
vpbroadcastd m21, [o(pw_4091x8)]
vpbroadcastd m8, [o(pw_201x8)]
vpbroadcastd m24, [o(pw_m601x8)]
vpbroadcastd m12, [o(pw_4052x8)]
pmulhrsw m21, m22 ; t31a
pmulhrsw m22, m8 ; t16a
pmulhrsw m24, m23 ; t23a
pmulhrsw m23, m12 ; t24a
punpcklwd m9, m22, m21
punpckhwd m8, m22, m21
mova m15, m10
vpdpwssd m15, m9, [o(pw_m4017_799)] {bcstd}
mova m17, m10
vpdpwssd m17, m8, [o(pw_m4017_799)] {bcstd}
REPX {psrad x, 12}, m15, m17
packssdw m15, m17
mova m17, m10
vpdpwssd m17, m8, [o(pw_799_4017)] {bcstd}
mova m8, m10
vpdpwssd m8, m9, [o(pw_799_4017)] {bcstd}
REPX {psrad x, 12}, m17, m8
packssdw m8, m17
punpcklwd m9, m24, m23
punpckhwd m16, m24, m23
mova m20, m10
vpdpwssd m20, m9, [o(pw_m3406_m2276)] {bcstd}
mova m17, m10
vpdpwssd m17, m16, [o(pw_m3406_m2276)] {bcstd}
REPX {psrad x, 12}, m20, m17
packssdw m20, m17
mova m17, m10
vpdpwssd m17, m16, [o(pw_m2276_3406)] {bcstd}
mova m16, m10
vpdpwssd m16, m9, [o(pw_m2276_3406)] {bcstd}
REPX {psrad x, 12}, m17, m16
packssdw m16, m17
mova m17, m21
mova m27, m15
mova m25, m20
mova m29, m8
mova m18, m22
mova m14, m24
mova m28, m16
mova m26, m23
jmp .main4
cglobal_label .main_oddhalf_fast2 ; bottom three-quarters are zero
vpbroadcastd m21, [o(pw_4091x8)]
vpbroadcastd m8, [o(pw_201x8)]
@ -4768,8 +4858,6 @@ cglobal_label .main_oddhalf
ITX_MULSUB_2W 25, 18, 9, 17, 10, m4017, 799 ; t18a, t29a
ITX_MULSUB_2W 29, 26, 9, 17, 10, 3406, 2276 ; t21a, t26a
ITX_MULSUB_2W 20, 16, 9, 17, 10, m2276, 3406 ; t22a, t25a
vpbroadcastd m12, [o(pw_m3784_1567)]
vpbroadcastd m11, [o(pw_1567_3784)]
psubsw m17, m21, m27 ; t28a
paddsw m21, m27 ; t31a
psubsw m27, m15, m25 ; t18
@ -4786,6 +4874,9 @@ cglobal_label .main_oddhalf
psubsw m16, m26 ; t26
psubsw m26, m23, m19 ; t27a
paddsw m23, m19 ; t24a
.main4:
vpbroadcastd m12, [o(pw_m3784_1567)]
vpbroadcastd m11, [o(pw_1567_3784)]
ITX_MULSUB_2W 29, 27, 9, 19, 10, 11, 12 ; t18a, t29a
ITX_MULSUB_2W 17, 18, 9, 19, 10, 11, 12 ; t19, t28
vpbroadcastd m11, [o(pw_m1567_m3784)]
@ -6090,7 +6181,33 @@ cglobal inv_txfm_add_dct_dct_32x64_8bpc, 4, 7, 0, dst, stride, c, eob
sar r6d, 8+1
jmp m(inv_txfm_add_dct_dct_32x8_8bpc).dconly3
ALIGN function_align ; bottom three-quarters are zero
.main_part1_fast:
cglobal_label .main_part1_fast2
vpbroadcastd m7, [o(idct64_mul+4*0)]
vpbroadcastd m8, [o(idct64_mul+4*1)]
pmulhrsw m7, m0 ; t63a
pmulhrsw m0, m8 ; t32a
punpcklwd m4, m0, m7
punpckhwd m6, m0, m7
mova m1, m10
vpdpwssd m1, m4, [o(idct64_mul+4*9)] {bcstd}
mova m9, m10
vpdpwssd m9, m6, [o(idct64_mul+4*9)] {bcstd}
REPX {psrad x, 12}, m1, m9
packssdw m1, m9
mova m9, m10
vpdpwssd m9, m6, [o(idct64_mul+4*8)] {bcstd}
mova m6, m10
vpdpwssd m6, m4, [o(idct64_mul+4*8)] {bcstd}
REPX {psrad x, 12}, m9, m6
packssdw m6, m9
mova m4, m0
mova m3, m7
mova m5, m1
mova m2, m6
jmp .main_part1c
cglobal_label .main_part1_fast
vpbroadcastd m1, [o(idct64_mul+4*0)]
vpbroadcastd m8, [o(idct64_mul+4*1)]
vpbroadcastd m2, [o(idct64_mul+4*6)]
@ -6104,7 +6221,7 @@ ALIGN function_align ; bottom three-quarters are zero
mova m6, m3
mova m5, m2
jmp .main_part1b
.main_part1:
cglobal_label .main_part1
; idct64 steps 1-5:
; in1/31/17/15 -> t32a/33/34a/35/60/61a/62/63a
; in7/25/23/ 9 -> t56a/57/58a/59/36/37a/38/39a
@ -6140,8 +6257,6 @@ ALIGN function_align ; bottom three-quarters are zero
ITX_MULSUB_2W 1, 8, 4, 9, 10, 11, 12 ; t33a, t62a
vpbroadcastd m11, [o(idct64_mul+4*10)]
ITX_MULSUB_2W 2, 6, 4, 9, 10, 12, 11 ; t34a, t61a
vpbroadcastd m11, [o(idct64_mul+4*11)]
vpbroadcastd m12, [o(idct64_mul+4*12)]
psubsw m4, m0, m3 ; t35a
paddsw m0, m3 ; t32a
psubsw m3, m7, m5 ; t60a
@ -6150,6 +6265,9 @@ ALIGN function_align ; bottom three-quarters are zero
paddsw m1, m2 ; t33
psubsw m2, m8, m6 ; t61
paddsw m6, m8 ; t62
.main_part1c:
vpbroadcastd m11, [o(idct64_mul+4*11)]
vpbroadcastd m12, [o(idct64_mul+4*12)]
add r5, 4*13
ITX_MULSUB_2W 3, 4, 8, 9, 10, 11, 12 ; t35, t60
ITX_MULSUB_2W 2, 5, 8, 9, 10, 11, 12 ; t34a, t61a
@ -6163,7 +6281,7 @@ ALIGN function_align ; bottom three-quarters are zero
mova [r4+64*5], m5
add r4, 64*8
ret
.main_part2:
cglobal_label .main_part2
vpbroadcastd m11, [o(pw_1567_3784 -16*13)]
vpbroadcastd m12, [o(pw_m3784_1567 -16*13)]
lea r6, [r4+64*7]

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

@ -144,7 +144,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
if (!frame_size) continue;
if (!have_seq_hdr) {
Dav1dSequenceHeader seq = { 0 };
Dav1dSequenceHeader seq;
int err = dav1d_parse_sequence_header(&seq, ptr, frame_size);
// skip frames until we see a sequence header
if (err != 0) {