1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/*
2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *
4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Use of this source code is governed by a BSD-style license
5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  that can be found in the LICENSE file in the root of the source
6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  tree. An additional intellectual property rights grant can be found
7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  in the file PATENTS.  All contributing project authors may
8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  be found in the AUTHORS file in the root of the source tree.
9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */
10474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org#include <assert.h>
12474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <stdio.h>
13474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <stdlib.h>
14474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <stdarg.h>
15474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <string.h>
16474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <limits.h>
17474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
18d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "third_party/libyuv/include/libyuv/scale.h"
19d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
20d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "./args.h"
21d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "./ivfdec.h"
22d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
23474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define VPX_CODEC_DISABLE_COMPAT 1
24d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "./vpx_config.h"
25474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx/vpx_decoder.h"
26411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "vpx_ports/mem_ops.h"
27474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx_ports/vpx_timer.h"
28d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
30474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx/vp8dx.h"
31474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
32474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
33d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "./md5_utils.h"
34474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
35d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "./tools_common.h"
367765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org#if CONFIG_WEBM_IO
37d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "./webmdec.h"
387765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org#endif
39dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "./y4menc.h"
40474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
41474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const char *exec_name;
42474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
43d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstruct VpxDecInputContext {
44d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  struct VpxInputContext *vpx_input_ctx;
45d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  struct WebmInputContext *webm_ctx;
46d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org};
47d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
485dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.orgstatic const arg_def_t looparg = ARG_DEF(NULL, "loops", 1,
495dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org                                          "Number of times to decode the file");
50474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1,
516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                          "Codec to use");
52474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0,
536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                          "Output raw YV12 frames");
54474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0,
556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                          "Output raw I420 frames");
56474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0,
576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                           "Flip the chroma planes in the output");
58474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t noblitarg = ARG_DEF(NULL, "noblit", 0,
596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                           "Don't process the decoded frames");
60474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t progressarg = ARG_DEF(NULL, "progress", 0,
616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                             "Show progress after each frame decodes");
62474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t limitarg = ARG_DEF(NULL, "limit", 1,
636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                          "Stop decoding after n frames");
646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic const arg_def_t skiparg = ARG_DEF(NULL, "skip", 1,
656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                         "Skip the first n input frames");
66474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t postprocarg = ARG_DEF(NULL, "postproc", 0,
676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                             "Postprocess decoded frames");
68474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t summaryarg = ARG_DEF(NULL, "summary", 0,
696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                            "Show timing summary");
70474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t outputfile = ARG_DEF("o", "output", 1,
716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                            "Output file name pattern (see below)");
72474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t threadsarg = ARG_DEF("t", "threads", 1,
736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                            "Max threads to use");
74474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t verbosearg = ARG_DEF("v", "verbose", 0,
756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                            "Show version string");
76474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t error_concealment = ARG_DEF(NULL, "error-concealment", 0,
776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                                   "Enable decoder error-concealment");
784b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.orgstatic const arg_def_t scalearg = ARG_DEF("S", "scale", 0,
794b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org                                            "Scale output frames uniformly");
80474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
8176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic const arg_def_t fb_arg =
8276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use");
83474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
84474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0,
85474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                        "Compute the MD5 sum of the decoded frame");
86dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic const arg_def_t *all_args[] = {
886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  &codecarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg,
896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  &progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile,
9076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  &threadsarg, &verbosearg, &scalearg, &fb_arg,
916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  &md5arg,
926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  &error_concealment,
936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  NULL
94474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org};
95474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
96474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if CONFIG_VP8_DECODER
97474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t addnoise_level = ARG_DEF(NULL, "noise-level", 1,
986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                                "Enable VP8 postproc add noise");
99474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t deblock = ARG_DEF(NULL, "deblock", 0,
1006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                         "Enable VP8 deblocking");
101474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t demacroblock_level = ARG_DEF(NULL, "demacroblock-level", 1,
1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                                    "Enable VP8 demacroblocking, w/ level");
103474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t pp_debug_info = ARG_DEF(NULL, "pp-debug-info", 1,
1046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                               "Enable VP8 visible debug info");
105474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t pp_disp_ref_frame = ARG_DEF(NULL, "pp-dbg-ref-frame", 1,
1066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                                   "Display only selected reference frame per macro block");
107474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t pp_disp_mb_modes = ARG_DEF(NULL, "pp-dbg-mb-modes", 1,
1086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                                  "Display only selected macro block modes");
109474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t pp_disp_b_modes = ARG_DEF(NULL, "pp-dbg-b-modes", 1,
1106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                                 "Display only selected block modes");
111474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const arg_def_t pp_disp_mvs = ARG_DEF(NULL, "pp-dbg-mvs", 1,
1126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                             "Draw only selected motion vectors");
113167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgstatic const arg_def_t mfqe = ARG_DEF(NULL, "mfqe", 0,
1146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                      "Enable multiframe quality enhancement");
115474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic const arg_def_t *vp8_pp_args[] = {
1176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  &addnoise_level, &deblock, &demacroblock_level, &pp_debug_info,
1186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  &pp_disp_ref_frame, &pp_disp_mb_modes, &pp_disp_b_modes, &pp_disp_mvs, &mfqe,
1196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  NULL
120474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org};
121474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
122474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
123dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic int vpx_image_scale(vpx_image_t *src, vpx_image_t *dst,
124693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                           FilterModeEnum mode) {
125dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  assert(src->fmt == VPX_IMG_FMT_I420);
126dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  assert(dst->fmt == VPX_IMG_FMT_I420);
127dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  return I420Scale(src->planes[VPX_PLANE_Y], src->stride[VPX_PLANE_Y],
128dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                   src->planes[VPX_PLANE_U], src->stride[VPX_PLANE_U],
129dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                   src->planes[VPX_PLANE_V], src->stride[VPX_PLANE_V],
130dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                   src->d_w, src->d_h,
131dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                   dst->planes[VPX_PLANE_Y], dst->stride[VPX_PLANE_Y],
132dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                   dst->planes[VPX_PLANE_U], dst->stride[VPX_PLANE_U],
133dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                   dst->planes[VPX_PLANE_V], dst->stride[VPX_PLANE_V],
134dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                   dst->d_w, dst->d_h,
135dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                   mode);
136dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
137dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
138d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid usage_exit() {
1396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int i;
140474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  fprintf(stderr, "Usage: %s <options> filename\n\n"
1426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "Options:\n", exec_name);
1436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  arg_show_usage(stderr, all_args);
144474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if CONFIG_VP8_DECODER
1456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  fprintf(stderr, "\nVP8 Postprocessing Options:\n");
1466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  arg_show_usage(stderr, vp8_pp_args);
147474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
1486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  fprintf(stderr,
1496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "\nOutput File Patterns:\n\n"
1506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "  The -o argument specifies the name of the file(s) to "
1516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "write to. If the\n  argument does not include any escape "
1526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "characters, the output will be\n  written to a single file. "
1536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "Otherwise, the filename will be calculated by\n  expanding "
1546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "the following escape characters:\n");
1556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  fprintf(stderr,
1566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "\n\t%%w   - Frame width"
1576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "\n\t%%h   - Frame height"
1586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "\n\t%%<n> - Frame number, zero padded to <n> places (1..9)"
1596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "\n\n  Pattern arguments are only supported in conjunction "
1606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "with the --yv12 and\n  --i420 options. If the -o option is "
1616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "not specified, the output will be\n  directed to stdout.\n"
1626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org         );
1636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  fprintf(stderr, "\nIncluded decoders:\n\n");
1646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
16576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < get_vpx_decoder_count(); ++i) {
16676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
1676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "    %-6s - %s\n",
16876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org            decoder->name, vpx_codec_iface_name(decoder->interface()));
16976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
1706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  exit(EXIT_FAILURE);
172474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
173474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
174dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic int raw_read_frame(FILE *infile, uint8_t **buffer,
175dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                          size_t *bytes_read, size_t *buffer_size) {
176d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  char raw_hdr[RAW_FRAME_HDR_SZ];
177dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  size_t frame_size = 0;
178474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
179dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (fread(raw_hdr, RAW_FRAME_HDR_SZ, 1, infile) != 1) {
180dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (!feof(infile))
181dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      warn("Failed to read RAW frame size\n");
182dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  } else {
18376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const size_t kCorruptFrameThreshold = 256 * 1024 * 1024;
18476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const size_t kFrameTooSmallThreshold = 256 * 1024;
185dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    frame_size = mem_get_le32(raw_hdr);
186474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
187dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (frame_size > kCorruptFrameThreshold) {
188dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      warn("Read invalid frame size (%u)\n", (unsigned int)frame_size);
189dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      frame_size = 0;
190dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
1916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
192dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (frame_size < kFrameTooSmallThreshold) {
193dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      warn("Warning: Read invalid frame size (%u) - not a raw file?\n",
194dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org           (unsigned int)frame_size);
1956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
196474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
197dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (frame_size > *buffer_size) {
198dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      uint8_t *new_buf = realloc(*buffer, 2 * frame_size);
199dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      if (new_buf) {
200dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        *buffer = new_buf;
201dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        *buffer_size = 2 * frame_size;
202dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      } else {
203dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        warn("Failed to allocate compressed data buffer\n");
204dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        frame_size = 0;
205d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
206474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
207dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
208474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
209dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (!feof(infile)) {
210dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (fread(*buffer, 1, frame_size, infile) != frame_size) {
211dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      warn("Failed to read full frame\n");
212dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      return 1;
213dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
214dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    *bytes_read = frame_size;
2156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
2166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
217dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  return 0;
218474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
219474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
220dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic int read_frame(struct VpxDecInputContext *input, uint8_t **buf,
221dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                      size_t *bytes_in_buffer, size_t *buffer_size) {
222dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  switch (input->vpx_input_ctx->file_type) {
22393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if CONFIG_WEBM_IO
224dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    case FILE_TYPE_WEBM:
225dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      return webm_read_frame(input->webm_ctx,
226dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                             buf, bytes_in_buffer, buffer_size);
22793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif
228dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    case FILE_TYPE_RAW:
229dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      return raw_read_frame(input->vpx_input_ctx->file,
230dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                            buf, bytes_in_buffer, buffer_size);
231dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    case FILE_TYPE_IVF:
232dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      return ivf_read_frame(input->vpx_input_ctx->file,
233dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                            buf, bytes_in_buffer, buffer_size);
234dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    default:
235dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      return 1;
2366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
237dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
238474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
239dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic void update_image_md5(const vpx_image_t *img, const int planes[3],
240dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                             MD5Context *md5) {
241dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  int i, y;
242474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
243dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  for (i = 0; i < 3; ++i) {
244dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const int plane = planes[i];
245dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const unsigned char *buf = img->planes[plane];
246dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const int stride = img->stride[plane];
24776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int w = vpx_img_plane_width(img, plane);
24876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int h = vpx_img_plane_height(img, plane);
249474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
250dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    for (y = 0; y < h; ++y) {
251dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      MD5Update(md5, buf, w);
252dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      buf += stride;
253dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
254dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
255dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
256474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
257dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic void write_image_file(const vpx_image_t *img, const int planes[3],
258dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                             FILE *file) {
259dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  int i, y;
260dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
261dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  for (i = 0; i < 3; ++i) {
262dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const int plane = planes[i];
263dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const unsigned char *buf = img->planes[plane];
264dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const int stride = img->stride[plane];
26576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int w = vpx_img_plane_width(img, plane);
26676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    const int h = vpx_img_plane_height(img, plane);
267dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
268dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    for (y = 0; y < h; ++y) {
269dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      fwrite(buf, 1, w, file);
270dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      buf += stride;
271dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
2726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
273474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
274474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
275d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgint file_is_raw(struct VpxInputContext *input) {
276d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  uint8_t buf[32];
2776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int is_raw = 0;
2786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_codec_stream_info_t si;
279474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  si.sz = sizeof(si);
2816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
282d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (fread(buf, 1, 32, input->file) == 32) {
2836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    int i;
2846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
285d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    if (mem_get_le32(buf) < 256 * 1024 * 1024) {
28676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      for (i = 0; i < get_vpx_decoder_count(); ++i) {
28776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
28876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        if (!vpx_codec_peek_stream_info(decoder->interface(),
2896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                        buf + 4, 32 - 4, &si)) {
2906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          is_raw = 1;
29176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org          input->fourcc = decoder->fourcc;
292d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org          input->width = si.w;
293d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org          input->height = si.h;
294d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org          input->framerate.numerator = 30;
295d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org          input->framerate.denominator = 1;
2966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
2976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
298d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
299474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
3006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
301474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
302d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  rewind(input->file);
303d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  return is_raw;
304474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
305474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
306411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgvoid show_progress(int frame_in, int frame_out, uint64_t dx_time) {
307411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  fprintf(stderr,
308411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org          "%d decoded frames/%d showed frames in %"PRId64" us (%.2f fps)\r",
3096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          frame_in, frame_out, dx_time,
310411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org          (double)frame_out * 1000000.0 / (double)dx_time);
311474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
312474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
31376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstruct ExternalFrameBuffer {
31476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  uint8_t* data;
31576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  size_t size;
31676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int in_use;
31776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org};
31876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
31976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstruct ExternalFrameBufferList {
32076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int num_external_frame_buffers;
32176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  struct ExternalFrameBuffer *ext_fb;
32276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org};
32376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
32476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// Callback used by libvpx to request an external frame buffer. |cb_priv|
32576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// Application private data passed into the set function. |min_size| is the
32676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// minimum size in bytes needed to decode the next frame. |fb| pointer to the
32776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// frame buffer.
32876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint get_vp9_frame_buffer(void *cb_priv, size_t min_size,
32976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                         vpx_codec_frame_buffer_t *fb) {
33076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i;
33176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  struct ExternalFrameBufferList *const ext_fb_list =
33276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      (struct ExternalFrameBufferList *)cb_priv;
33376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (ext_fb_list == NULL)
33476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return -1;
33576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
33676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Find a free frame buffer.
33776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < ext_fb_list->num_external_frame_buffers; ++i) {
33876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (!ext_fb_list->ext_fb[i].in_use)
33976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      break;
34076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
34176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
34276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (i == ext_fb_list->num_external_frame_buffers)
34376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return -1;
34476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
34576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (ext_fb_list->ext_fb[i].size < min_size) {
34676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    free(ext_fb_list->ext_fb[i].data);
34776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    ext_fb_list->ext_fb[i].data = (uint8_t *)malloc(min_size);
34876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (!ext_fb_list->ext_fb[i].data)
34976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      return -1;
35076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
35176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    ext_fb_list->ext_fb[i].size = min_size;
35276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
35376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
35476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  fb->data = ext_fb_list->ext_fb[i].data;
35576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  fb->size = ext_fb_list->ext_fb[i].size;
35676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  ext_fb_list->ext_fb[i].in_use = 1;
35776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
35876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Set the frame buffer's private data to point at the external frame buffer.
35976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  fb->priv = &ext_fb_list->ext_fb[i];
36076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return 0;
36176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
36276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
36376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// Callback used by libvpx when there are no references to the frame buffer.
36476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// |cb_priv| user private data passed into the set function. |fb| pointer
36576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// to the frame buffer.
36676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint release_vp9_frame_buffer(void *cb_priv,
36776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                             vpx_codec_frame_buffer_t *fb) {
36876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  struct ExternalFrameBuffer *const ext_fb =
36976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      (struct ExternalFrameBuffer *)fb->priv;
37076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  (void)cb_priv;
37176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  ext_fb->in_use = 0;
37276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return 0;
37376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
37476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
375474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid generate_filename(const char *pattern, char *out, size_t q_len,
376474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                       unsigned int d_w, unsigned int d_h,
3776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                       unsigned int frame_in) {
3786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  const char *p = pattern;
3796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  char *q = out;
3806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
3816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  do {
3826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    char *next_pat = strchr(p, '%');
3836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
3846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (p == next_pat) {
3856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      size_t pat_len;
3866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
3876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      /* parse the pattern */
3886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      q[q_len - 1] = '\0';
3896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      switch (p[1]) {
3906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case 'w':
3916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%d", d_w);
3926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
3936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case 'h':
3946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%d", d_h);
3956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
3966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '1':
3976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%d", frame_in);
3986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
3996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '2':
4006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%02d", frame_in);
4016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
4026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '3':
4036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%03d", frame_in);
4046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
4056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '4':
4066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%04d", frame_in);
4076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
4086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '5':
4096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%05d", frame_in);
4106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
4116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '6':
4126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%06d", frame_in);
4136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
4146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '7':
4156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%07d", frame_in);
4166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
4176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '8':
4186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%08d", frame_in);
4196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
4206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        case '9':
4216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          snprintf(q, q_len - 1, "%09d", frame_in);
4226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          break;
4236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        default:
4246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          die("Unrecognized pattern %%%c\n", p[1]);
4256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
4266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      pat_len = strlen(q);
4286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (pat_len >= q_len - 1)
4296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        die("Output filename too long.\n");
4306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      q += pat_len;
4316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      p += 2;
4326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      q_len -= pat_len;
4336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else {
4346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      size_t copy_len;
4356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      /* copy the next segment */
4376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (!next_pat)
4386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        copy_len = strlen(p);
4396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      else
4406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        copy_len = next_pat - p;
4416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (copy_len >= q_len - 1)
4436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        die("Output filename too long.\n");
4446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      memcpy(q, p, copy_len);
4466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      q[copy_len] = '\0';
4476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      q += copy_len;
4486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      p += copy_len;
4496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      q_len -= copy_len;
4506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
4516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  } while (*p);
452474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
453474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
454dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic int is_single_file(const char *outfile_pattern) {
455dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const char *p = outfile_pattern;
456dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
457dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  do {
458dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    p = strchr(p, '%');
459dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (p && p[1] >= '1' && p[1] <= '9')
460dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      return 0;  // pattern contains sequence number, so it's not unique
461dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (p)
462dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      p++;
463dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  } while (p);
464dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
465dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  return 1;
466dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
467dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
468dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic void print_md5(unsigned char digest[16], const char *filename) {
469dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  int i;
470dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
471dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  for (i = 0; i < 16; ++i)
472dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    printf("%02x", digest[i]);
473dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  printf("  %s\n", filename);
474dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
475dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
476dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic FILE *open_outfile(const char *name) {
477dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (strcmp("-", name) == 0) {
478dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    set_binary_mode(stdout);
479dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    return stdout;
480dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  } else {
481dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    FILE *file = fopen(name, "wb");
482dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (!file)
483dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      fatal("Failed to output file %s", name);
484dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    return file;
485dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
486dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
487474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
4885dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.orgint main_loop(int argc, const char **argv_) {
489d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  vpx_codec_ctx_t       decoder;
4906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  char                  *fn = NULL;
491411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  int                    i;
4926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  uint8_t               *buf = NULL;
493d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  size_t                 bytes_in_buffer = 0, buffer_size = 0;
4946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  FILE                  *infile;
495d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int                    frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
496d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int                    do_md5 = 0, progress = 0;
4976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                    stop_after = 0, postproc = 0, summary = 0, quiet = 1;
4986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                    arg_skip = 0;
4996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                    ec_enabled = 0;
50076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const VpxInterface *interface = NULL;
50176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const VpxInterface *fourcc_interface = NULL;
502411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  uint64_t dx_time = 0;
5036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  struct arg               arg;
5046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  char                   **argv, **argi, **argj;
505dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
5066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                     single_file;
5076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                     use_y4m = 1;
5086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_codec_dec_cfg_t     cfg = {0};
509474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if CONFIG_VP8_DECODER
5106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vp8_postproc_cfg_t      vp8_pp_cfg = {0};
5116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                     vp8_dbg_color_ref_frame = 0;
5126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                     vp8_dbg_color_mb_modes = 0;
5136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                     vp8_dbg_color_b_modes = 0;
5146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                     vp8_dbg_display_mv = 0;
515474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
5166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                     frames_corrupted = 0;
5176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int                     dec_flags = 0;
5184b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org  int                     do_scale = 0;
5194b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org  vpx_image_t             *scaled_img = NULL;
52010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  int                     frame_avail, got_data;
52176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int                     num_external_frame_buffers = 0;
52276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  struct ExternalFrameBufferList ext_fb_list = {0};
523dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
524dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const char *outfile_pattern = NULL;
525dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  char outfile_name[PATH_MAX] = {0};
526dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  FILE *outfile = NULL;
527dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
528dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  MD5Context md5_ctx;
529dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  unsigned char md5_digest[16];
530d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
531d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  struct VpxDecInputContext input = {0};
532d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  struct VpxInputContext vpx_input_ctx = {0};
5337765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org#if CONFIG_WEBM_IO
534d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  struct WebmInputContext webm_ctx = {0};
535d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  input.webm_ctx = &webm_ctx;
5367765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org#endif
5377765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  input.vpx_input_ctx = &vpx_input_ctx;
5386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Parse command line */
5406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  exec_name = argv_[0];
5416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  argv = argv_dup(argc - 1, argv_ + 1);
5426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
5446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    memset(&arg, 0, sizeof(arg));
5456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    arg.argv_step = 1;
5466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (arg_match(&arg, &codecarg, argi)) {
54876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      interface = get_vpx_decoder_by_name(arg.val);
54976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (!interface)
55076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
5515dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org    } else if (arg_match(&arg, &looparg, argi)) {
5525dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org      // no-op
5536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &outputfile, argi))
5546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      outfile_pattern = arg.val;
5556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &use_yv12, argi)) {
5566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      use_y4m = 0;
5576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      flipuv = 1;
5586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &use_i420, argi)) {
5596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      use_y4m = 0;
5606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      flipuv = 0;
5616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &flipuvarg, argi))
5626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      flipuv = 1;
5636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &noblitarg, argi))
5646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      noblit = 1;
5656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &progressarg, argi))
5666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      progress = 1;
5676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &limitarg, argi))
5686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      stop_after = arg_parse_uint(&arg);
5696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &skiparg, argi))
5706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      arg_skip = arg_parse_uint(&arg);
5716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &postprocarg, argi))
5726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      postproc = 1;
5736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &md5arg, argi))
5746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      do_md5 = 1;
5756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &summaryarg, argi))
5766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      summary = 1;
5776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &threadsarg, argi))
5786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      cfg.threads = arg_parse_uint(&arg);
5796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &verbosearg, argi))
5806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      quiet = 0;
5814b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org    else if (arg_match(&arg, &scalearg, argi))
5824b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org      do_scale = 1;
58376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    else if (arg_match(&arg, &fb_arg, argi))
58476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      num_external_frame_buffers = arg_parse_uint(&arg);
585474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
586474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if CONFIG_VP8_DECODER
5876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else if (arg_match(&arg, &addnoise_level, argi)) {
5886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      postproc = 1;
5896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE;
5906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      vp8_pp_cfg.noise_level = arg_parse_uint(&arg);
5916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &demacroblock_level, argi)) {
5926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      postproc = 1;
5936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK;
5946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg);
5956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &deblock, argi)) {
5966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      postproc = 1;
5976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      vp8_pp_cfg.post_proc_flag |= VP8_DEBLOCK;
5986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &mfqe, argi)) {
5996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      postproc = 1;
6006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      vp8_pp_cfg.post_proc_flag |= VP8_MFQE;
6016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &pp_debug_info, argi)) {
6026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      unsigned int level = arg_parse_uint(&arg);
6036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      postproc = 1;
6056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      vp8_pp_cfg.post_proc_flag &= ~0x7;
6066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (level)
6086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        vp8_pp_cfg.post_proc_flag |= level;
6096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &pp_disp_ref_frame, argi)) {
6106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      unsigned int flags = arg_parse_int(&arg);
6116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (flags) {
6126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        postproc = 1;
6136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        vp8_dbg_color_ref_frame = flags;
6146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
6156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &pp_disp_mb_modes, argi)) {
6166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      unsigned int flags = arg_parse_int(&arg);
6176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (flags) {
6186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        postproc = 1;
6196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        vp8_dbg_color_mb_modes = flags;
6206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
6216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &pp_disp_b_modes, argi)) {
6226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      unsigned int flags = arg_parse_int(&arg);
6236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (flags) {
6246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        postproc = 1;
6256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        vp8_dbg_color_b_modes = flags;
6266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
6276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &pp_disp_mvs, argi)) {
6286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      unsigned int flags = arg_parse_int(&arg);
6296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (flags) {
6306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        postproc = 1;
6316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        vp8_dbg_display_mv = flags;
6326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
6336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else if (arg_match(&arg, &error_concealment, argi)) {
6346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ec_enabled = 1;
6356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
636474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
637474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
6386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    else
6396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      argj++;
6406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
641474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
6426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Check for unrecognized options */
6436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  for (argi = argv; *argi; argi++)
6446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
6456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      die("Error: Unrecognized option %s\n", *argi);
646474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
6476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Handle non-option arguments */
6486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  fn = argv[0];
649474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
6506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!fn)
6516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    usage_exit();
652474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
6536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Open file */
6546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);
655474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
6566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!infile) {
657dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    fprintf(stderr, "Failed to open file '%s'", strcmp(fn, "-") ? fn : "stdin");
6586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
6596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
660474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if CONFIG_OS_SUPPORT
6616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Make sure we don't dump to the terminal, unless forced to with -o - */
6626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) {
6636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr,
6646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            "Not dumping raw video to your terminal. Use '-o -' to "
6656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            "override.\n");
6666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
6676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
668474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
669d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  input.vpx_input_ctx->file = infile;
670d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (file_is_ivf(input.vpx_input_ctx))
671d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    input.vpx_input_ctx->file_type = FILE_TYPE_IVF;
67293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if CONFIG_WEBM_IO
673d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx))
674d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    input.vpx_input_ctx->file_type = FILE_TYPE_WEBM;
67593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif
676d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  else if (file_is_raw(input.vpx_input_ctx))
677d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    input.vpx_input_ctx->file_type = FILE_TYPE_RAW;
6786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  else {
6796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "Unrecognized input file type.\n");
68093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if !CONFIG_WEBM_IO
68193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    fprintf(stderr, "vpxdec was built without WebM container support.\n");
68293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif
6836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
6846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
6856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
687dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  single_file = is_single_file(outfile_pattern);
6886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
689dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (!noblit && single_file) {
690dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
691d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                      vpx_input_ctx.width, vpx_input_ctx.height, 0);
692dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (do_md5)
693dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      MD5Init(&md5_ctx);
694dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    else
695dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      outfile = open_outfile(outfile_name);
6966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
6976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (use_y4m && !noblit) {
6996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (!single_file) {
7006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      fprintf(stderr, "YUV4MPEG2 not supported with output patterns,"
7016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org              " try --i420 or --yv12.\n");
7026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      return EXIT_FAILURE;
703474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
704474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
70593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if CONFIG_WEBM_IO
706dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) {
707d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) {
7086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        fprintf(stderr, "Failed to guess framerate -- error parsing "
7096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "webm file?\n");
7106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        return EXIT_FAILURE;
7116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
712dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
71393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif
7146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
71676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc);
71776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (interface && fourcc_interface && interface != fourcc_interface)
71876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    warn("Header indicates codec: %s\n", fourcc_interface->name);
71976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  else
72076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    interface = fourcc_interface;
7216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
72276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (!interface)
72376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    interface = get_vpx_decoder_by_index(0);
724474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
7256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
7266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org              (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0);
72776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (vpx_codec_dec_init(&decoder, interface->interface(), &cfg, dec_flags)) {
72876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    fprintf(stderr, "Failed to initialize decoder: %s\n",
72976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org            vpx_codec_error(&decoder));
7306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
7316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
732474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
7336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!quiet)
7346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "%s\n", decoder.name);
735474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
7366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#if CONFIG_VP8_DECODER
737474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
7386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (vp8_pp_cfg.post_proc_flag
7396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      && vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) {
7406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "Failed to configure postproc: %s\n", vpx_codec_error(&decoder));
7416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
7426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (vp8_dbg_color_ref_frame
7456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_REF_FRAME, vp8_dbg_color_ref_frame)) {
7466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "Failed to configure reference block visualizer: %s\n", vpx_codec_error(&decoder));
7476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
7486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (vp8_dbg_color_mb_modes
7516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_MB_MODES, vp8_dbg_color_mb_modes)) {
7526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "Failed to configure macro block visualizer: %s\n", vpx_codec_error(&decoder));
7536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
7546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (vp8_dbg_color_b_modes
7576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_B_MODES, vp8_dbg_color_b_modes)) {
7586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "Failed to configure block visualizer: %s\n", vpx_codec_error(&decoder));
7596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
7606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (vp8_dbg_display_mv
7636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      && vpx_codec_control(&decoder, VP8_SET_DBG_DISPLAY_MV, vp8_dbg_display_mv)) {
7646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "Failed to configure motion vector visualizer: %s\n", vpx_codec_error(&decoder));
7656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
7666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#endif
768474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
769474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
770d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (arg_skip)
771d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
7726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  while (arg_skip) {
773d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size))
7746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
7756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    arg_skip--;
7766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
777474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
77876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (num_external_frame_buffers > 0) {
77976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
78076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
78176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
78276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (vpx_codec_set_frame_buffer_functions(
78376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org            &decoder, get_vp9_frame_buffer, release_vp9_frame_buffer,
78476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org            &ext_fb_list)) {
78576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
78676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org              vpx_codec_error(&decoder));
78776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      return EXIT_FAILURE;
78876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
78976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
79076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
79110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  frame_avail = 1;
79210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  got_data = 0;
79310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
7946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Decode file */
79510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  while (frame_avail || got_data) {
7966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vpx_codec_iter_t  iter = NULL;
7976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vpx_image_t    *img;
7986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    struct vpx_usec_timer timer;
7996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    int                   corrupted;
800474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
80110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    frame_avail = 0;
80210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    if (!stop_after || frame_in < stop_after) {
803d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
80410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org        frame_avail = 1;
80510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org        frame_in++;
806474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
80710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org        vpx_usec_timer_start(&timer);
808474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
809411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        if (vpx_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer,
810411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org                             NULL, 0)) {
81110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org          const char *detail = vpx_codec_error_detail(&decoder);
812d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org          warn("Failed to decode frame %d: %s",
813d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org               frame_in, vpx_codec_error(&decoder));
814474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
81510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org          if (detail)
816d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org            warn("Additional information: %s", detail);
81710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org          goto fail;
81810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org        }
81910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
82010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org        vpx_usec_timer_mark(&timer);
821411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        dx_time += vpx_usec_timer_elapsed(&timer);
82210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org      }
82310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    }
82410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
82510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    vpx_usec_timer_start(&timer);
82610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
82710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    got_data = 0;
82810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    if ((img = vpx_codec_get_frame(&decoder, &iter))) {
82910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org      ++frame_out;
83010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org      got_data = 1;
831474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
832474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
8336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vpx_usec_timer_mark(&timer);
8346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);
835474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
8366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
837d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder));
8386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      goto fail;
839474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
8406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    frames_corrupted += corrupted;
841474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
8426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (progress)
8436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      show_progress(frame_in, frame_out, dx_time);
844474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
845dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (!noblit && img) {
846dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      const int PLANES_YUV[] = {VPX_PLANE_Y, VPX_PLANE_U, VPX_PLANE_V};
847dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      const int PLANES_YVU[] = {VPX_PLANE_Y, VPX_PLANE_V, VPX_PLANE_U};
848dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;
84910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
8504b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org      if (do_scale) {
851dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        if (frame_out == 1) {
852dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          // If the output frames are to be scaled to a fixed display size then
853dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          // use the width and height specified in the container. If either of
854dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          // these is set to 0, use the display size set in the first frame
855dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          // header. If that is unavailable, use the raw decoded size of the
856dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          // first decoded frame.
857dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          int display_width = vpx_input_ctx.width;
858dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          int display_height = vpx_input_ctx.height;
859dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          if (!display_width || !display_height) {
860dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            int display_size[2];
861dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE,
862dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                                  display_size)) {
863dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org              // As last resort use size of first frame as display size.
864dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org              display_width = img->d_w;
865dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org              display_height = img->d_h;
866dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            } else {
867dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org              display_width = display_size[0];
868dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org              display_height = display_size[1];
869dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            }
870d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org          }
871dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, display_width,
872dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                                     display_height, 16);
8734b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org        }
874dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
875dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
876dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          vpx_image_scale(img, scaled_img, kFilterBox);
8774b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org          img = scaled_img;
8784b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org        }
8794b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org      }
8806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
881dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      if (single_file) {
882dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        if (use_y4m) {
883dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          char buf[Y4M_BUFFER_SIZE] = {0};
884dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          size_t len = 0;
885dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          if (frame_out == 1) {
886dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            // Y4M file header
887dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            len = y4m_write_file_header(buf, sizeof(buf),
888dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                                        vpx_input_ctx.width,
889dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                                        vpx_input_ctx.height,
890dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                                        &vpx_input_ctx.framerate, img->fmt);
891dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            if (do_md5) {
892411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org              MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
893dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            } else {
894dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org              fputs(buf, outfile);
895dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            }
896dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          }
8976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
898dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          // Y4M frame header
899dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          len = y4m_write_frame_header(buf, sizeof(buf));
900dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          if (do_md5) {
901411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org            MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
902dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          } else {
903dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org            fputs(buf, outfile);
904dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          }
905474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
906474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
907dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        if (do_md5) {
908dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          update_image_md5(img, planes, &md5_ctx);
909dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        } else {
910dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          write_image_file(img, planes, outfile);
911dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        }
912dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      } else {
913dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        generate_filename(outfile_pattern, outfile_name, PATH_MAX,
914dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                          img->d_w, img->d_h, frame_in);
915dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        if (do_md5) {
916dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          MD5Init(&md5_ctx);
917dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          update_image_md5(img, planes, &md5_ctx);
918dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          MD5Final(md5_digest, &md5_ctx);
919dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          print_md5(md5_digest, outfile_name);
920dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        } else {
921dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          outfile = open_outfile(outfile_name);
922dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          write_image_file(img, planes, outfile);
923dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          fclose(outfile);
9246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
9256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
926474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
927474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
9286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (stop_after && frame_in >= stop_after)
9296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
9306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
9316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
9326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (summary || progress) {
9336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    show_progress(frame_in, frame_out, dx_time);
9346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "\n");
9356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
9366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
9376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (frames_corrupted)
9386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);
939474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
940474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgfail:
941474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
9426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (vpx_codec_destroy(&decoder)) {
943d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    fprintf(stderr, "Failed to destroy decoder: %s\n",
944d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org            vpx_codec_error(&decoder));
9456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return EXIT_FAILURE;
9466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
947474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
948dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (!noblit && single_file) {
949dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (do_md5) {
950dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      MD5Final(md5_digest, &md5_ctx);
951dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      print_md5(md5_digest, outfile_name);
952dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    } else {
953dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      fclose(outfile);
954dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
955dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
956474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
95793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if CONFIG_WEBM_IO
958d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM)
959d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    webm_free(input.webm_ctx);
96093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif
96193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
96293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (input.vpx_input_ctx->file_type != FILE_TYPE_WEBM)
9636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    free(buf);
964d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
965d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (scaled_img) vpx_img_free(scaled_img);
966d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
96776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
96876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    free(ext_fb_list.ext_fb[i].data);
96976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
97076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  free(ext_fb_list.ext_fb);
97176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
9726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  fclose(infile);
9736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  free(argv);
974474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
9756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS;
976474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
9775dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org
9785dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.orgint main(int argc, const char **argv_) {
9795dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  unsigned int loops = 1, i;
9805dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  char **argv, **argi, **argj;
9815dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  struct arg arg;
9825dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  int error = 0;
9835dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org
9845dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  argv = argv_dup(argc - 1, argv_ + 1);
9855dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
9865dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org    memset(&arg, 0, sizeof(arg));
9875dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org    arg.argv_step = 1;
9885dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org
9895dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org    if (arg_match(&arg, &looparg, argi)) {
9905dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org      loops = arg_parse_uint(&arg);
9915dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org      break;
9925dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org    }
9935dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  }
9945dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  free(argv);
9955dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  for (i = 0; !error && i < loops; i++)
9965dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org    error = main_loop(argc, argv_);
9975dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org  return error;
9985dd56c20f0694054af94fd6a5062eb0233d5cce6fgalligan@chromium.org}
999