зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b24fc21cd7
Коммит
283fc7df62
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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]
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче