Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: source/libvpx/vpxdec.c

Issue 168343002: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: libvpx: Pull from upstream Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/libvpx/vpx_scale/yv12config.h ('k') | source/libvpx/vpxenc.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/libvpx/vpxdec.c
===================================================================
--- source/libvpx/vpxdec.c (revision 251189)
+++ source/libvpx/vpxdec.c (working copy)
@@ -37,19 +37,6 @@
static const char *exec_name;
-static const struct {
- char const *name;
- const vpx_codec_iface_t *(*iface)(void);
- uint32_t fourcc;
-} ifaces[] = {
-#if CONFIG_VP8_DECODER
- {"vp8", vpx_codec_vp8_dx, VP8_FOURCC},
-#endif
-#if CONFIG_VP9_DECODER
- {"vp9", vpx_codec_vp9_dx, VP9_FOURCC},
-#endif
-};
-
struct VpxDecInputContext {
struct VpxInputContext *vpx_input_ctx;
struct WebmInputContext *webm_ctx;
@@ -88,6 +75,8 @@
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 md5arg = ARG_DEF(NULL, "md5", 0,
"Compute the MD5 sum of the decoded frame");
@@ -95,7 +84,7 @@
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,
&md5arg,
&error_concealment,
NULL
@@ -170,10 +159,11 @@
);
fprintf(stderr, "\nIncluded decoders:\n\n");
- for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++)
+ for (i = 0; i < get_vpx_decoder_count(); ++i) {
+ const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
fprintf(stderr, " %-6s - %s\n",
- ifaces[i].name,
- vpx_codec_iface_name(ifaces[i].iface()));
+ decoder->name, vpx_codec_iface_name(decoder->interface()));
+ }
exit(EXIT_FAILURE);
}
@@ -187,8 +177,8 @@
if (!feof(infile))
warn("Failed to read RAW frame size\n");
} else {
- const int kCorruptFrameThreshold = 256 * 1024 * 1024;
- const int kFrameTooSmallThreshold = 256 * 1024;
+ const size_t kCorruptFrameThreshold = 256 * 1024 * 1024;
+ const size_t kFrameTooSmallThreshold = 256 * 1024;
frame_size = mem_get_le32(raw_hdr);
if (frame_size > kCorruptFrameThreshold) {
@@ -241,18 +231,6 @@
}
}
-static int get_image_plane_width(int plane, const vpx_image_t *img) {
- return (plane > 0 && img->x_chroma_shift > 0) ?
- (img->d_w + 1) >> img->x_chroma_shift :
- img->d_w;
-}
-
-static int get_image_plane_height(int plane, const vpx_image_t *img) {
- return (plane > 0 && img->y_chroma_shift > 0) ?
- (img->d_h + 1) >> img->y_chroma_shift :
- img->d_h;
-}
-
static void update_image_md5(const vpx_image_t *img, const int planes[3],
MD5Context *md5) {
int i, y;
@@ -261,8 +239,8 @@
const int plane = planes[i];
const unsigned char *buf = img->planes[plane];
const int stride = img->stride[plane];
- const int w = get_image_plane_width(plane, img);
- const int h = get_image_plane_height(plane, img);
+ const int w = vpx_img_plane_width(img, plane);
+ const int h = vpx_img_plane_height(img, plane);
for (y = 0; y < h; ++y) {
MD5Update(md5, buf, w);
@@ -279,8 +257,8 @@
const int plane = planes[i];
const unsigned char *buf = img->planes[plane];
const int stride = img->stride[plane];
- const int w = get_image_plane_width(plane, img);
- const int h = get_image_plane_height(plane, img);
+ const int w = vpx_img_plane_width(img, plane);
+ const int h = vpx_img_plane_height(img, plane);
for (y = 0; y < h; ++y) {
fwrite(buf, 1, w, file);
@@ -300,11 +278,12 @@
int i;
if (mem_get_le32(buf) < 256 * 1024 * 1024) {
- for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) {
- if (!vpx_codec_peek_stream_info(ifaces[i].iface(),
+ for (i = 0; i < get_vpx_decoder_count(); ++i) {
+ const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
+ if (!vpx_codec_peek_stream_info(decoder->interface(),
buf + 4, 32 - 4, &si)) {
is_raw = 1;
- input->fourcc = ifaces[i].fourcc;
+ input->fourcc = decoder->fourcc;
input->width = si.w;
input->height = si.h;
input->framerate.numerator = 30;
@@ -325,6 +304,68 @@
(float)frame_out * 1000000.0 / (float)dx_time);
}
+struct ExternalFrameBuffer {
+ uint8_t* data;
+ size_t size;
+ int in_use;
+};
+
+struct ExternalFrameBufferList {
+ int num_external_frame_buffers;
+ struct ExternalFrameBuffer *ext_fb;
+};
+
+// Callback used by libvpx to request an external frame buffer. |cb_priv|
+// Application private data passed into the set function. |min_size| is the
+// minimum size in bytes needed to decode the next frame. |fb| pointer to the
+// frame buffer.
+int get_vp9_frame_buffer(void *cb_priv, size_t min_size,
+ vpx_codec_frame_buffer_t *fb) {
+ int i;
+ struct ExternalFrameBufferList *const ext_fb_list =
+ (struct ExternalFrameBufferList *)cb_priv;
+ if (ext_fb_list == NULL)
+ return -1;
+
+ // Find a free frame buffer.
+ for (i = 0; i < ext_fb_list->num_external_frame_buffers; ++i) {
+ if (!ext_fb_list->ext_fb[i].in_use)
+ break;
+ }
+
+ if (i == ext_fb_list->num_external_frame_buffers)
+ return -1;
+
+ if (ext_fb_list->ext_fb[i].size < min_size) {
+ free(ext_fb_list->ext_fb[i].data);
+ ext_fb_list->ext_fb[i].data = (uint8_t *)malloc(min_size);
+ if (!ext_fb_list->ext_fb[i].data)
+ return -1;
+
+ ext_fb_list->ext_fb[i].size = min_size;
+ }
+
+ fb->data = ext_fb_list->ext_fb[i].data;
+ fb->size = ext_fb_list->ext_fb[i].size;
+ ext_fb_list->ext_fb[i].in_use = 1;
+
+ // Set the frame buffer's private data to point at the external frame buffer.
+ fb->priv = &ext_fb_list->ext_fb[i];
+ return 0;
+}
+
+// Callback used by libvpx when there are no references to the frame buffer.
+// |cb_priv| user private data passed into the set function. |fb| pointer
+// to the frame buffer.
+int release_vp9_frame_buffer(void *cb_priv,
+ vpx_codec_frame_buffer_t *fb) {
+ struct ExternalFrameBuffer *const ext_fb =
+ (struct ExternalFrameBuffer *)fb->priv;
+ (void)cb_priv;
+ ext_fb->in_use = 0;
+ 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) {
@@ -441,7 +482,6 @@
int main_loop(int argc, const char **argv_) {
vpx_codec_ctx_t decoder;
char *fn = NULL;
- int i;
uint8_t *buf = NULL;
size_t bytes_in_buffer = 0, buffer_size = 0;
FILE *infile;
@@ -450,7 +490,8 @@
int stop_after = 0, postproc = 0, summary = 0, quiet = 1;
int arg_skip = 0;
int ec_enabled = 0;
- vpx_codec_iface_t *iface = NULL;
+ const VpxInterface *interface = NULL;
+ const VpxInterface *fourcc_interface = NULL;
unsigned long dx_time = 0;
struct arg arg;
char **argv, **argi, **argj;
@@ -470,6 +511,8 @@
int do_scale = 0;
vpx_image_t *scaled_img = NULL;
int frame_avail, got_data;
+ int num_external_frame_buffers = 0;
+ struct ExternalFrameBufferList ext_fb_list = {0};
const char *outfile_pattern = NULL;
char outfile_name[PATH_MAX] = {0};
@@ -493,17 +536,9 @@
arg.argv_step = 1;
if (arg_match(&arg, &codecarg, argi)) {
- int j, k = -1;
-
- for (j = 0; j < sizeof(ifaces) / sizeof(ifaces[0]); j++)
- if (!strcmp(ifaces[j].name, arg.val))
- k = j;
-
- if (k >= 0)
- iface = ifaces[k].iface();
- else
- die("Error: Unrecognized argument (%s) to --codec\n",
- arg.val);
+ interface = get_vpx_decoder_by_name(arg.val);
+ if (!interface)
+ die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
} else if (arg_match(&arg, &looparg, argi)) {
// no-op
} else if (arg_match(&arg, &outputfile, argi))
@@ -536,6 +571,8 @@
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);
#if CONFIG_VP8_DECODER
else if (arg_match(&arg, &addnoise_level, argi)) {
@@ -660,24 +697,20 @@
}
}
- /* Try to determine the codec from the fourcc. */
- for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++)
- if (vpx_input_ctx.fourcc == ifaces[i].fourcc) {
- vpx_codec_iface_t *vpx_iface = ifaces[i].iface();
+ fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc);
+ if (interface && fourcc_interface && interface != fourcc_interface)
+ warn("Header indicates codec: %s\n", fourcc_interface->name);
+ else
+ interface = fourcc_interface;
- if (iface && iface != vpx_iface)
- warn("Header indicates codec: %s\n", ifaces[i].name);
- else
- iface = vpx_iface;
+ if (!interface)
+ interface = get_vpx_decoder_by_index(0);
- break;
- }
-
dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
(ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0);
- if (vpx_codec_dec_init(&decoder, iface ? iface : ifaces[0].iface(), &cfg,
- dec_flags)) {
- fprintf(stderr, "Failed to initialize decoder: %s\n", vpx_codec_error(&decoder));
+ if (vpx_codec_dec_init(&decoder, interface->interface(), &cfg, dec_flags)) {
+ fprintf(stderr, "Failed to initialize decoder: %s\n",
+ vpx_codec_error(&decoder));
return EXIT_FAILURE;
}
@@ -726,6 +759,19 @@
arg_skip--;
}
+ if (num_external_frame_buffers > 0) {
+ ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
+ ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
+ num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
+ if (vpx_codec_set_frame_buffer_functions(
+ &decoder, get_vp9_frame_buffer, release_vp9_frame_buffer,
+ &ext_fb_list)) {
+ fprintf(stderr, "Failed to configure external frame buffers: %s\n",
+ vpx_codec_error(&decoder));
+ return EXIT_FAILURE;
+ }
+ }
+
frame_avail = 1;
got_data = 0;
@@ -898,6 +944,11 @@
if (scaled_img) vpx_img_free(scaled_img);
+ for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
+ free(ext_fb_list.ext_fb[i].data);
+ }
+ free(ext_fb_list.ext_fb);
+
fclose(infile);
free(argv);
« no previous file with comments | « source/libvpx/vpx_scale/yv12config.h ('k') | source/libvpx/vpxenc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698