summaryrefslogtreecommitdiff
path: root/vpxdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'vpxdec.c')
-rw-r--r--vpxdec.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/vpxdec.c b/vpxdec.c
index 1b9bfd302..91d8faf01 100644
--- a/vpxdec.c
+++ b/vpxdec.c
@@ -89,6 +89,10 @@ static const arg_def_t error_concealment = ARG_DEF(NULL, "error-concealment", 0,
"Enable decoder error-concealment");
static const arg_def_t scalearg = ARG_DEF("S", "scale", 0,
"Scale output frames uniformly");
+static const arg_def_t fb_arg =
+ ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use");
+static const arg_def_t fb_lru_arg =
+ ARG_DEF(NULL, "frame-buffers-lru", 1, "Turn on/off frame buffer lru");
#if CONFIG_MD5
@@ -98,7 +102,7 @@ static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0,
static const arg_def_t *all_args[] = {
&codecarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg,
&progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile,
- &threadsarg, &verbosearg, &scalearg,
+ &threadsarg, &verbosearg, &scalearg, &fb_arg, &fb_lru_arg,
#if CONFIG_MD5
&md5arg,
#endif
@@ -314,6 +318,31 @@ void show_progress(int frame_in, int frame_out, unsigned long dx_time) {
(float)frame_out * 1000000.0 / (float)dx_time);
}
+// Called by libvpx if the frame buffer size needs to increase.
+//
+// Parameters:
+// user_priv Data passed into libvpx.
+// new_size Minimum size needed by libvpx to decompress the next frame.
+// fb Pointer to the frame buffer to update.
+//
+// Returns 0 on success. Returns < 0 on failure.
+int realloc_vp9_frame_buffer(void *user_priv, size_t new_size,
+ vpx_codec_frame_buffer_t *fb) {
+ (void)user_priv;
+ if (!fb)
+ return -1;
+
+ free(fb->data);
+ fb->data = (uint8_t*)malloc(new_size);
+ if (!fb->data) {
+ fb->size = 0;
+ return -1;
+ }
+
+ fb->size = new_size;
+ return 0;
+}
+
void generate_filename(const char *pattern, char *out, size_t q_len,
unsigned int d_w, unsigned int d_h,
unsigned int frame_in) {
@@ -428,6 +457,9 @@ int main_loop(int argc, const char **argv_) {
int do_scale = 0;
vpx_image_t *scaled_img = NULL;
int frame_avail, got_data;
+ int num_external_frame_buffers = 0;
+ int fb_lru_cache = 0;
+ vpx_codec_frame_buffer_t *frame_buffers = NULL;
struct VpxDecInputContext input = {0};
struct VpxInputContext vpx_input_ctx = {0};
@@ -487,6 +519,10 @@ int main_loop(int argc, const char **argv_) {
quiet = 0;
else if (arg_match(&arg, &scalearg, argi))
do_scale = 1;
+ else if (arg_match(&arg, &fb_arg, argi))
+ num_external_frame_buffers = arg_parse_uint(&arg);
+ else if (arg_match(&arg, &fb_lru_arg, argi))
+ fb_lru_cache = arg_parse_uint(&arg);
#if CONFIG_VP8_DECODER
else if (arg_match(&arg, &addnoise_level, argi)) {
@@ -704,6 +740,30 @@ int main_loop(int argc, const char **argv_) {
arg_skip--;
}
+ if (num_external_frame_buffers > 0) {
+ // Allocate the frame buffer list, setting all of the values to 0.
+ // Including the size of frame buffers. Libvpx will request the
+ // application to realloc the frame buffer data if the size is too small.
+ frame_buffers = (vpx_codec_frame_buffer_t*)calloc(
+ num_external_frame_buffers, sizeof(*frame_buffers));
+ if (vpx_codec_set_frame_buffers(&decoder, frame_buffers,
+ num_external_frame_buffers,
+ realloc_vp9_frame_buffer,
+ NULL)) {
+ fprintf(stderr, "Failed to configure external frame buffers: %s\n",
+ vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (fb_lru_cache > 0 &&
+ vpx_codec_control(&decoder, VP9D_SET_FRAME_BUFFER_LRU_CACHE,
+ fb_lru_cache)) {
+ fprintf(stderr, "Failed to set frame buffer lru cache: %s\n",
+ vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
+
frame_avail = 1;
got_data = 0;
@@ -878,6 +938,10 @@ fail:
free(buf);
if (scaled_img) vpx_img_free(scaled_img);
+ for (i = 0; i < num_external_frame_buffers; ++i) {
+ free(frame_buffers[i].data);
+ }
+ free(frame_buffers);
fclose(infile);
free(argv);