mirror of
https://code.videolan.org/videolan/dav1d
synced 2026-06-11 04:03:05 +00:00
add --inloopfilters to enable/disable postfilters dynamically
(To be used alongside --filmgrain.) Addresses part of #310.
This commit is contained in:
+13
-1
@@ -58,6 +58,16 @@ typedef struct Dav1dLogger {
|
||||
void (*callback)(void *cookie, const char *format, va_list ap);
|
||||
} Dav1dLogger;
|
||||
|
||||
enum Dav1dInloopFilterType {
|
||||
DAV1D_INLOOPFILTER_NONE = 0,
|
||||
DAV1D_INLOOPFILTER_DEBLOCK = 1 << 0,
|
||||
DAV1D_INLOOPFILTER_CDEF = 1 << 1,
|
||||
DAV1D_INLOOPFILTER_RESTORATION = 1 << 2,
|
||||
DAV1D_INLOOPFILTER_ALL = DAV1D_INLOOPFILTER_DEBLOCK |
|
||||
DAV1D_INLOOPFILTER_CDEF |
|
||||
DAV1D_INLOOPFILTER_RESTORATION,
|
||||
};
|
||||
|
||||
typedef struct Dav1dSettings {
|
||||
int n_threads; ///< number of threads (0 = number of logical cores in host system, default 0)
|
||||
int max_frame_delay; ///< Set to 1 for low-latency decoding (0 = ceil(sqrt(n_threads)), default 0)
|
||||
@@ -74,7 +84,9 @@ typedef struct Dav1dSettings {
|
||||
///< to all visible frames. Because of show-existing-frame, this
|
||||
///< means some frames may appear twice (once when coded,
|
||||
///< once when shown, default 0)
|
||||
uint8_t reserved[24]; ///< reserved for future use
|
||||
enum Dav1dInloopFilterType inloop_filters; ///< postfilters to enable during decoding (default
|
||||
///< DAV1D_INLOOPFILTER_ALL)
|
||||
uint8_t reserved[20]; ///< reserved for future use
|
||||
} Dav1dSettings;
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ project('dav1d', ['c'],
|
||||
'b_ndebug=if-release'],
|
||||
meson_version: '>= 0.49.0')
|
||||
|
||||
dav1d_soname_version = '6.3.0'
|
||||
dav1d_soname_version = '6.4.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]
|
||||
|
||||
@@ -158,6 +158,7 @@ struct Dav1dContext {
|
||||
unsigned frame_size_limit;
|
||||
int strict_std_compliance;
|
||||
int output_invisible_frames;
|
||||
enum Dav1dInloopFilterType inloop_filters;
|
||||
int drain;
|
||||
enum PictureFlags frame_flags;
|
||||
enum Dav1dEventFlags event_flags;
|
||||
|
||||
@@ -76,6 +76,7 @@ COLD void dav1d_default_settings(Dav1dSettings *const s) {
|
||||
s->frame_size_limit = 0;
|
||||
s->strict_std_compliance = 0;
|
||||
s->output_invisible_frames = 0;
|
||||
s->inloop_filters = DAV1D_INLOOPFILTER_ALL;
|
||||
}
|
||||
|
||||
static void close_internal(Dav1dContext **const c_out, int flush);
|
||||
@@ -131,6 +132,7 @@ COLD int dav1d_open(Dav1dContext **const c_out, const Dav1dSettings *const s) {
|
||||
c->frame_size_limit = s->frame_size_limit;
|
||||
c->strict_std_compliance = s->strict_std_compliance;
|
||||
c->output_invisible_frames = s->output_invisible_frames;
|
||||
c->inloop_filters = s->inloop_filters;
|
||||
|
||||
if (dav1d_mem_pool_init(&c->seq_hdr_pool) ||
|
||||
dav1d_mem_pool_init(&c->frame_hdr_pool) ||
|
||||
|
||||
+12
-4
@@ -2046,6 +2046,11 @@ int bytefn(dav1d_recon_b_inter)(Dav1dTaskContext *const t, const enum BlockSize
|
||||
}
|
||||
|
||||
void bytefn(dav1d_filter_sbrow_deblock_cols)(Dav1dFrameContext *const f, const int sby) {
|
||||
if (!(f->c->inloop_filters & DAV1D_INLOOPFILTER_DEBLOCK) ||
|
||||
(!f->frame_hdr->loopfilter.level_y[0] && !f->frame_hdr->loopfilter.level_y[1]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
const int y = sby * f->sb_step * 4;
|
||||
const int ss_ver = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
|
||||
pixel *const p[3] = {
|
||||
@@ -2054,9 +2059,8 @@ void bytefn(dav1d_filter_sbrow_deblock_cols)(Dav1dFrameContext *const f, const i
|
||||
f->lf.p[2] + (y * PXSTRIDE(f->cur.stride[1]) >> ss_ver)
|
||||
};
|
||||
Av1Filter *mask = f->lf.mask + (sby >> !f->seq_hdr->sb128) * f->sb128w;
|
||||
if (f->frame_hdr->loopfilter.level_y[0] || f->frame_hdr->loopfilter.level_y[1])
|
||||
bytefn(dav1d_loopfilter_sbrow_cols)(f, p, mask, sby,
|
||||
f->lf.start_of_tile_row[sby]);
|
||||
bytefn(dav1d_loopfilter_sbrow_cols)(f, p, mask, sby,
|
||||
f->lf.start_of_tile_row[sby]);
|
||||
}
|
||||
|
||||
void bytefn(dav1d_filter_sbrow_deblock_rows)(Dav1dFrameContext *const f, const int sby) {
|
||||
@@ -2068,7 +2072,9 @@ void bytefn(dav1d_filter_sbrow_deblock_rows)(Dav1dFrameContext *const f, const i
|
||||
f->lf.p[2] + (y * PXSTRIDE(f->cur.stride[1]) >> ss_ver)
|
||||
};
|
||||
Av1Filter *mask = f->lf.mask + (sby >> !f->seq_hdr->sb128) * f->sb128w;
|
||||
if (f->frame_hdr->loopfilter.level_y[0] || f->frame_hdr->loopfilter.level_y[1]) {
|
||||
if (f->c->inloop_filters & DAV1D_INLOOPFILTER_DEBLOCK &&
|
||||
(f->frame_hdr->loopfilter.level_y[0] || f->frame_hdr->loopfilter.level_y[1]))
|
||||
{
|
||||
bytefn(dav1d_loopfilter_sbrow_rows)(f, p, mask, sby);
|
||||
}
|
||||
if (f->seq_hdr->cdef || f->lf.restore_planes) {
|
||||
@@ -2079,6 +2085,7 @@ void bytefn(dav1d_filter_sbrow_deblock_rows)(Dav1dFrameContext *const f, const i
|
||||
|
||||
void bytefn(dav1d_filter_sbrow_cdef)(Dav1dTaskContext *const tc, const int sby) {
|
||||
const Dav1dFrameContext *const f = tc->f;
|
||||
if (!(f->c->inloop_filters & DAV1D_INLOOPFILTER_CDEF)) return;
|
||||
const int sbsz = f->sb_step;
|
||||
const int y = sby * sbsz * 4;
|
||||
const int ss_ver = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
|
||||
@@ -2140,6 +2147,7 @@ void bytefn(dav1d_filter_sbrow_resize)(Dav1dFrameContext *const f, const int sby
|
||||
}
|
||||
|
||||
void bytefn(dav1d_filter_sbrow_lr)(Dav1dFrameContext *const f, const int sby) {
|
||||
if (!(f->c->inloop_filters & DAV1D_INLOOPFILTER_RESTORATION)) return;
|
||||
const int y = sby * f->sb_step * 4;
|
||||
const int ss_ver = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
|
||||
pixel *const sr_p[3] = {
|
||||
|
||||
+21
-1
@@ -61,6 +61,7 @@ enum {
|
||||
ARG_CPU_MASK,
|
||||
ARG_NEG_STRIDE,
|
||||
ARG_OUTPUT_INVISIBLE,
|
||||
ARG_INLOOP_FILTERS,
|
||||
};
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
@@ -86,6 +87,7 @@ static const struct option long_opts[] = {
|
||||
{ "cpumask", 1, NULL, ARG_CPU_MASK },
|
||||
{ "negstride", 0, NULL, ARG_NEG_STRIDE },
|
||||
{ "outputinvisible", 1, NULL, ARG_OUTPUT_INVISIBLE },
|
||||
{ "inloopfilters", 1, NULL, ARG_INLOOP_FILTERS },
|
||||
{ NULL, 0, NULL, 0 },
|
||||
};
|
||||
|
||||
@@ -142,7 +144,8 @@ static void usage(const char *const app, const char *const reason, ...) {
|
||||
" --cpumask $mask: restrict permitted CPU instruction sets (0" ALLOWED_CPU_MASKS "; default: -1)\n"
|
||||
" --negstride: use negative picture strides\n"
|
||||
" this is mostly meant as a developer option\n"
|
||||
" --outputinvisible $num: whether to output invisible (alt-ref) frames (default: 0)\n");
|
||||
" --outputinvisible $num: whether to output invisible (alt-ref) frames (default: 0)\n"
|
||||
" --inloopfilters $str: which in-loop filters to enable (none, (no)deblock, (no)cdef, (no)restoration or all; default: all)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -221,6 +224,18 @@ static const EnumParseTable cpu_mask_tbl[] = {
|
||||
{ "none", 0 },
|
||||
};
|
||||
|
||||
static const EnumParseTable inloop_filters_tbl[] = {
|
||||
{ "none", DAV1D_INLOOPFILTER_NONE },
|
||||
{ "deblock", DAV1D_INLOOPFILTER_DEBLOCK },
|
||||
{ "nodeblock", DAV1D_INLOOPFILTER_ALL - DAV1D_INLOOPFILTER_DEBLOCK },
|
||||
{ "cdef", DAV1D_INLOOPFILTER_CDEF },
|
||||
{ "nocdef", DAV1D_INLOOPFILTER_ALL - DAV1D_INLOOPFILTER_CDEF },
|
||||
{ "restoration", DAV1D_INLOOPFILTER_RESTORATION },
|
||||
{ "norestoration", DAV1D_INLOOPFILTER_ALL - DAV1D_INLOOPFILTER_RESTORATION },
|
||||
{ "all", DAV1D_INLOOPFILTER_ALL },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(n) (sizeof(n)/sizeof(*(n)))
|
||||
|
||||
static unsigned parse_enum(char *optarg, const EnumParseTable *const tbl,
|
||||
@@ -362,6 +377,11 @@ void parse(const int argc, char *const *const argv,
|
||||
lib_settings->output_invisible_frames =
|
||||
!!parse_unsigned(optarg, ARG_OUTPUT_INVISIBLE, argv[0]);
|
||||
break;
|
||||
case ARG_INLOOP_FILTERS:
|
||||
lib_settings->inloop_filters =
|
||||
parse_enum(optarg, inloop_filters_tbl,
|
||||
ARRAY_SIZE(inloop_filters_tbl),ARG_INLOOP_FILTERS, argv[0]);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0], NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user