Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/videolan/dav1d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanne Grunau <janne-vlc@jannau.net>2018-11-23 23:07:17 +0300
committerJanne Grunau <janne-vlc@jannau.net>2018-11-24 00:01:22 +0300
commit0eafb6f5abc61a8c08cd27c649c935b40f25fe70 (patch)
tree7e33e54eab358366392fe979490e2b1cd744ec15
parent0e3c21979b5e2e6e7e49968b1377e38220c58774 (diff)
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.
-rw-r--r--include/dav1d/dav1d.h1
-rw-r--r--src/internal.h2
-rw-r--r--src/lib.c4
-rw-r--r--src/obu.c20
-rw-r--r--tools/dav1d_cli_parse.c7
5 files changed, 32 insertions, 2 deletions
diff --git a/include/dav1d/dav1d.h b/include/dav1d/dav1d.h
index 5bf7a2b..64b9042 100644
--- a/include/dav1d/dav1d.h
+++ b/include/dav1d/dav1d.h
@@ -46,6 +46,7 @@ typedef struct Dav1dSettings {
int n_tile_threads;
Dav1dPicAllocator allocator;
int apply_grain;
+ int operating_point; ///< select an operating point for scalable AV1 bitstreams (0 - 31)
} Dav1dSettings;
/**
diff --git a/src/internal.h b/src/internal.h
index 9149c12..5332200 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -116,6 +116,8 @@ struct Dav1dContext {
Dav1dPicAllocator allocator;
int apply_grain;
+ int operating_point;
+ unsigned operating_point_idc;
};
struct Dav1dFrameContext {
diff --git a/src/lib.c b/src/lib.c
index 98aa2a1..22fab5e 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -62,6 +62,7 @@ void dav1d_default_settings(Dav1dSettings *const s) {
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 @@ int dav1d_open(Dav1dContext **const c_out,
-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 @@ int dav1d_open(Dav1dContext **const c_out,
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;
diff --git a/src/obu.c b/src/obu.c
index 53469c4..b1091ec 100644
--- a/src/obu.c
+++ b/src/obu.c
@@ -126,6 +126,10 @@ static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
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 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
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
}
@@ -1185,6 +1191,16 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
// 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: {
Av1SequenceHeader hdr, *const hdr_ptr = c->have_seq_hdr ? &hdr : &c->seq_hdr;
diff --git a/tools/dav1d_cli_parse.c b/tools/dav1d_cli_parse.c
index d60ebe8..affd75c 100644
--- a/tools/dav1d_cli_parse.c
+++ b/tools/dav1d_cli_parse.c
@@ -49,6 +49,7 @@ enum {
ARG_TILE_THREADS,
ARG_VERIFY,
ARG_FILM_GRAIN,
+ ARG_OPPOINT,
};
static const struct option long_opts[] = {
@@ -64,6 +65,7 @@ static const struct option long_opts[] = {
{ "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 @@ static void usage(const char *const app, const char *const reason, ...) {
" --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);
}
@@ -168,6 +171,10 @@ void parse(const int argc, char *const *const argv,
!!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());
exit(0);