ref: 0eafb6f5abc61a8c08cd27c649c935b40f25fe70
parent: 0e3c21979b5e2e6e7e49968b1377e38220c58774
author: Janne Grunau <[email protected]>
date: Fri Nov 23 16:07:17 EST 2018
API/scalable: add operating point Dav1dSetting Refs #188, adds a corrosponding dav1d CLI option and skips not required temporal and spatial layers based on the selected operating point.
--- a/include/dav1d/dav1d.h
+++ b/include/dav1d/dav1d.h
@@ -46,6 +46,7 @@
int n_tile_threads;
Dav1dPicAllocator allocator;
int apply_grain;
+ int operating_point; ///< select an operating point for scalable AV1 bitstreams (0 - 31)
} Dav1dSettings;
/**
--- a/src/internal.h
+++ b/src/internal.h
@@ -116,6 +116,8 @@
Dav1dPicAllocator allocator;
int apply_grain;
+ int operating_point;
+ unsigned operating_point_idc;
};
struct Dav1dFrameContext {
--- a/src/lib.c
+++ b/src/lib.c
@@ -62,6 +62,7 @@
s->allocator.cookie = NULL;
s->allocator.alloc_picture_callback = default_picture_allocator;
s->allocator.release_picture_callback = default_picture_release;
+ s->operating_point = 0;
}
int dav1d_open(Dav1dContext **const c_out,
@@ -80,6 +81,8 @@
-EINVAL);
validate_input_or_ret(s->allocator.release_picture_callback != NULL,
-EINVAL);
+ validate_input_or_ret(s->operating_point >= 0 &&
+ s->operating_point <= 31, -EINVAL);
Dav1dContext *const c = *c_out = dav1d_alloc_aligned(sizeof(*c), 32);
if (!c) goto error;
@@ -87,6 +90,7 @@
c->allocator = s->allocator;
c->apply_grain = s->apply_grain;
+ c->operating_point = s->operating_point;
c->n_fc = s->n_frame_threads;
c->fc = dav1d_alloc_aligned(sizeof(*c->fc) * s->n_frame_threads, 32);
if (!c->fc) goto error;
--- a/src/obu.c
+++ b/src/obu.c
@@ -126,6 +126,10 @@
op->initial_display_delay = dav1d_get_bits(gb, 4) + 1;
}
}
+ if (c->operating_point < hdr->num_operating_points)
+ c->operating_point_idc = hdr->operating_points[c->operating_point].idc;
+ else
+ c->operating_point_idc = hdr->operating_points[0].idc;
#if DEBUG_SEQ_HDR
printf("SEQHDR: post-operating-points: off=%ld\n",
dav1d_get_bits_pos(gb) - init_bit_pos);
@@ -1145,9 +1149,11 @@
const int has_extension = dav1d_get_bits(&gb, 1);
const int has_length_field = dav1d_get_bits(&gb, 1);
dav1d_get_bits(&gb, 1); // reserved
+
+ int temporal_id, spatial_id;
if (has_extension) {
- dav1d_get_bits(&gb, 3); // temporal_layer_id
- dav1d_get_bits(&gb, 2); // enhancement_layer_id
+ temporal_id = dav1d_get_bits(&gb, 3);
+ spatial_id = dav1d_get_bits(&gb, 2);
dav1d_get_bits(&gb, 3); // reserved
}
@@ -1184,6 +1190,16 @@
// 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;
+
+ // skip obu not belonging to the selected temporal/spatial layer
+ if (type != OBU_SEQ_HDR && type != OBU_TD &&
+ has_extension && c->operating_point_idc != 0)
+ {
+ 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;
+ }
switch (type) {
case OBU_SEQ_HDR: {
--- a/tools/dav1d_cli_parse.c
+++ b/tools/dav1d_cli_parse.c
@@ -49,6 +49,7 @@
ARG_TILE_THREADS,
ARG_VERIFY,
ARG_FILM_GRAIN,
+ ARG_OPPOINT,
};
static const struct option long_opts[] = {
@@ -64,6 +65,7 @@
{ "tilethreads", 1, NULL, ARG_TILE_THREADS },
{ "verify", 1, NULL, ARG_VERIFY },
{ "filmgrain", 1, NULL, ARG_FILM_GRAIN },
+ { "oppoint", 1, NULL, ARG_OPPOINT },
{ NULL, 0, NULL, 0 },
};
@@ -89,6 +91,7 @@
" --framethreads $num: number of frame threads (default: 1)\n"
" --tilethreads $num: number of tile threads (default: 1)\n"
" --filmgrain enable film grain application (default: 1, except if muxer is md5)\n"
+ " --oppoint $num: select an operating point for scalable AV1 (0 - 32)\n"
" --verify $md5: verify decoded md5. implies --muxer md5, no output\n");
exit(1);
}
@@ -167,6 +170,10 @@
lib_settings->apply_grain =
!!parse_unsigned(optarg, ARG_FILM_GRAIN, argv[0]);
grain_specified = 1;
+ break;
+ case ARG_OPPOINT:
+ lib_settings->operating_point =
+ parse_unsigned(optarg, ARG_OPPOINT, argv[0]);
break;
case 'v':
fprintf(stderr, "%s\n", dav1d_version());