Commit aae5ac81 authored by Ronald S. Bultje's avatar Ronald S. Bultje
Browse files

Add interface to output invisible (alt-ref) frames

Addresses part of #310.
parent 4504ae3f
......@@ -65,7 +65,8 @@ typedef struct Dav1dSettings {
int operating_point; ///< select an operating point for scalable AV1 bitstreams (0 - 31)
int all_layers; ///< output all spatial layers of a scalable AV1 biststream
unsigned frame_size_limit; ///< maximum frame size, in pixels (0 = unlimited)
uint8_t reserved[32]; ///< reserved for future use
int output_invisible_frames;
uint8_t reserved[28]; ///< reserved for future use
Dav1dPicAllocator allocator;
Dav1dLogger logger;
} Dav1dSettings;
......
......@@ -3196,8 +3196,11 @@ int dav1d_submit_frame(Dav1dContext *const c) {
if (out_delayed->p.data[0]) {
const unsigned progress = atomic_load_explicit(&out_delayed->progress[1],
memory_order_relaxed);
if (out_delayed->visible && progress != FRAME_ERROR)
if ((out_delayed->visible || c->output_invisible_frames) &&
progress != FRAME_ERROR)
{
dav1d_picture_ref(&c->out, &out_delayed->p);
}
dav1d_thread_picture_unref(out_delayed);
}
} else {
......@@ -3363,7 +3366,7 @@ int dav1d_submit_frame(Dav1dContext *const c) {
// move f->cur into output queue
if (c->n_fc == 1) {
if (f->frame_hdr->show_frame)
if (f->frame_hdr->show_frame || c->output_invisible_frames)
dav1d_picture_ref(&c->out, &f->sr_cur.p);
} else {
dav1d_thread_picture_ref(out_delayed, &f->sr_cur);
......
......@@ -132,6 +132,7 @@ struct Dav1dContext {
unsigned operating_point_idc;
int all_layers;
unsigned frame_size_limit;
int output_invisible_frames;
int drain;
Dav1dLogger logger;
......
......@@ -75,6 +75,7 @@ COLD void dav1d_default_settings(Dav1dSettings *const s) {
s->operating_point = 0;
s->all_layers = 1; // just until the tests are adjusted
s->frame_size_limit = 0;
s->output_invisible_frames = 0;
}
static void close_internal(Dav1dContext **const c_out, int flush);
......@@ -122,6 +123,7 @@ COLD int dav1d_open(Dav1dContext **const c_out, const Dav1dSettings *const s) {
c->operating_point = s->operating_point;
c->all_layers = s->all_layers;
c->frame_size_limit = s->frame_size_limit;
c->output_invisible_frames = s->output_invisible_frames;
/* On 32-bit systems extremely large frame sizes can cause overflows in
* dav1d_decode_frame() malloc size calculations. Prevent that from occuring
......@@ -359,8 +361,11 @@ static int drain_picture(Dav1dContext *const c, Dav1dPicture *const out) {
const unsigned progress =
atomic_load_explicit(&out_delayed->progress[1],
memory_order_relaxed);
if (out_delayed->visible && progress != FRAME_ERROR)
if ((out_delayed->visible || c->output_invisible_frames) &&
progress != FRAME_ERROR)
{
dav1d_picture_ref(&c->out, &out_delayed->p);
}
dav1d_thread_picture_unref(out_delayed);
if (output_picture_ready(c))
return output_image(c, out, &c->out);
......
......@@ -1517,8 +1517,11 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, int global) {
if (out_delayed->p.data[0]) {
const unsigned progress = atomic_load_explicit(&out_delayed->progress[1],
memory_order_relaxed);
if (out_delayed->visible && progress != FRAME_ERROR)
if ((out_delayed->visible || c->output_invisible_frames) &&
progress != FRAME_ERROR)
{
dav1d_picture_ref(&c->out, &out_delayed->p);
}
dav1d_thread_picture_unref(out_delayed);
}
dav1d_thread_picture_ref(out_delayed,
......
......@@ -57,6 +57,7 @@ enum {
ARG_ALL_LAYERS,
ARG_SIZE_LIMIT,
ARG_CPU_MASK,
ARG_OUTPUT_INVISIBLE,
};
static const struct option long_opts[] = {
......@@ -79,6 +80,7 @@ static const struct option long_opts[] = {
{ "alllayers", 1, NULL, ARG_ALL_LAYERS },
{ "sizelimit", 1, NULL, ARG_SIZE_LIMIT },
{ "cpumask", 1, NULL, ARG_CPU_MASK },
{ "outputinvisible", 1, NULL, ARG_OUTPUT_INVISIBLE },
{ NULL, 0, NULL, 0 },
};
......@@ -120,7 +122,8 @@ static void usage(const char *const app, const char *const reason, ...) {
" --alllayers $num: output all spatial layers of a scalable AV1 bitstream (default: 1)\n"
" --sizelimit $num: stop decoding if the frame size exceeds the specified limit\n"
" --verify $md5: verify decoded md5. implies --muxer md5, no output\n"
" --cpumask $mask: restrict permitted CPU instruction sets (0" ALLOWED_CPU_MASKS "; default: -1)\n");
" --cpumask $mask: restrict permitted CPU instruction sets (0" ALLOWED_CPU_MASKS "; default: -1)\n"
" --outputinvisible $num: whether to output invisible (alt-ref) frames (default: 0)\n");
exit(1);
}
......@@ -324,6 +327,10 @@ void parse(const int argc, char *const *const argv,
dav1d_set_cpu_flags_mask(parse_enum(optarg, cpu_mask_tbl,
ARG_CPU_MASK, argv[0]));
break;
case ARG_OUTPUT_INVISIBLE:
lib_settings->output_invisible_frames =
!!parse_unsigned(optarg, ARG_OUTPUT_INVISIBLE, argv[0]);
break;
default:
usage(argv[0], NULL);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment