1538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/*
2538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *
4538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  Use of this source code is governed by a BSD-style license
5538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  that can be found in the LICENSE file in the root of the source
6538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  tree. An additional intellectual property rights grant can be found
7538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  in the file PATENTS.  All contributing project authors may
8538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
9538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber */
10538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <assert.h>
127bc9febe8749e98a3812a0dc4380ceae75c29450Johann#include <limits.h>
137bc9febe8749e98a3812a0dc4380ceae75c29450Johann#include <stdarg.h>
14538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <stdio.h>
15538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <stdlib.h>
16538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <string.h>
1779f15823c34ae1e423108295e416213200bb280fAndreas Huber
187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "./vpx_config.h"
197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_LIBYUV
212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "third_party/libyuv/include/libyuv/scale.h"
227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./args.h"
252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./ivfdec.h"
262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
27538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "vpx/vpx_decoder.h"
282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vpx_ports/mem_ops.h"
29538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "vpx_ports/vpx_timer.h"
302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
3168e1c830ade592be74773e249bf94e2bbfb50de7Johann#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
32538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "vpx/vp8dx.h"
33538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./md5_utils.h"
362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./tools_common.h"
38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if CONFIG_WEBM_IO
392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./webmdec.h"
40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./y4menc.h"
42538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
43538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic const char *exec_name;
44538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstruct VpxDecInputContext {
462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  struct VpxInputContext *vpx_input_ctx;
472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  struct WebmInputContext *webm_ctx;
48538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber};
49538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
50df37111358d02836cb29bbcb9c6e4c95dff90a16Johannstatic const arg_def_t help =
51df37111358d02836cb29bbcb9c6e4c95dff90a16Johann    ARG_DEF(NULL, "help", 0, "Show usage options and exit");
527bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t looparg =
537bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "loops", 1, "Number of times to decode the file");
547bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, "Codec to use");
557bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t use_yv12 =
567bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "yv12", 0, "Output raw YV12 frames");
577bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t use_i420 =
587bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "i420", 0, "Output raw I420 frames");
597bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t flipuvarg =
607bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "flipuv", 0, "Flip the chroma planes in the output");
617bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t rawvideo =
627bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "rawvideo", 0, "Output raw YUV frames");
637bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t noblitarg =
647bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "noblit", 0, "Don't process the decoded frames");
657bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t progressarg =
667bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "progress", 0, "Show progress after each frame decodes");
677bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t limitarg =
687bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "limit", 1, "Stop decoding after n frames");
697bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t skiparg =
707bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "skip", 1, "Skip the first n input frames");
717bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t postprocarg =
727bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "postproc", 0, "Postprocess decoded frames");
737bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t summaryarg =
747bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "summary", 0, "Show timing summary");
757bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t outputfile =
767bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF("o", "output", 1, "Output file name pattern (see below)");
777bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t threadsarg =
787bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF("t", "threads", 1, "Max threads to use");
797bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t frameparallelarg =
800a39d0a697ff3603e8c100300fda363658e10b23James Zern    ARG_DEF(NULL, "frame-parallel", 0, "Frame parallel decode (ignored)");
817bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t verbosearg =
827bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF("v", "verbose", 0, "Show version string");
837bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t error_concealment =
847bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "error-concealment", 0, "Enable decoder error-concealment");
857bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t scalearg =
867bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF("S", "scale", 0, "Scale output frames uniformly");
877bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t continuearg =
887bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF("k", "keep-going", 0, "(debug) Continue decoding after error");
897bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t fb_arg =
907bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use");
917bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t md5arg =
927bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "md5", 0, "Compute the MD5 sum of the decoded frame");
937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
947bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t outbitdeptharg =
957bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "output-bit-depth", 1, "Output bit-depth for decoded frames");
967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
977bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t svcdecodingarg = ARG_DEF(
987bc9febe8749e98a3812a0dc4380ceae75c29450Johann    NULL, "svc-decode-layer", 1, "Decode SVC stream up to given spatial layer");
990a39d0a697ff3603e8c100300fda363658e10b23James Zernstatic const arg_def_t framestatsarg =
1000a39d0a697ff3603e8c100300fda363658e10b23James Zern    ARG_DEF(NULL, "framestats", 1, "Output per-frame stats (.csv format)");
1012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic const arg_def_t *all_args[] = {
103df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  &help,           &codecarg,          &use_yv12,
104df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  &use_i420,       &flipuvarg,         &rawvideo,
105df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  &noblitarg,      &progressarg,       &limitarg,
106df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  &skiparg,        &postprocarg,       &summaryarg,
107df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  &outputfile,     &threadsarg,        &frameparallelarg,
108df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  &verbosearg,     &scalearg,          &fb_arg,
109df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  &md5arg,         &error_concealment, &continuearg,
1107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
1117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  &outbitdeptharg,
1127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
113df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  &svcdecodingarg, &framestatsarg,     NULL
114538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber};
115538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
116538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if CONFIG_VP8_DECODER
1177bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t addnoise_level =
1187bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "noise-level", 1, "Enable VP8 postproc add noise");
1197bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t deblock =
1207bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "deblock", 0, "Enable VP8 deblocking");
1217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic const arg_def_t demacroblock_level = ARG_DEF(
1227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    NULL, "demacroblock-level", 1, "Enable VP8 demacroblocking, w/ level");
1237bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t mfqe =
1247bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ARG_DEF(NULL, "mfqe", 0, "Enable multiframe quality enhancement");
1257bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1267bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic const arg_def_t *vp8_pp_args[] = { &addnoise_level, &deblock,
1277bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                          &demacroblock_level, &mfqe, NULL };
128538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
129538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
1307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_LIBYUV
1317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic INLINE int libyuv_scale(vpx_image_t *src, vpx_image_t *dst,
1327bc9febe8749e98a3812a0dc4380ceae75c29450Johann                               FilterModeEnum mode) {
1337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
1347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (src->fmt == VPX_IMG_FMT_I42016) {
1357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    assert(dst->fmt == VPX_IMG_FMT_I42016);
1367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    return I420Scale_16(
1377bc9febe8749e98a3812a0dc4380ceae75c29450Johann        (uint16_t *)src->planes[VPX_PLANE_Y], src->stride[VPX_PLANE_Y] / 2,
1387bc9febe8749e98a3812a0dc4380ceae75c29450Johann        (uint16_t *)src->planes[VPX_PLANE_U], src->stride[VPX_PLANE_U] / 2,
1397bc9febe8749e98a3812a0dc4380ceae75c29450Johann        (uint16_t *)src->planes[VPX_PLANE_V], src->stride[VPX_PLANE_V] / 2,
1407bc9febe8749e98a3812a0dc4380ceae75c29450Johann        src->d_w, src->d_h, (uint16_t *)dst->planes[VPX_PLANE_Y],
1417bc9febe8749e98a3812a0dc4380ceae75c29450Johann        dst->stride[VPX_PLANE_Y] / 2, (uint16_t *)dst->planes[VPX_PLANE_U],
1427bc9febe8749e98a3812a0dc4380ceae75c29450Johann        dst->stride[VPX_PLANE_U] / 2, (uint16_t *)dst->planes[VPX_PLANE_V],
1437bc9febe8749e98a3812a0dc4380ceae75c29450Johann        dst->stride[VPX_PLANE_V] / 2, dst->d_w, dst->d_h, mode);
1447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
1457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
1462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  assert(src->fmt == VPX_IMG_FMT_I420);
1472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  assert(dst->fmt == VPX_IMG_FMT_I420);
1482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  return I420Scale(src->planes[VPX_PLANE_Y], src->stride[VPX_PLANE_Y],
1492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                   src->planes[VPX_PLANE_U], src->stride[VPX_PLANE_U],
1507bc9febe8749e98a3812a0dc4380ceae75c29450Johann                   src->planes[VPX_PLANE_V], src->stride[VPX_PLANE_V], src->d_w,
1517bc9febe8749e98a3812a0dc4380ceae75c29450Johann                   src->d_h, dst->planes[VPX_PLANE_Y], dst->stride[VPX_PLANE_Y],
1522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                   dst->planes[VPX_PLANE_U], dst->stride[VPX_PLANE_U],
1537bc9febe8749e98a3812a0dc4380ceae75c29450Johann                   dst->planes[VPX_PLANE_V], dst->stride[VPX_PLANE_V], dst->d_w,
1547bc9febe8749e98a3812a0dc4380ceae75c29450Johann                   dst->d_h, mode);
1552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
1567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
157df37111358d02836cb29bbcb9c6e4c95dff90a16Johannvoid show_help(FILE *fout, int shorthelp) {
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
159538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
160df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  fprintf(fout, "Usage: %s <options> filename\n\n", exec_name);
161df37111358d02836cb29bbcb9c6e4c95dff90a16Johann
162df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  if (shorthelp) {
163df37111358d02836cb29bbcb9c6e4c95dff90a16Johann    fprintf(fout, "Use --help to see the full list of options.\n");
164df37111358d02836cb29bbcb9c6e4c95dff90a16Johann    return;
165df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  }
166df37111358d02836cb29bbcb9c6e4c95dff90a16Johann
167df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  fprintf(fout, "Options:\n");
168df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  arg_show_usage(fout, all_args);
169538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if CONFIG_VP8_DECODER
170df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  fprintf(fout, "\nVP8 Postprocessing Options:\n");
171df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  arg_show_usage(fout, vp8_pp_args);
172538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
173df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  fprintf(fout,
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "\nOutput File Patterns:\n\n"
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "  The -o argument specifies the name of the file(s) to "
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "write to. If the\n  argument does not include any escape "
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "characters, the output will be\n  written to a single file. "
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "Otherwise, the filename will be calculated by\n  expanding "
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "the following escape characters:\n");
180df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  fprintf(fout,
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "\n\t%%w   - Frame width"
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "\n\t%%h   - Frame height"
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "\n\t%%<n> - Frame number, zero padded to <n> places (1..9)"
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "\n\n  Pattern arguments are only supported in conjunction "
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          "with the --yv12 and\n  --i420 options. If the -o option is "
1867bc9febe8749e98a3812a0dc4380ceae75c29450Johann          "not specified, the output will be\n  directed to stdout.\n");
187df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  fprintf(fout, "\nIncluded decoders:\n\n");
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (i = 0; i < get_vpx_decoder_count(); ++i) {
1902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
191df37111358d02836cb29bbcb9c6e4c95dff90a16Johann    fprintf(fout, "    %-6s - %s\n", decoder->name,
1927bc9febe8749e98a3812a0dc4380ceae75c29450Johann            vpx_codec_iface_name(decoder->codec_interface()));
1932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
194df37111358d02836cb29bbcb9c6e4c95dff90a16Johann}
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
196df37111358d02836cb29bbcb9c6e4c95dff90a16Johannvoid usage_exit(void) {
197df37111358d02836cb29bbcb9c6e4c95dff90a16Johann  show_help(stderr, 1);
198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  exit(EXIT_FAILURE);
199538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
200538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2017bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic int raw_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
2027bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          size_t *buffer_size) {
2032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  char raw_hdr[RAW_FRAME_HDR_SZ];
2042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  size_t frame_size = 0;
205538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (fread(raw_hdr, RAW_FRAME_HDR_SZ, 1, infile) != 1) {
2077bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!feof(infile)) warn("Failed to read RAW frame size\n");
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
2092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const size_t kCorruptFrameThreshold = 256 * 1024 * 1024;
2102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const size_t kFrameTooSmallThreshold = 256 * 1024;
2112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    frame_size = mem_get_le32(raw_hdr);
212538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (frame_size > kCorruptFrameThreshold) {
2142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      warn("Read invalid frame size (%u)\n", (unsigned int)frame_size);
2152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      frame_size = 0;
216538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
217538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (frame_size < kFrameTooSmallThreshold) {
2192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      warn("Warning: Read invalid frame size (%u) - not a raw file?\n",
2202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian           (unsigned int)frame_size);
2212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
222538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (frame_size > *buffer_size) {
2242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      uint8_t *new_buf = realloc(*buffer, 2 * frame_size);
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (new_buf) {
2262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        *buffer = new_buf;
2272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        *buffer_size = 2 * frame_size;
228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
2292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        warn("Failed to allocate compressed data buffer\n");
2302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        frame_size = 0;
231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
232538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
234538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!feof(infile)) {
2362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (fread(*buffer, 1, frame_size, infile) != frame_size) {
2372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      warn("Failed to read full frame\n");
238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return 1;
239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    *bytes_read = frame_size;
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
242538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  return 0;
244538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
245538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic int read_frame(struct VpxDecInputContext *input, uint8_t **buf,
2472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                      size_t *bytes_in_buffer, size_t *buffer_size) {
2482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  switch (input->vpx_input_ctx->file_type) {
2492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#if CONFIG_WEBM_IO
2502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    case FILE_TYPE_WEBM:
25168e1c830ade592be74773e249bf94e2bbfb50de7Johann      return webm_read_frame(input->webm_ctx, buf, bytes_in_buffer);
252538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
2532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    case FILE_TYPE_RAW:
2547bc9febe8749e98a3812a0dc4380ceae75c29450Johann      return raw_read_frame(input->vpx_input_ctx->file, buf, bytes_in_buffer,
2557bc9febe8749e98a3812a0dc4380ceae75c29450Johann                            buffer_size);
2562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    case FILE_TYPE_IVF:
2577bc9febe8749e98a3812a0dc4380ceae75c29450Johann      return ivf_read_frame(input->vpx_input_ctx->file, buf, bytes_in_buffer,
2587bc9febe8749e98a3812a0dc4380ceae75c29450Johann                            buffer_size);
2597bc9febe8749e98a3812a0dc4380ceae75c29450Johann    default: return 1;
260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
261538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
262538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void update_image_md5(const vpx_image_t *img, const int planes[3],
2642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             MD5Context *md5) {
2652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int i, y;
266538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (i = 0; i < 3; ++i) {
2682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int plane = planes[i];
2692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const unsigned char *buf = img->planes[plane];
2702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int stride = img->stride[plane];
2717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    const int w = vpx_img_plane_width(img, plane) *
2727bc9febe8749e98a3812a0dc4380ceae75c29450Johann                  ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
2732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int h = vpx_img_plane_height(img, plane);
274538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    for (y = 0; y < h; ++y) {
2762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      MD5Update(md5, buf, w);
2772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      buf += stride;
2782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
280538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
281538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void write_image_file(const vpx_image_t *img, const int planes[3],
2832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             FILE *file) {
2842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int i, y;
2857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
2867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int bytes_per_sample = ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
2877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#else
2887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int bytes_per_sample = 1;
2897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
290538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (i = 0; i < 3; ++i) {
2922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int plane = planes[i];
2932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const unsigned char *buf = img->planes[plane];
2942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int stride = img->stride[plane];
2952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int w = vpx_img_plane_width(img, plane);
2962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const int h = vpx_img_plane_height(img, plane);
297538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
2982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    for (y = 0; y < h; ++y) {
2997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      fwrite(buf, bytes_per_sample, w, file);
3002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      buf += stride;
3012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
3022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
303538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
304538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
3057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic int file_is_raw(struct VpxInputContext *input) {
3062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  uint8_t buf[32];
307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int is_raw = 0;
308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_codec_stream_info_t si;
309538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  si.sz = sizeof(si);
311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (fread(buf, 1, 32, input->file) == 32) {
313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i;
314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (mem_get_le32(buf) < 256 * 1024 * 1024) {
3162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (i = 0; i < get_vpx_decoder_count(); ++i) {
3172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
3187bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (!vpx_codec_peek_stream_info(decoder->codec_interface(), buf + 4,
3197bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                        32 - 4, &si)) {
320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          is_raw = 1;
3212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          input->fourcc = decoder->fourcc;
3222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          input->width = si.w;
3232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          input->height = si.h;
3242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          input->framerate.numerator = 30;
3252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          input->framerate.denominator = 1;
326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          break;
327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
3282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      }
3292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  rewind(input->file);
333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return is_raw;
334538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
335538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
3367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic void show_progress(int frame_in, int frame_out, uint64_t dx_time) {
3372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  fprintf(stderr,
3387bc9febe8749e98a3812a0dc4380ceae75c29450Johann          "%d decoded frames/%d showed frames in %" PRId64 " us (%.2f fps)\r",
3392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          frame_in, frame_out, dx_time,
3402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          (double)frame_out * 1000000.0 / (double)dx_time);
341538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
342538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
3432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstruct ExternalFrameBuffer {
3447bc9febe8749e98a3812a0dc4380ceae75c29450Johann  uint8_t *data;
3452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  size_t size;
3462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int in_use;
3472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian};
348538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
3492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstruct ExternalFrameBufferList {
3502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int num_external_frame_buffers;
3512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  struct ExternalFrameBuffer *ext_fb;
3522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian};
353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Callback used by libvpx to request an external frame buffer. |cb_priv|
3552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Application private data passed into the set function. |min_size| is the
3562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// minimum size in bytes needed to decode the next frame. |fb| pointer to the
3572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// frame buffer.
3587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic int get_vp9_frame_buffer(void *cb_priv, size_t min_size,
3597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                vpx_codec_frame_buffer_t *fb) {
3602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int i;
3612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  struct ExternalFrameBufferList *const ext_fb_list =
3622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      (struct ExternalFrameBufferList *)cb_priv;
3637bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (ext_fb_list == NULL) return -1;
3642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
3652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  // Find a free frame buffer.
3662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (i = 0; i < ext_fb_list->num_external_frame_buffers; ++i) {
3677bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!ext_fb_list->ext_fb[i].in_use) break;
368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
369538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
3707bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (i == ext_fb_list->num_external_frame_buffers) return -1;
371538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
3722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (ext_fb_list->ext_fb[i].size < min_size) {
3732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    free(ext_fb_list->ext_fb[i].data);
3747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    ext_fb_list->ext_fb[i].data = (uint8_t *)calloc(min_size, sizeof(uint8_t));
3757bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!ext_fb_list->ext_fb[i].data) return -1;
376538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
3772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    ext_fb_list->ext_fb[i].size = min_size;
378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  fb->data = ext_fb_list->ext_fb[i].data;
3812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  fb->size = ext_fb_list->ext_fb[i].size;
3822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  ext_fb_list->ext_fb[i].in_use = 1;
383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  // Set the frame buffer's private data to point at the external frame buffer.
3852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  fb->priv = &ext_fb_list->ext_fb[i];
386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 0;
387538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
388538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
3892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Callback used by libvpx when there are no references to the frame buffer.
3902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// |cb_priv| user private data passed into the set function. |fb| pointer
3912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// to the frame buffer.
3927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic int release_vp9_frame_buffer(void *cb_priv,
3937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                    vpx_codec_frame_buffer_t *fb) {
3942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  struct ExternalFrameBuffer *const ext_fb =
3952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      (struct ExternalFrameBuffer *)fb->priv;
3962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  (void)cb_priv;
3972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  ext_fb->in_use = 0;
3982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  return 0;
399538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
400538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
4017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic void generate_filename(const char *pattern, char *out, size_t q_len,
4027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              unsigned int d_w, unsigned int d_h,
4037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              unsigned int frame_in) {
404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const char *p = pattern;
405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char *q = out;
406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  do {
408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    char *next_pat = strchr(p, '%');
409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (p == next_pat) {
411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      size_t pat_len;
412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* parse the pattern */
414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      q[q_len - 1] = '\0';
415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      switch (p[1]) {
4167bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case 'w': snprintf(q, q_len - 1, "%d", d_w); break;
4177bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case 'h': snprintf(q, q_len - 1, "%d", d_h); break;
4187bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '1': snprintf(q, q_len - 1, "%d", frame_in); break;
4197bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '2': snprintf(q, q_len - 1, "%02d", frame_in); break;
4207bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '3': snprintf(q, q_len - 1, "%03d", frame_in); break;
4217bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '4': snprintf(q, q_len - 1, "%04d", frame_in); break;
4227bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '5': snprintf(q, q_len - 1, "%05d", frame_in); break;
4237bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '6': snprintf(q, q_len - 1, "%06d", frame_in); break;
4247bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '7': snprintf(q, q_len - 1, "%07d", frame_in); break;
4257bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '8': snprintf(q, q_len - 1, "%08d", frame_in); break;
4267bc9febe8749e98a3812a0dc4380ceae75c29450Johann        case '9': snprintf(q, q_len - 1, "%09d", frame_in); break;
4277bc9febe8749e98a3812a0dc4380ceae75c29450Johann        default: die("Unrecognized pattern %%%c\n", p[1]); break;
428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      pat_len = strlen(q);
4317bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (pat_len >= q_len - 1) die("Output filename too long.\n");
432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      q += pat_len;
433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      p += 2;
434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      q_len -= pat_len;
435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      size_t copy_len;
437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* copy the next segment */
439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!next_pat)
440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        copy_len = strlen(p);
441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      else
442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        copy_len = next_pat - p;
443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4447bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (copy_len >= q_len - 1) die("Output filename too long.\n");
445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      memcpy(q, p, copy_len);
447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      q[copy_len] = '\0';
448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      q += copy_len;
449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      p += copy_len;
450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      q_len -= copy_len;
451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } while (*p);
453538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
454538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
4552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic int is_single_file(const char *outfile_pattern) {
4562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const char *p = outfile_pattern;
4572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
4582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  do {
4592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    p = strchr(p, '%');
4602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (p && p[1] >= '1' && p[1] <= '9')
4612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      return 0;  // pattern contains sequence number, so it's not unique
4627bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (p) p++;
4632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  } while (p);
4642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
4652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  return 1;
4662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
4672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
4682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void print_md5(unsigned char digest[16], const char *filename) {
4692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int i;
4702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
4717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < 16; ++i) printf("%02x", digest[i]);
4722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  printf("  %s\n", filename);
4732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
4742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
4752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic FILE *open_outfile(const char *name) {
4762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (strcmp("-", name) == 0) {
4772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    set_binary_mode(stdout);
4782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    return stdout;
4792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  } else {
4802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    FILE *file = fopen(name, "wb");
4817bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!file) fatal("Failed to open output file '%s'", name);
4822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    return file;
4832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
4842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
485538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
4867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
4877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic int img_shifted_realloc_required(const vpx_image_t *img,
4887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                        const vpx_image_t *shifted,
4897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                        vpx_img_fmt_t required_fmt) {
4907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return img->d_w != shifted->d_w || img->d_h != shifted->d_h ||
4917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian         required_fmt != shifted->fmt;
4927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
4937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
4947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic int main_loop(int argc, const char **argv_) {
4967bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_codec_ctx_t decoder;
4977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  char *fn = NULL;
4987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i;
4997bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ret = EXIT_FAILURE;
5007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  uint8_t *buf = NULL;
5017bc9febe8749e98a3812a0dc4380ceae75c29450Johann  size_t bytes_in_buffer = 0, buffer_size = 0;
5027bc9febe8749e98a3812a0dc4380ceae75c29450Johann  FILE *infile;
5037bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
5040a39d0a697ff3603e8c100300fda363658e10b23James Zern  int do_md5 = 0, progress = 0;
5057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int stop_after = 0, postproc = 0, summary = 0, quiet = 1;
5067bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int arg_skip = 0;
5077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ec_enabled = 0;
5087bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int keep_going = 0;
5092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const VpxInterface *interface = NULL;
5102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const VpxInterface *fourcc_interface = NULL;
5112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  uint64_t dx_time = 0;
5127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  struct arg arg;
5137bc9febe8749e98a3812a0dc4380ceae75c29450Johann  char **argv, **argi, **argj;
5147bc9febe8749e98a3812a0dc4380ceae75c29450Johann
5157bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int single_file;
5167bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int use_y4m = 1;
5177bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int opt_yv12 = 0;
5187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int opt_i420 = 0;
5197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_codec_dec_cfg_t cfg = { 0, 0, 0 };
5207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
5217bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned int output_bit_depth = 0;
5227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
5237bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int svc_decoding = 0;
5247bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int svc_spatial_layer = 0;
525538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if CONFIG_VP8_DECODER
5267bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_postproc_cfg_t vp8_pp_cfg = { 0, 0, 0 };
527538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
5287bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int frames_corrupted = 0;
5297bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int dec_flags = 0;
5307bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int do_scale = 0;
5317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_image_t *scaled_img = NULL;
5327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
5337bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_image_t *img_shifted = NULL;
5347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
5357bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int frame_avail, got_data, flush_decoder = 0;
5367bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int num_external_frame_buffers = 0;
5377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  struct ExternalFrameBufferList ext_fb_list = { 0, NULL };
5382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
5392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const char *outfile_pattern = NULL;
5407bc9febe8749e98a3812a0dc4380ceae75c29450Johann  char outfile_name[PATH_MAX] = { 0 };
5412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  FILE *outfile = NULL;
5422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
5430a39d0a697ff3603e8c100300fda363658e10b23James Zern  FILE *framestats_file = NULL;
5440a39d0a697ff3603e8c100300fda363658e10b23James Zern
5452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  MD5Context md5_ctx;
5462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  unsigned char md5_digest[16];
5472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
5487bc9febe8749e98a3812a0dc4380ceae75c29450Johann  struct VpxDecInputContext input = { NULL, NULL };
549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  struct VpxInputContext vpx_input_ctx;
550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if CONFIG_WEBM_IO
5517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  struct WebmInputContext webm_ctx;
5527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  memset(&(webm_ctx), 0, sizeof(webm_ctx));
5532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  input.webm_ctx = &webm_ctx;
554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  input.vpx_input_ctx = &vpx_input_ctx;
556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Parse command line */
558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  exec_name = argv_[0];
559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  argv = argv_dup(argc - 1, argv_ + 1);
560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    memset(&arg, 0, sizeof(arg));
563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    arg.argv_step = 1;
564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
565df37111358d02836cb29bbcb9c6e4c95dff90a16Johann    if (arg_match(&arg, &help, argi)) {
566df37111358d02836cb29bbcb9c6e4c95dff90a16Johann      show_help(stdout, 0);
567df37111358d02836cb29bbcb9c6e4c95dff90a16Johann      exit(EXIT_SUCCESS);
568df37111358d02836cb29bbcb9c6e4c95dff90a16Johann    } else if (arg_match(&arg, &codecarg, argi)) {
5692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      interface = get_vpx_decoder_by_name(arg.val);
5702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      if (!interface)
5712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (arg_match(&arg, &looparg, argi)) {
573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // no-op
574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (arg_match(&arg, &outputfile, argi))
575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      outfile_pattern = arg.val;
576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &use_yv12, argi)) {
577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      use_y4m = 0;
578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      flipuv = 1;
579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      opt_yv12 = 1;
580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (arg_match(&arg, &use_i420, argi)) {
581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      use_y4m = 0;
582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      flipuv = 0;
583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      opt_i420 = 1;
584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    } else if (arg_match(&arg, &rawvideo, argi)) {
585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      use_y4m = 0;
586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (arg_match(&arg, &flipuvarg, argi))
587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      flipuv = 1;
588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &noblitarg, argi))
589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      noblit = 1;
590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &progressarg, argi))
591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      progress = 1;
592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &limitarg, argi))
593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      stop_after = arg_parse_uint(&arg);
594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &skiparg, argi))
595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      arg_skip = arg_parse_uint(&arg);
596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &postprocarg, argi))
597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      postproc = 1;
598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &md5arg, argi))
599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      do_md5 = 1;
600ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &summaryarg, argi))
601ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      summary = 1;
602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &threadsarg, argi))
603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cfg.threads = arg_parse_uint(&arg);
60468e1c830ade592be74773e249bf94e2bbfb50de7Johann#if CONFIG_VP9_DECODER
6050a39d0a697ff3603e8c100300fda363658e10b23James Zern    else if (arg_match(&arg, &frameparallelarg, argi)) {
6060a39d0a697ff3603e8c100300fda363658e10b23James Zern      /* ignored for compatibility */
6070a39d0a697ff3603e8c100300fda363658e10b23James Zern    }
6087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &verbosearg, argi))
610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      quiet = 0;
611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &scalearg, argi))
612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      do_scale = 1;
6132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    else if (arg_match(&arg, &fb_arg, argi))
6142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      num_external_frame_buffers = arg_parse_uint(&arg);
6157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    else if (arg_match(&arg, &continuearg, argi))
6167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      keep_going = 1;
6177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
6187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    else if (arg_match(&arg, &outbitdeptharg, argi)) {
6197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      output_bit_depth = arg_parse_uint(&arg);
6207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
6217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
6227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    else if (arg_match(&arg, &svcdecodingarg, argi)) {
6237bc9febe8749e98a3812a0dc4380ceae75c29450Johann      svc_decoding = 1;
6247bc9febe8749e98a3812a0dc4380ceae75c29450Johann      svc_spatial_layer = arg_parse_uint(&arg);
6250a39d0a697ff3603e8c100300fda363658e10b23James Zern    } else if (arg_match(&arg, &framestatsarg, argi)) {
6260a39d0a697ff3603e8c100300fda363658e10b23James Zern      framestats_file = fopen(arg.val, "w");
6270a39d0a697ff3603e8c100300fda363658e10b23James Zern      if (!framestats_file) {
6280a39d0a697ff3603e8c100300fda363658e10b23James Zern        die("Error: Could not open --framestats file (%s) for writing.\n",
6290a39d0a697ff3603e8c100300fda363658e10b23James Zern            arg.val);
6300a39d0a697ff3603e8c100300fda363658e10b23James Zern      }
6317bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
632538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if CONFIG_VP8_DECODER
633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (arg_match(&arg, &addnoise_level, argi)) {
634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      postproc = 1;
635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE;
636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp8_pp_cfg.noise_level = arg_parse_uint(&arg);
637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (arg_match(&arg, &demacroblock_level, argi)) {
638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      postproc = 1;
639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK;
640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg);
641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (arg_match(&arg, &deblock, argi)) {
642ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      postproc = 1;
643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp8_pp_cfg.post_proc_flag |= VP8_DEBLOCK;
644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (arg_match(&arg, &mfqe, argi)) {
645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      postproc = 1;
646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp8_pp_cfg.post_proc_flag |= VP8_MFQE;
647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (arg_match(&arg, &error_concealment, argi)) {
648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ec_enabled = 1;
649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
6507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_VP8_DECODER
651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else
652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      argj++;
653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
654538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Check for unrecognized options */
656ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (argi = argv; *argi; argi++)
657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      die("Error: Unrecognized option %s\n", *argi);
659538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Handle non-option arguments */
661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  fn = argv[0];
662538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
6637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (!fn) {
6647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    free(argv);
665df37111358d02836cb29bbcb9c6e4c95dff90a16Johann    fprintf(stderr, "No input file specified!\n");
666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    usage_exit();
6677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Open file */
669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);
670538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!infile) {
6727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    fatal("Failed to open input file '%s'", strcmp(fn, "-") ? fn : "stdin");
673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
67479f15823c34ae1e423108295e416213200bb280fAndreas Huber#if CONFIG_OS_SUPPORT
675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Make sure we don't dump to the terminal, unless forced to with -o - */
676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) {
677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    fprintf(stderr,
678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            "Not dumping raw video to your terminal. Use '-o -' to "
679ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            "override.\n");
680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return EXIT_FAILURE;
681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
68279f15823c34ae1e423108295e416213200bb280fAndreas Huber#endif
6832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  input.vpx_input_ctx->file = infile;
6842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (file_is_ivf(input.vpx_input_ctx))
6852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    input.vpx_input_ctx->file_type = FILE_TYPE_IVF;
6862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#if CONFIG_WEBM_IO
6872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx))
6882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    input.vpx_input_ctx->file_type = FILE_TYPE_WEBM;
6892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
6902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  else if (file_is_raw(input.vpx_input_ctx))
6912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    input.vpx_input_ctx->file_type = FILE_TYPE_RAW;
692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else {
693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    fprintf(stderr, "Unrecognized input file type.\n");
6942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#if !CONFIG_WEBM_IO
6952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    fprintf(stderr, "vpxdec was built without WebM container support.\n");
6962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
697ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return EXIT_FAILURE;
698ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
699ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
700ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
7012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  single_file = is_single_file(outfile_pattern);
702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
7032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (!noblit && single_file) {
7042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
7052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                      vpx_input_ctx.width, vpx_input_ctx.height, 0);
7062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (do_md5)
7072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      MD5Init(&md5_ctx);
7082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    else
7092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      outfile = open_outfile(outfile_name);
710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (use_y4m && !noblit) {
713ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!single_file) {
7147bc9febe8749e98a3812a0dc4380ceae75c29450Johann      fprintf(stderr,
7157bc9febe8749e98a3812a0dc4380ceae75c29450Johann              "YUV4MPEG2 not supported with output patterns,"
7167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian              " try --i420 or --yv12 or --rawvideo.\n");
717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return EXIT_FAILURE;
718538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
719538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
7202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#if CONFIG_WEBM_IO
7212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) {
7222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) {
7237bc9febe8749e98a3812a0dc4380ceae75c29450Johann        fprintf(stderr,
7247bc9febe8749e98a3812a0dc4380ceae75c29450Johann                "Failed to guess framerate -- error parsing "
725ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                "webm file?\n");
726538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        return EXIT_FAILURE;
727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
7282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
7292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
7322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc);
7332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (interface && fourcc_interface && interface != fourcc_interface)
7342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    warn("Header indicates codec: %s\n", fourcc_interface->name);
7352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  else
7362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    interface = fourcc_interface;
737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
7387bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!interface) interface = get_vpx_decoder_by_index(0);
739538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
7410a39d0a697ff3603e8c100300fda363658e10b23James Zern              (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0);
7427bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (vpx_codec_dec_init(&decoder, interface->codec_interface(), &cfg,
7437bc9febe8749e98a3812a0dc4380ceae75c29450Johann                         dec_flags)) {
7442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    fprintf(stderr, "Failed to initialize decoder: %s\n",
7452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            vpx_codec_error(&decoder));
7467bc9febe8749e98a3812a0dc4380ceae75c29450Johann    goto fail2;
747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
7487bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (svc_decoding) {
7497bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (vpx_codec_control(&decoder, VP9_DECODE_SVC_SPATIAL_LAYER,
7507bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          svc_spatial_layer)) {
7517bc9febe8749e98a3812a0dc4380ceae75c29450Johann      fprintf(stderr, "Failed to set spatial layer for svc decode: %s\n",
7527bc9febe8749e98a3812a0dc4380ceae75c29450Johann              vpx_codec_error(&decoder));
7537bc9febe8749e98a3812a0dc4380ceae75c29450Johann      goto fail;
7547bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
7557bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
7567bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!quiet) fprintf(stderr, "%s\n", decoder.name);
757538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
758538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if CONFIG_VP8_DECODER
7597bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (vp8_pp_cfg.post_proc_flag &&
7607bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) {
7617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    fprintf(stderr, "Failed to configure postproc: %s\n",
7627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            vpx_codec_error(&decoder));
7637bc9febe8749e98a3812a0dc4380ceae75c29450Johann    goto fail;
764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
765ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
766538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
7677bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (arg_skip) fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
768ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  while (arg_skip) {
7697bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) break;
770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    arg_skip--;
771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
77279f15823c34ae1e423108295e416213200bb280fAndreas Huber
7732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (num_external_frame_buffers > 0) {
7742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
7752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
7762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
7777bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (vpx_codec_set_frame_buffer_functions(&decoder, get_vp9_frame_buffer,
7787bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                             release_vp9_frame_buffer,
7797bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                             &ext_fb_list)) {
7802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
7812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian              vpx_codec_error(&decoder));
7827bc9febe8749e98a3812a0dc4380ceae75c29450Johann      goto fail;
7832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
7842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
7852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
786ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  frame_avail = 1;
787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  got_data = 0;
78879f15823c34ae1e423108295e416213200bb280fAndreas Huber
7890a39d0a697ff3603e8c100300fda363658e10b23James Zern  if (framestats_file) fprintf(framestats_file, "bytes,qp\n");
7900a39d0a697ff3603e8c100300fda363658e10b23James Zern
791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Decode file */
792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  while (frame_avail || got_data) {
7937bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vpx_codec_iter_t iter = NULL;
7947bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vpx_image_t *img;
795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    struct vpx_usec_timer timer;
7967bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int corrupted = 0;
797538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    frame_avail = 0;
799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!stop_after || frame_in < stop_after) {
8002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
801ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frame_avail = 1;
802ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frame_in++;
803538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
804538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        vpx_usec_timer_start(&timer);
805538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
8067bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (vpx_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer, NULL,
8077bc9febe8749e98a3812a0dc4380ceae75c29450Johann                             0)) {
808ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          const char *detail = vpx_codec_error_detail(&decoder);
8097bc9febe8749e98a3812a0dc4380ceae75c29450Johann          warn("Failed to decode frame %d: %s", frame_in,
8107bc9febe8749e98a3812a0dc4380ceae75c29450Johann               vpx_codec_error(&decoder));
8117bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (detail) warn("Additional information: %s", detail);
8127bc9febe8749e98a3812a0dc4380ceae75c29450Johann          corrupted = 1;
8137bc9febe8749e98a3812a0dc4380ceae75c29450Johann          if (!keep_going) goto fail;
814538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
815538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
8160a39d0a697ff3603e8c100300fda363658e10b23James Zern        if (framestats_file) {
8170a39d0a697ff3603e8c100300fda363658e10b23James Zern          int qp;
8180a39d0a697ff3603e8c100300fda363658e10b23James Zern          if (vpx_codec_control(&decoder, VPXD_GET_LAST_QUANTIZER, &qp)) {
8190a39d0a697ff3603e8c100300fda363658e10b23James Zern            warn("Failed VPXD_GET_LAST_QUANTIZER: %s",
8200a39d0a697ff3603e8c100300fda363658e10b23James Zern                 vpx_codec_error(&decoder));
8210a39d0a697ff3603e8c100300fda363658e10b23James Zern            if (!keep_going) goto fail;
8220a39d0a697ff3603e8c100300fda363658e10b23James Zern          }
8230a39d0a697ff3603e8c100300fda363658e10b23James Zern          fprintf(framestats_file, "%d,%d\n", (int)bytes_in_buffer, qp);
8240a39d0a697ff3603e8c100300fda363658e10b23James Zern        }
8250a39d0a697ff3603e8c100300fda363658e10b23James Zern
826538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        vpx_usec_timer_mark(&timer);
8272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        dx_time += vpx_usec_timer_elapsed(&timer);
8287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      } else {
8297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        flush_decoder = 1;
830ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
8317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    } else {
8327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      flush_decoder = 1;
833ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
834538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
835ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_usec_timer_start(&timer);
836538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
8377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    if (flush_decoder) {
8387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      // Flush the decoder in frame parallel decode.
8397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      if (vpx_codec_decode(&decoder, NULL, 0, NULL, 0)) {
8407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        warn("Failed to flush decoder: %s", vpx_codec_error(&decoder));
8417bc9febe8749e98a3812a0dc4380ceae75c29450Johann        corrupted = 1;
8427bc9febe8749e98a3812a0dc4380ceae75c29450Johann        if (!keep_going) goto fail;
8437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      }
8447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
8457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
846ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    got_data = 0;
847ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if ((img = vpx_codec_get_frame(&decoder, &iter))) {
848ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ++frame_out;
849ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      got_data = 1;
850ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
851ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
852ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_usec_timer_mark(&timer);
853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);
854ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8550a39d0a697ff3603e8c100300fda363658e10b23James Zern    if (!corrupted &&
8567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
8572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder));
8587bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (!keep_going) goto fail;
859ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
860ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    frames_corrupted += corrupted;
861ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8627bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (progress) show_progress(frame_in, frame_out, dx_time);
863ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (!noblit && img) {
8657bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const int PLANES_YUV[] = { VPX_PLANE_Y, VPX_PLANE_U, VPX_PLANE_V };
8667bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const int PLANES_YVU[] = { VPX_PLANE_Y, VPX_PLANE_V, VPX_PLANE_U };
8672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;
868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (do_scale) {
8702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        if (frame_out == 1) {
8712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          // If the output frames are to be scaled to a fixed display size then
8722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          // use the width and height specified in the container. If either of
8732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          // these is set to 0, use the display size set in the first frame
8742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          // header. If that is unavailable, use the raw decoded size of the
8752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          // first decoded frame.
876c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann          int render_width = vpx_input_ctx.width;
877c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann          int render_height = vpx_input_ctx.height;
878c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann          if (!render_width || !render_height) {
879c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann            int render_size[2];
8802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE,
881c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann                                  render_size)) {
8822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian              // As last resort use size of first frame as display size.
883c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann              render_width = img->d_w;
884c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann              render_height = img->d_h;
8852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            } else {
886c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann              render_width = render_size[0];
887c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann              render_height = render_size[1];
8882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            }
8892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          }
8907bc9febe8749e98a3812a0dc4380ceae75c29450Johann          scaled_img =
8917bc9febe8749e98a3812a0dc4380ceae75c29450Johann              vpx_img_alloc(NULL, img->fmt, render_width, render_height, 16);
892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian          scaled_img->bit_depth = img->bit_depth;
893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
8942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
8952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if CONFIG_LIBYUV
8977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          libyuv_scale(img, scaled_img, kFilterBox);
898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          img = scaled_img;
899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else
9007bc9febe8749e98a3812a0dc4380ceae75c29450Johann          fprintf(stderr,
9017bc9febe8749e98a3812a0dc4380ceae75c29450Johann                  "Failed  to scale output frame: %s.\n"
902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  "Scaling is disabled in this configuration. "
903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  "To enable scaling, configure with --enable-libyuv\n",
904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  vpx_codec_error(&decoder));
9057bc9febe8749e98a3812a0dc4380ceae75c29450Johann          goto fail;
906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
908ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
9097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
9107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      // Default to codec bit depth if output bit depth not set
911c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann      if (!output_bit_depth && single_file && !do_md5) {
9127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        output_bit_depth = img->bit_depth;
9137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      }
9147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      // Shift up or down if necessary
915c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann      if (output_bit_depth != 0 && output_bit_depth != img->bit_depth) {
9167bc9febe8749e98a3812a0dc4380ceae75c29450Johann        const vpx_img_fmt_t shifted_fmt =
9177bc9febe8749e98a3812a0dc4380ceae75c29450Johann            output_bit_depth == 8
9187bc9febe8749e98a3812a0dc4380ceae75c29450Johann                ? img->fmt ^ (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH)
9197bc9febe8749e98a3812a0dc4380ceae75c29450Johann                : img->fmt | VPX_IMG_FMT_HIGHBITDEPTH;
9207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        if (img_shifted &&
9217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            img_shifted_realloc_required(img, img_shifted, shifted_fmt)) {
9227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          vpx_img_free(img_shifted);
9237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          img_shifted = NULL;
9247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        }
9257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        if (!img_shifted) {
9267bc9febe8749e98a3812a0dc4380ceae75c29450Johann          img_shifted =
9277bc9febe8749e98a3812a0dc4380ceae75c29450Johann              vpx_img_alloc(NULL, shifted_fmt, img->d_w, img->d_h, 16);
9287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          img_shifted->bit_depth = output_bit_depth;
9297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        }
9307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        if (output_bit_depth > img->bit_depth) {
9317bc9febe8749e98a3812a0dc4380ceae75c29450Johann          vpx_img_upshift(img_shifted, img, output_bit_depth - img->bit_depth);
9327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        } else {
9337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          vpx_img_downshift(img_shifted, img,
9347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                            img->bit_depth - output_bit_depth);
9357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        }
9367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        img = img_shifted;
9377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      }
9387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
939ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      if (single_file) {
9412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        if (use_y4m) {
9427bc9febe8749e98a3812a0dc4380ceae75c29450Johann          char buf[Y4M_BUFFER_SIZE] = { 0 };
9432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          size_t len = 0;
9447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          if (img->fmt == VPX_IMG_FMT_I440 || img->fmt == VPX_IMG_FMT_I44016) {
9457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            fprintf(stderr, "Cannot produce y4m output for 440 sampling.\n");
9467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            goto fail;
9477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          }
9482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          if (frame_out == 1) {
9492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            // Y4M file header
9507bc9febe8749e98a3812a0dc4380ceae75c29450Johann            len = y4m_write_file_header(
9517bc9febe8749e98a3812a0dc4380ceae75c29450Johann                buf, sizeof(buf), vpx_input_ctx.width, vpx_input_ctx.height,
9527bc9febe8749e98a3812a0dc4380ceae75c29450Johann                &vpx_input_ctx.framerate, img->fmt, img->bit_depth);
9532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            if (do_md5) {
9542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian              MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
9552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            } else {
9562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian              fputs(buf, outfile);
9572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            }
9582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          }
9592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
9602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          // Y4M frame header
9612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          len = y4m_write_frame_header(buf, sizeof(buf));
9622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          if (do_md5) {
9632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
9642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          } else {
9652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            fputs(buf, outfile);
9662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          }
967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        } else {
968ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian          if (frame_out == 1) {
969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian            // Check if --yv12 or --i420 options are consistent with the
970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian            // bit-stream decoded
971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian            if (opt_i420) {
972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              if (img->fmt != VPX_IMG_FMT_I420 &&
973ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  img->fmt != VPX_IMG_FMT_I42016) {
974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                fprintf(stderr, "Cannot produce i420 output for bit-stream.\n");
975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                goto fail;
976ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              }
977ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian            }
978ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian            if (opt_yv12) {
979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              if ((img->fmt != VPX_IMG_FMT_I420 &&
9807bc9febe8749e98a3812a0dc4380ceae75c29450Johann                   img->fmt != VPX_IMG_FMT_YV12) ||
9817bc9febe8749e98a3812a0dc4380ceae75c29450Johann                  img->bit_depth != 8) {
982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                fprintf(stderr, "Cannot produce yv12 output for bit-stream.\n");
983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                goto fail;
984ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian              }
985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian            }
986ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian          }
9871b362b15af34006e6a11974088a46d42b903418eJohann        }
9881b362b15af34006e6a11974088a46d42b903418eJohann
9892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        if (do_md5) {
9902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          update_image_md5(img, planes, &md5_ctx);
9912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        } else {
9920a39d0a697ff3603e8c100300fda363658e10b23James Zern          if (!corrupted) write_image_file(img, planes, outfile);
993ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
9942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      } else {
9957bc9febe8749e98a3812a0dc4380ceae75c29450Johann        generate_filename(outfile_pattern, outfile_name, PATH_MAX, img->d_w,
9967bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          img->d_h, frame_in);
9972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        if (do_md5) {
9982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          MD5Init(&md5_ctx);
9992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          update_image_md5(img, planes, &md5_ctx);
10002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          MD5Final(md5_digest, &md5_ctx);
10012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          print_md5(md5_digest, outfile_name);
10022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        } else {
10032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          outfile = open_outfile(outfile_name);
10042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          write_image_file(img, planes, outfile);
10052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          fclose(outfile);
1006538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
1007ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1008538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
1009ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1010538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
1011ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (summary || progress) {
1012ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    show_progress(frame_in, frame_out, dx_time);
1013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    fprintf(stderr, "\n");
1014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10167bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (frames_corrupted) {
1017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);
10187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
10197bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ret = EXIT_SUCCESS;
10207bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
10211b362b15af34006e6a11974088a46d42b903418eJohann
1022538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberfail:
1023538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
1024ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (vpx_codec_destroy(&decoder)) {
10252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    fprintf(stderr, "Failed to destroy decoder: %s\n",
10262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian            vpx_codec_error(&decoder));
1027ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1028ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10297bc9febe8749e98a3812a0dc4380ceae75c29450Johannfail2:
10307bc9febe8749e98a3812a0dc4380ceae75c29450Johann
10312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (!noblit && single_file) {
10322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (do_md5) {
10332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      MD5Final(md5_digest, &md5_ctx);
10342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      print_md5(md5_digest, outfile_name);
10352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    } else {
10362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      fclose(outfile);
10372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
10382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
10392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
10402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#if CONFIG_WEBM_IO
10412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM)
10422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    webm_free(input.webm_ctx);
10432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
1044538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
10457bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (input.vpx_input_ctx->file_type != FILE_TYPE_WEBM) free(buf);
10462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
10472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (scaled_img) vpx_img_free(scaled_img);
10487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
10497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (img_shifted) vpx_img_free(img_shifted);
10507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
10512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
10522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
10532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    free(ext_fb_list.ext_fb[i].data);
10542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
10552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  free(ext_fb_list.ext_fb);
10562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1057ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  fclose(infile);
10580a39d0a697ff3603e8c100300fda363658e10b23James Zern  if (framestats_file) fclose(framestats_file);
10590a39d0a697ff3603e8c100300fda363658e10b23James Zern
1060ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  free(argv);
1061538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
10627bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return ret;
1063ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1064ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1065ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint main(int argc, const char **argv_) {
1066ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int loops = 1, i;
1067ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char **argv, **argi, **argj;
1068ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct arg arg;
1069ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int error = 0;
1070538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
1071ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  argv = argv_dup(argc - 1, argv_ + 1);
1072ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
1073ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    memset(&arg, 0, sizeof(arg));
1074ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    arg.argv_step = 1;
1075ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1076ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (arg_match(&arg, &looparg, argi)) {
1077ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      loops = arg_parse_uint(&arg);
1078ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1079ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1080ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1081ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  free(argv);
10827bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; !error && i < loops; i++) error = main_loop(argc, argv_);
1083ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return error;
1084538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
1085