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

Side by Side Diff: source/libvpx/vpxdec.c

Issue 111463005: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vpx_scale/yv12config.h ('k') | source/libvpx/vpxenc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11
12 /* This is a simple program that reads ivf files and decodes them
13 * using the new interface. Decoded frames are output as YV12 raw.
14 */
15 #include <assert.h> 11 #include <assert.h>
16 #include <stdio.h> 12 #include <stdio.h>
17 #include <stdlib.h> 13 #include <stdlib.h>
18 #include <stdarg.h> 14 #include <stdarg.h>
19 #include <string.h> 15 #include <string.h>
20 #include <limits.h> 16 #include <limits.h>
21 17
18 #include "third_party/libyuv/include/libyuv/scale.h"
19
20 #include "./args.h"
21 #include "./ivfdec.h"
22
22 #define VPX_CODEC_DISABLE_COMPAT 1 23 #define VPX_CODEC_DISABLE_COMPAT 1
23 #include "vpx_config.h" 24 #include "./vpx_config.h"
24 #include "vpx/vpx_decoder.h" 25 #include "vpx/vpx_decoder.h"
25 #include "vpx_ports/vpx_timer.h" 26 #include "vpx_ports/vpx_timer.h"
27
26 #if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER 28 #if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
27 #include "vpx/vp8dx.h" 29 #include "vpx/vp8dx.h"
28 #endif 30 #endif
31
29 #if CONFIG_MD5 32 #if CONFIG_MD5
30 #include "md5_utils.h" 33 #include "./md5_utils.h"
31 #endif
32 #include "tools_common.h"
33 #include "nestegg/include/nestegg/nestegg.h"
34 #include "third_party/libyuv/include/libyuv/scale.h"
35
36 #if CONFIG_OS_SUPPORT
37 #if defined(_MSC_VER)
38 #include <io.h>
39 #define snprintf _snprintf
40 #define isatty _isatty
41 #define fileno _fileno
42 #else
43 #include <unistd.h>
44 #endif
45 #endif 34 #endif
46 35
47 #ifndef PATH_MAX 36 #include "./tools_common.h"
48 #define PATH_MAX 256 37 #include "./webmdec.h"
49 #endif
50 38
51 static const char *exec_name; 39 static const char *exec_name;
52 40
53 #define VP8_FOURCC (0x00385056)
54 #define VP9_FOURCC (0x00395056)
55 static const struct { 41 static const struct {
56 char const *name; 42 char const *name;
57 const vpx_codec_iface_t *(*iface)(void); 43 const vpx_codec_iface_t *(*iface)(void);
58 unsigned int fourcc; 44 uint32_t fourcc;
59 unsigned int fourcc_mask; 45 uint32_t fourcc_mask;
60 } ifaces[] = { 46 } ifaces[] = {
61 #if CONFIG_VP8_DECODER 47 #if CONFIG_VP8_DECODER
62 {"vp8", vpx_codec_vp8_dx, VP8_FOURCC, 0x00FFFFFF}, 48 {"vp8", vpx_codec_vp8_dx, VP8_FOURCC_MASK, 0x00FFFFFF},
63 #endif 49 #endif
64 #if CONFIG_VP9_DECODER 50 #if CONFIG_VP9_DECODER
65 {"vp9", vpx_codec_vp9_dx, VP9_FOURCC, 0x00FFFFFF}, 51 {"vp9", vpx_codec_vp9_dx, VP9_FOURCC_MASK, 0x00FFFFFF},
66 #endif 52 #endif
67 }; 53 };
68 54
69 #include "args.h" 55 struct VpxDecInputContext {
56 struct VpxInputContext *vpx_input_ctx;
57 struct WebmInputContext *webm_ctx;
58 };
59
70 static const arg_def_t looparg = ARG_DEF(NULL, "loops", 1, 60 static const arg_def_t looparg = ARG_DEF(NULL, "loops", 1,
71 "Number of times to decode the file"); 61 "Number of times to decode the file");
72 static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, 62 static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1,
73 "Codec to use"); 63 "Codec to use");
74 static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, 64 static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0,
75 "Output raw YV12 frames"); 65 "Output raw YV12 frames");
76 static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0, 66 static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0,
77 "Output raw I420 frames"); 67 "Output raw I420 frames");
78 static const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0, 68 static const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0,
79 "Flip the chroma planes in the output "); 69 "Flip the chroma planes in the output ");
(...skipping 12 matching lines...) Expand all
92 static const arg_def_t outputfile = ARG_DEF("o", "output", 1, 82 static const arg_def_t outputfile = ARG_DEF("o", "output", 1,
93 "Output file name pattern (see below )"); 83 "Output file name pattern (see below )");
94 static const arg_def_t threadsarg = ARG_DEF("t", "threads", 1, 84 static const arg_def_t threadsarg = ARG_DEF("t", "threads", 1,
95 "Max threads to use"); 85 "Max threads to use");
96 static const arg_def_t verbosearg = ARG_DEF("v", "verbose", 0, 86 static const arg_def_t verbosearg = ARG_DEF("v", "verbose", 0,
97 "Show version string"); 87 "Show version string");
98 static const arg_def_t error_concealment = ARG_DEF(NULL, "error-concealment", 0, 88 static const arg_def_t error_concealment = ARG_DEF(NULL, "error-concealment", 0,
99 "Enable decoder error-conceal ment"); 89 "Enable decoder error-conceal ment");
100 static const arg_def_t scalearg = ARG_DEF("S", "scale", 0, 90 static const arg_def_t scalearg = ARG_DEF("S", "scale", 0,
101 "Scale output frames uniformly"); 91 "Scale output frames uniformly");
92 static const arg_def_t fb_arg =
93 ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use");
94 static const arg_def_t fb_lru_arg =
95 ARG_DEF(NULL, "frame-buffers-lru", 1, "Turn on/off frame buffer lru");
102 96
103 97
104 #if CONFIG_MD5 98 #if CONFIG_MD5
105 static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0, 99 static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0,
106 "Compute the MD5 sum of the decoded fram e"); 100 "Compute the MD5 sum of the decoded fram e");
107 #endif 101 #endif
108 static const arg_def_t *all_args[] = { 102 static const arg_def_t *all_args[] = {
109 &codecarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg, 103 &codecarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg,
110 &progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile, 104 &progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile,
111 &threadsarg, &verbosearg, &scalearg, 105 &threadsarg, &verbosearg, &scalearg, &fb_arg, &fb_lru_arg,
112 #if CONFIG_MD5 106 #if CONFIG_MD5
113 &md5arg, 107 &md5arg,
114 #endif 108 #endif
115 &error_concealment, 109 &error_concealment,
116 NULL 110 NULL
117 }; 111 };
118 112
119 #if CONFIG_VP8_DECODER 113 #if CONFIG_VP8_DECODER
120 static const arg_def_t addnoise_level = ARG_DEF(NULL, "noise-level", 1, 114 static const arg_def_t addnoise_level = ARG_DEF(NULL, "noise-level", 1,
121 "Enable VP8 postproc add noise") ; 115 "Enable VP8 postproc add noise") ;
(...skipping 14 matching lines...) Expand all
136 static const arg_def_t mfqe = ARG_DEF(NULL, "mfqe", 0, 130 static const arg_def_t mfqe = ARG_DEF(NULL, "mfqe", 0,
137 "Enable multiframe quality enhancement"); 131 "Enable multiframe quality enhancement");
138 132
139 static const arg_def_t *vp8_pp_args[] = { 133 static const arg_def_t *vp8_pp_args[] = {
140 &addnoise_level, &deblock, &demacroblock_level, &pp_debug_info, 134 &addnoise_level, &deblock, &demacroblock_level, &pp_debug_info,
141 &pp_disp_ref_frame, &pp_disp_mb_modes, &pp_disp_b_modes, &pp_disp_mvs, &mfqe, 135 &pp_disp_ref_frame, &pp_disp_mb_modes, &pp_disp_b_modes, &pp_disp_mvs, &mfqe,
142 NULL 136 NULL
143 }; 137 };
144 #endif 138 #endif
145 139
146 static void usage_exit() { 140 void usage_exit() {
147 int i; 141 int i;
148 142
149 fprintf(stderr, "Usage: %s <options> filename\n\n" 143 fprintf(stderr, "Usage: %s <options> filename\n\n"
150 "Options:\n", exec_name); 144 "Options:\n", exec_name);
151 arg_show_usage(stderr, all_args); 145 arg_show_usage(stderr, all_args);
152 #if CONFIG_VP8_DECODER 146 #if CONFIG_VP8_DECODER
153 fprintf(stderr, "\nVP8 Postprocessing Options:\n"); 147 fprintf(stderr, "\nVP8 Postprocessing Options:\n");
154 arg_show_usage(stderr, vp8_pp_args); 148 arg_show_usage(stderr, vp8_pp_args);
155 #endif 149 #endif
156 fprintf(stderr, 150 fprintf(stderr,
(...skipping 14 matching lines...) Expand all
171 fprintf(stderr, "\nIncluded decoders:\n\n"); 165 fprintf(stderr, "\nIncluded decoders:\n\n");
172 166
173 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) 167 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++)
174 fprintf(stderr, " %-6s - %s\n", 168 fprintf(stderr, " %-6s - %s\n",
175 ifaces[i].name, 169 ifaces[i].name,
176 vpx_codec_iface_name(ifaces[i].iface())); 170 vpx_codec_iface_name(ifaces[i].iface()));
177 171
178 exit(EXIT_FAILURE); 172 exit(EXIT_FAILURE);
179 } 173 }
180 174
181 void die(const char *fmt, ...) { 175 static int read_frame(struct VpxDecInputContext *input,
182 va_list ap; 176 uint8_t **buf,
183 va_start(ap, fmt); 177 size_t *bytes_in_buffer,
184 vfprintf(stderr, fmt, ap); 178 size_t *buffer_size) {
185 fprintf(stderr, "\n"); 179 char raw_hdr[RAW_FRAME_HDR_SZ];
186 usage_exit(); 180 size_t bytes_to_read = 0;
187 } 181 FILE *infile = input->vpx_input_ctx->file;
182 enum VideoFileType kind = input->vpx_input_ctx->file_type;
183 if (kind == FILE_TYPE_WEBM) {
184 return webm_read_frame(input->webm_ctx,
185 buf, bytes_in_buffer, buffer_size);
186 } else if (kind == FILE_TYPE_RAW) {
187 if (fread(raw_hdr, RAW_FRAME_HDR_SZ, 1, infile) != 1) {
188 if (!feof(infile))
189 warn("Failed to read RAW frame size\n");
190 } else {
191 const int kCorruptFrameThreshold = 256 * 1024 * 1024;
192 const int kFrameTooSmallThreshold = 256 * 1024;
193 bytes_to_read = mem_get_le32(raw_hdr);
188 194
189 static unsigned int mem_get_le16(const void *vmem) { 195 if (bytes_to_read > kCorruptFrameThreshold) {
190 unsigned int val; 196 warn("Read invalid frame size (%u)\n", (unsigned int)bytes_to_read);
191 const unsigned char *mem = (const unsigned char *)vmem; 197 bytes_to_read = 0;
198 }
192 199
193 val = mem[1] << 8; 200 if (kind == FILE_TYPE_RAW && bytes_to_read < kFrameTooSmallThreshold) {
194 val |= mem[0]; 201 warn("Warning: Read invalid frame size (%u) - not a raw file?\n",
195 return val; 202 (unsigned int)bytes_to_read);
196 } 203 }
197 204
198 static unsigned int mem_get_le32(const void *vmem) { 205 if (bytes_to_read > *buffer_size) {
199 unsigned int val; 206 uint8_t *new_buf = realloc(*buf, 2 * bytes_to_read);
200 const unsigned char *mem = (const unsigned char *)vmem;
201 207
202 val = mem[3] << 24; 208 if (new_buf) {
203 val |= mem[2] << 16; 209 *buf = new_buf;
204 val |= mem[1] << 8; 210 *buffer_size = 2 * bytes_to_read;
205 val |= mem[0]; 211 } else {
206 return val; 212 warn("Failed to allocate compressed data buffer\n");
207 } 213 bytes_to_read = 0;
208 214 }
209 enum file_kind { 215 }
210 RAW_FILE,
211 IVF_FILE,
212 WEBM_FILE
213 };
214
215 struct input_ctx {
216 enum file_kind kind;
217 FILE *infile;
218 nestegg *nestegg_ctx;
219 nestegg_packet *pkt;
220 unsigned int chunk;
221 unsigned int chunks;
222 unsigned int video_track;
223 };
224
225 #define IVF_FRAME_HDR_SZ (sizeof(uint32_t) + sizeof(uint64_t))
226 #define RAW_FRAME_HDR_SZ (sizeof(uint32_t))
227 static int read_frame(struct input_ctx *input,
228 uint8_t **buf,
229 size_t *buf_sz,
230 size_t *buf_alloc_sz) {
231 char raw_hdr[IVF_FRAME_HDR_SZ];
232 size_t new_buf_sz;
233 FILE *infile = input->infile;
234 enum file_kind kind = input->kind;
235 if (kind == WEBM_FILE) {
236 if (input->chunk >= input->chunks) {
237 unsigned int track;
238
239 do {
240 /* End of this packet, get another. */
241 if (input->pkt)
242 nestegg_free_packet(input->pkt);
243
244 if (nestegg_read_packet(input->nestegg_ctx, &input->pkt) <= 0
245 || nestegg_packet_track(input->pkt, &track))
246 return 1;
247
248 } while (track != input->video_track);
249
250 if (nestegg_packet_count(input->pkt, &input->chunks))
251 return 1;
252 input->chunk = 0;
253 } 216 }
254 217
255 if (nestegg_packet_data(input->pkt, input->chunk, buf, buf_sz)) 218 if (!feof(infile)) {
256 return 1; 219 if (fread(*buf, 1, bytes_to_read, infile) != bytes_to_read) {
257 input->chunk++; 220 warn("Failed to read full frame\n");
258 221 return 1;
259 return 0;
260 }
261 /* For both the raw and ivf formats, the frame size is the first 4 bytes
262 * of the frame header. We just need to special case on the header
263 * size.
264 */
265 else if (fread(raw_hdr, kind == IVF_FILE
266 ? IVF_FRAME_HDR_SZ : RAW_FRAME_HDR_SZ, 1, infile) != 1) {
267 if (!feof(infile))
268 fprintf(stderr, "Failed to read frame size\n");
269
270 new_buf_sz = 0;
271 } else {
272 new_buf_sz = mem_get_le32(raw_hdr);
273
274 if (new_buf_sz > 256 * 1024 * 1024) {
275 fprintf(stderr, "Error: Read invalid frame size (%u)\n",
276 (unsigned int)new_buf_sz);
277 new_buf_sz = 0;
278 }
279
280 if (kind == RAW_FILE && new_buf_sz > 256 * 1024)
281 fprintf(stderr, "Warning: Read invalid frame size (%u)"
282 " - not a raw file?\n", (unsigned int)new_buf_sz);
283
284 if (new_buf_sz > *buf_alloc_sz) {
285 uint8_t *new_buf = realloc(*buf, 2 * new_buf_sz);
286
287 if (new_buf) {
288 *buf = new_buf;
289 *buf_alloc_sz = 2 * new_buf_sz;
290 } else {
291 fprintf(stderr, "Failed to allocate compressed data buffer\n");
292 new_buf_sz = 0;
293 } 222 }
294 } 223 *bytes_in_buffer = bytes_to_read;
295 }
296
297 *buf_sz = new_buf_sz;
298
299 if (!feof(infile)) {
300 if (fread(*buf, 1, *buf_sz, infile) != *buf_sz) {
301 fprintf(stderr, "Failed to read full frame\n");
302 return 1;
303 } 224 }
304 225
305 return 0; 226 return 0;
227 } else if (kind == FILE_TYPE_IVF) {
228 return ivf_read_frame(input->vpx_input_ctx,
229 buf, bytes_in_buffer, buffer_size);
306 } 230 }
307 231
308 return 1; 232 return 1;
309 } 233 }
310 234
311 void *out_open(const char *out_fn, int do_md5) { 235 void *out_open(const char *out_fn, int do_md5) {
312 void *out = NULL; 236 void *out = NULL;
313 237
314 if (do_md5) { 238 if (do_md5) {
315 #if CONFIG_MD5 239 #if CONFIG_MD5
316 MD5Context *md5_ctx = out = malloc(sizeof(MD5Context)); 240 MD5Context *md5_ctx = out = malloc(sizeof(MD5Context));
317 (void)out_fn; 241 (void)out_fn;
318 MD5Init(md5_ctx); 242 MD5Init(md5_ctx);
319 #endif 243 #endif
320 } else { 244 } else {
321 FILE *outfile = out = strcmp("-", out_fn) ? fopen(out_fn, "wb") 245 FILE *outfile = out = strcmp("-", out_fn) ? fopen(out_fn, "wb")
322 : set_binary_mode(stdout); 246 : set_binary_mode(stdout);
323 247
324 if (!outfile) { 248 if (!outfile) {
325 fprintf(stderr, "Failed to output file"); 249 fatal("Failed to output file");
326 exit(EXIT_FAILURE);
327 } 250 }
328 } 251 }
329 252
330 return out; 253 return out;
331 } 254 }
332 255
333 void out_put(void *out, const uint8_t *buf, unsigned int len, int do_md5) { 256 void out_put(void *out, const uint8_t *buf, unsigned int len, int do_md5) {
334 if (do_md5) { 257 if (do_md5) {
335 #if CONFIG_MD5 258 #if CONFIG_MD5
336 MD5Update(out, buf, len); 259 MD5Update(out, buf, len);
(...skipping 15 matching lines...) Expand all
352 for (i = 0; i < 16; i++) 275 for (i = 0; i < 16; i++)
353 printf("%02x", md5[i]); 276 printf("%02x", md5[i]);
354 277
355 printf(" %s\n", out_fn); 278 printf(" %s\n", out_fn);
356 #endif 279 #endif
357 } else { 280 } else {
358 fclose(out); 281 fclose(out);
359 } 282 }
360 } 283 }
361 284
362 unsigned int file_is_ivf(FILE *infile, 285 int file_is_raw(struct VpxInputContext *input) {
363 unsigned int *fourcc, 286 uint8_t buf[32];
364 unsigned int *width,
365 unsigned int *height,
366 unsigned int *fps_den,
367 unsigned int *fps_num) {
368 char raw_hdr[32];
369 int is_ivf = 0;
370
371 if (fread(raw_hdr, 1, 32, infile) == 32) {
372 if (raw_hdr[0] == 'D' && raw_hdr[1] == 'K'
373 && raw_hdr[2] == 'I' && raw_hdr[3] == 'F') {
374 is_ivf = 1;
375
376 if (mem_get_le16(raw_hdr + 4) != 0)
377 fprintf(stderr, "Error: Unrecognized IVF version! This file may not"
378 " decode properly.");
379
380 *fourcc = mem_get_le32(raw_hdr + 8);
381 *width = mem_get_le16(raw_hdr + 12);
382 *height = mem_get_le16(raw_hdr + 14);
383 *fps_num = mem_get_le32(raw_hdr + 16);
384 *fps_den = mem_get_le32(raw_hdr + 20);
385
386 /* Some versions of vpxenc used 1/(2*fps) for the timebase, so
387 * we can guess the framerate using only the timebase in this
388 * case. Other files would require reading ahead to guess the
389 * timebase, like we do for webm.
390 */
391 if (*fps_num < 1000) {
392 /* Correct for the factor of 2 applied to the timebase in the
393 * encoder.
394 */
395 if (*fps_num & 1)*fps_den <<= 1;
396 else *fps_num >>= 1;
397 } else {
398 /* Don't know FPS for sure, and don't have readahead code
399 * (yet?), so just default to 30fps.
400 */
401 *fps_num = 30;
402 *fps_den = 1;
403 }
404 }
405 }
406
407 if (!is_ivf)
408 rewind(infile);
409
410 return is_ivf;
411 }
412
413
414 unsigned int file_is_raw(FILE *infile,
415 unsigned int *fourcc,
416 unsigned int *width,
417 unsigned int *height,
418 unsigned int *fps_den,
419 unsigned int *fps_num) {
420 unsigned char buf[32];
421 int is_raw = 0; 287 int is_raw = 0;
422 vpx_codec_stream_info_t si; 288 vpx_codec_stream_info_t si;
423 289
424 si.sz = sizeof(si); 290 si.sz = sizeof(si);
425 291
426 if (fread(buf, 1, 32, infile) == 32) { 292 if (fread(buf, 1, 32, input->file) == 32) {
427 int i; 293 int i;
428 294
429 if (mem_get_le32(buf) < 256 * 1024 * 1024) 295 if (mem_get_le32(buf) < 256 * 1024 * 1024) {
430 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) 296 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) {
431 if (!vpx_codec_peek_stream_info(ifaces[i].iface(), 297 if (!vpx_codec_peek_stream_info(ifaces[i].iface(),
432 buf + 4, 32 - 4, &si)) { 298 buf + 4, 32 - 4, &si)) {
433 is_raw = 1; 299 is_raw = 1;
434 *fourcc = ifaces[i].fourcc; 300 input->fourcc = ifaces[i].fourcc;
435 *width = si.w; 301 input->width = si.w;
436 *height = si.h; 302 input->height = si.h;
437 *fps_num = 30; 303 input->framerate.numerator = 30;
438 *fps_den = 1; 304 input->framerate.denominator = 1;
439 break; 305 break;
440 } 306 }
307 }
308 }
441 } 309 }
442 310
443 rewind(infile); 311 rewind(input->file);
444 return is_raw; 312 return is_raw;
445 } 313 }
446 314
447
448 static int
449 nestegg_read_cb(void *buffer, size_t length, void *userdata) {
450 FILE *f = userdata;
451
452 if (fread(buffer, 1, length, f) < length) {
453 if (ferror(f))
454 return -1;
455 if (feof(f))
456 return 0;
457 }
458 return 1;
459 }
460
461
462 static int
463 nestegg_seek_cb(int64_t offset, int whence, void *userdata) {
464 switch (whence) {
465 case NESTEGG_SEEK_SET:
466 whence = SEEK_SET;
467 break;
468 case NESTEGG_SEEK_CUR:
469 whence = SEEK_CUR;
470 break;
471 case NESTEGG_SEEK_END:
472 whence = SEEK_END;
473 break;
474 };
475 return fseek(userdata, (long)offset, whence) ? -1 : 0;
476 }
477
478
479 static int64_t
480 nestegg_tell_cb(void *userdata) {
481 return ftell(userdata);
482 }
483
484
485 static void
486 nestegg_log_cb(nestegg *context, unsigned int severity, char const *format,
487 ...) {
488 va_list ap;
489
490 va_start(ap, format);
491 vfprintf(stderr, format, ap);
492 fprintf(stderr, "\n");
493 va_end(ap);
494 }
495
496
497 static int
498 webm_guess_framerate(struct input_ctx *input,
499 unsigned int *fps_den,
500 unsigned int *fps_num) {
501 unsigned int i;
502 uint64_t tstamp = 0;
503
504 /* Check to see if we can seek before we parse any data. */
505 if (nestegg_track_seek(input->nestegg_ctx, input->video_track, 0)) {
506 fprintf(stderr,
507 "WARNING: Failed to guess framerate (no Cues), set to 30fps.\n");
508 *fps_num = 30;
509 *fps_den = 1;
510 return 0;
511 }
512
513 /* Guess the framerate. Read up to 1 second, or 50 video packets,
514 * whichever comes first.
515 */
516 for (i = 0; tstamp < 1000000000 && i < 50;) {
517 nestegg_packet *pkt;
518 unsigned int track;
519
520 if (nestegg_read_packet(input->nestegg_ctx, &pkt) <= 0)
521 break;
522
523 nestegg_packet_track(pkt, &track);
524 if (track == input->video_track) {
525 nestegg_packet_tstamp(pkt, &tstamp);
526 i++;
527 }
528
529 nestegg_free_packet(pkt);
530 }
531
532 if (nestegg_track_seek(input->nestegg_ctx, input->video_track, 0))
533 goto fail;
534
535 *fps_num = (i - 1) * 1000000;
536 *fps_den = (unsigned int)(tstamp / 1000);
537 return 0;
538 fail:
539 nestegg_destroy(input->nestegg_ctx);
540 input->nestegg_ctx = NULL;
541 rewind(input->infile);
542 return 1;
543 }
544
545
546 static int
547 file_is_webm(struct input_ctx *input,
548 unsigned int *fourcc,
549 unsigned int *width,
550 unsigned int *height,
551 unsigned int *fps_den,
552 unsigned int *fps_num) {
553 unsigned int i, n;
554 int track_type = -1;
555 int codec_id;
556
557 nestegg_io io = {nestegg_read_cb, nestegg_seek_cb, nestegg_tell_cb, 0};
558 nestegg_video_params params;
559
560 io.userdata = input->infile;
561 if (nestegg_init(&input->nestegg_ctx, io, NULL))
562 goto fail;
563
564 if (nestegg_track_count(input->nestegg_ctx, &n))
565 goto fail;
566
567 for (i = 0; i < n; i++) {
568 track_type = nestegg_track_type(input->nestegg_ctx, i);
569
570 if (track_type == NESTEGG_TRACK_VIDEO)
571 break;
572 else if (track_type < 0)
573 goto fail;
574 }
575
576 codec_id = nestegg_track_codec_id(input->nestegg_ctx, i);
577 if (codec_id == NESTEGG_CODEC_VP8) {
578 *fourcc = VP8_FOURCC;
579 } else if (codec_id == NESTEGG_CODEC_VP9) {
580 *fourcc = VP9_FOURCC;
581 } else {
582 fprintf(stderr, "Not VPx video, quitting.\n");
583 exit(1);
584 }
585
586 input->video_track = i;
587
588 if (nestegg_track_video_params(input->nestegg_ctx, i, &params))
589 goto fail;
590
591 *fps_den = 0;
592 *fps_num = 0;
593 *width = params.width;
594 *height = params.height;
595 return 1;
596 fail:
597 input->nestegg_ctx = NULL;
598 rewind(input->infile);
599 return 0;
600 }
601
602
603 void show_progress(int frame_in, int frame_out, unsigned long dx_time) { 315 void show_progress(int frame_in, int frame_out, unsigned long dx_time) {
604 fprintf(stderr, "%d decoded frames/%d showed frames in %lu us (%.2f fps)\r", 316 fprintf(stderr, "%d decoded frames/%d showed frames in %lu us (%.2f fps)\r",
605 frame_in, frame_out, dx_time, 317 frame_in, frame_out, dx_time,
606 (float)frame_out * 1000000.0 / (float)dx_time); 318 (float)frame_out * 1000000.0 / (float)dx_time);
607 } 319 }
608 320
321 // Called by libvpx if the frame buffer size needs to increase.
322 //
323 // Parameters:
324 // user_priv Data passed into libvpx.
325 // new_size Minimum size needed by libvpx to decompress the next frame.
326 // fb Pointer to the frame buffer to update.
327 //
328 // Returns 0 on success. Returns < 0 on failure.
329 int realloc_vp9_frame_buffer(void *user_priv, size_t new_size,
330 vpx_codec_frame_buffer_t *fb) {
331 (void)user_priv;
332 if (!fb)
333 return -1;
334
335 free(fb->data);
336 fb->data = (uint8_t*)malloc(new_size);
337 if (!fb->data) {
338 fb->size = 0;
339 return -1;
340 }
341
342 fb->size = new_size;
343 return 0;
344 }
609 345
610 void generate_filename(const char *pattern, char *out, size_t q_len, 346 void generate_filename(const char *pattern, char *out, size_t q_len,
611 unsigned int d_w, unsigned int d_h, 347 unsigned int d_w, unsigned int d_h,
612 unsigned int frame_in) { 348 unsigned int frame_in) {
613 const char *p = pattern; 349 const char *p = pattern;
614 char *q = out; 350 char *q = out;
615 351
616 do { 352 do {
617 char *next_pat = strchr(p, '%'); 353 char *next_pat = strchr(p, '%');
618 354
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 q[copy_len] = '\0'; 417 q[copy_len] = '\0';
682 q += copy_len; 418 q += copy_len;
683 p += copy_len; 419 p += copy_len;
684 q_len -= copy_len; 420 q_len -= copy_len;
685 } 421 }
686 } while (*p); 422 } while (*p);
687 } 423 }
688 424
689 425
690 int main_loop(int argc, const char **argv_) { 426 int main_loop(int argc, const char **argv_) {
691 vpx_codec_ctx_t decoder; 427 vpx_codec_ctx_t decoder;
692 char *fn = NULL; 428 char *fn = NULL;
693 int i; 429 int i;
694 uint8_t *buf = NULL; 430 uint8_t *buf = NULL;
695 size_t buf_sz = 0, buf_alloc_sz = 0; 431 size_t bytes_in_buffer = 0, buffer_size = 0;
696 FILE *infile; 432 FILE *infile;
697 int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0, do _md5 = 0, progress = 0; 433 int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
434 int do_md5 = 0, progress = 0;
698 int stop_after = 0, postproc = 0, summary = 0, quiet = 1; 435 int stop_after = 0, postproc = 0, summary = 0, quiet = 1;
699 int arg_skip = 0; 436 int arg_skip = 0;
700 int ec_enabled = 0; 437 int ec_enabled = 0;
701 vpx_codec_iface_t *iface = NULL; 438 vpx_codec_iface_t *iface = NULL;
702 unsigned int fourcc;
703 unsigned long dx_time = 0; 439 unsigned long dx_time = 0;
704 struct arg arg; 440 struct arg arg;
705 char **argv, **argi, **argj; 441 char **argv, **argi, **argj;
706 const char *outfile_pattern = 0; 442 const char *outfile_pattern = 0;
707 char outfile[PATH_MAX]; 443 char outfile[PATH_MAX];
708 int single_file; 444 int single_file;
709 int use_y4m = 1; 445 int use_y4m = 1;
710 unsigned int width;
711 unsigned int height;
712 unsigned int fps_den;
713 unsigned int fps_num;
714 void *out = NULL; 446 void *out = NULL;
715 vpx_codec_dec_cfg_t cfg = {0}; 447 vpx_codec_dec_cfg_t cfg = {0};
716 #if CONFIG_VP8_DECODER 448 #if CONFIG_VP8_DECODER
717 vp8_postproc_cfg_t vp8_pp_cfg = {0}; 449 vp8_postproc_cfg_t vp8_pp_cfg = {0};
718 int vp8_dbg_color_ref_frame = 0; 450 int vp8_dbg_color_ref_frame = 0;
719 int vp8_dbg_color_mb_modes = 0; 451 int vp8_dbg_color_mb_modes = 0;
720 int vp8_dbg_color_b_modes = 0; 452 int vp8_dbg_color_b_modes = 0;
721 int vp8_dbg_display_mv = 0; 453 int vp8_dbg_display_mv = 0;
722 #endif 454 #endif
723 struct input_ctx input = {0};
724 int frames_corrupted = 0; 455 int frames_corrupted = 0;
725 int dec_flags = 0; 456 int dec_flags = 0;
726 int do_scale = 0; 457 int do_scale = 0;
727 int stream_w = 0, stream_h = 0;
728 vpx_image_t *scaled_img = NULL; 458 vpx_image_t *scaled_img = NULL;
729 int frame_avail, got_data; 459 int frame_avail, got_data;
460 int num_external_frame_buffers = 0;
461 int fb_lru_cache = 0;
462 vpx_codec_frame_buffer_t *frame_buffers = NULL;
463
464 struct VpxDecInputContext input = {0};
465 struct VpxInputContext vpx_input_ctx = {0};
466 struct WebmInputContext webm_ctx = {0};
467 input.vpx_input_ctx = &vpx_input_ctx;
468 input.webm_ctx = &webm_ctx;
730 469
731 /* Parse command line */ 470 /* Parse command line */
732 exec_name = argv_[0]; 471 exec_name = argv_[0];
733 argv = argv_dup(argc - 1, argv_ + 1); 472 argv = argv_dup(argc - 1, argv_ + 1);
734 473
735 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { 474 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
736 memset(&arg, 0, sizeof(arg)); 475 memset(&arg, 0, sizeof(arg));
737 arg.argv_step = 1; 476 arg.argv_step = 1;
738 477
739 if (arg_match(&arg, &codecarg, argi)) { 478 if (arg_match(&arg, &codecarg, argi)) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 else if (arg_match(&arg, &md5arg, argi)) 512 else if (arg_match(&arg, &md5arg, argi))
774 do_md5 = 1; 513 do_md5 = 1;
775 else if (arg_match(&arg, &summaryarg, argi)) 514 else if (arg_match(&arg, &summaryarg, argi))
776 summary = 1; 515 summary = 1;
777 else if (arg_match(&arg, &threadsarg, argi)) 516 else if (arg_match(&arg, &threadsarg, argi))
778 cfg.threads = arg_parse_uint(&arg); 517 cfg.threads = arg_parse_uint(&arg);
779 else if (arg_match(&arg, &verbosearg, argi)) 518 else if (arg_match(&arg, &verbosearg, argi))
780 quiet = 0; 519 quiet = 0;
781 else if (arg_match(&arg, &scalearg, argi)) 520 else if (arg_match(&arg, &scalearg, argi))
782 do_scale = 1; 521 do_scale = 1;
522 else if (arg_match(&arg, &fb_arg, argi))
523 num_external_frame_buffers = arg_parse_uint(&arg);
524 else if (arg_match(&arg, &fb_lru_arg, argi))
525 fb_lru_cache = arg_parse_uint(&arg);
783 526
784 #if CONFIG_VP8_DECODER 527 #if CONFIG_VP8_DECODER
785 else if (arg_match(&arg, &addnoise_level, argi)) { 528 else if (arg_match(&arg, &addnoise_level, argi)) {
786 postproc = 1; 529 postproc = 1;
787 vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE; 530 vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE;
788 vp8_pp_cfg.noise_level = arg_parse_uint(&arg); 531 vp8_pp_cfg.noise_level = arg_parse_uint(&arg);
789 } else if (arg_match(&arg, &demacroblock_level, argi)) { 532 } else if (arg_match(&arg, &demacroblock_level, argi)) {
790 postproc = 1; 533 postproc = 1;
791 vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK; 534 vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK;
792 vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg); 535 vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 } 601 }
859 #if CONFIG_OS_SUPPORT 602 #if CONFIG_OS_SUPPORT
860 /* Make sure we don't dump to the terminal, unless forced to with -o - */ 603 /* Make sure we don't dump to the terminal, unless forced to with -o - */
861 if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) { 604 if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) {
862 fprintf(stderr, 605 fprintf(stderr,
863 "Not dumping raw video to your terminal. Use '-o -' to " 606 "Not dumping raw video to your terminal. Use '-o -' to "
864 "override.\n"); 607 "override.\n");
865 return EXIT_FAILURE; 608 return EXIT_FAILURE;
866 } 609 }
867 #endif 610 #endif
868 input.infile = infile; 611 input.vpx_input_ctx->file = infile;
869 if (file_is_ivf(infile, &fourcc, &width, &height, &fps_den, 612 if (file_is_ivf(input.vpx_input_ctx))
870 &fps_num)) 613 input.vpx_input_ctx->file_type = FILE_TYPE_IVF;
871 input.kind = IVF_FILE; 614 else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx))
872 else if (file_is_webm(&input, &fourcc, &width, &height, &fps_den, &fps_num)) 615 input.vpx_input_ctx->file_type = FILE_TYPE_WEBM;
873 input.kind = WEBM_FILE; 616 else if (file_is_raw(input.vpx_input_ctx))
874 else if (file_is_raw(infile, &fourcc, &width, &height, &fps_den, &fps_num)) 617 input.vpx_input_ctx->file_type = FILE_TYPE_RAW;
875 input.kind = RAW_FILE;
876 else { 618 else {
877 fprintf(stderr, "Unrecognized input file type.\n"); 619 fprintf(stderr, "Unrecognized input file type.\n");
878 return EXIT_FAILURE; 620 return EXIT_FAILURE;
879 } 621 }
880 622
881 /* If the output file is not set or doesn't have a sequence number in 623 /* If the output file is not set or doesn't have a sequence number in
882 * it, then we only open it once. 624 * it, then we only open it once.
883 */ 625 */
884 outfile_pattern = outfile_pattern ? outfile_pattern : "-"; 626 outfile_pattern = outfile_pattern ? outfile_pattern : "-";
885 single_file = 1; 627 single_file = 1;
886 { 628 {
887 const char *p = outfile_pattern; 629 const char *p = outfile_pattern;
888 do { 630 do {
889 p = strchr(p, '%'); 631 p = strchr(p, '%');
890 if (p && p[1] >= '1' && p[1] <= '9') { 632 if (p && p[1] >= '1' && p[1] <= '9') {
891 /* pattern contains sequence number, so it's not unique. */ 633 /* pattern contains sequence number, so it's not unique. */
892 single_file = 0; 634 single_file = 0;
893 break; 635 break;
894 } 636 }
895 if (p) 637 if (p)
896 p++; 638 p++;
897 } while (p); 639 } while (p);
898 } 640 }
899 641
900 if (single_file && !noblit) { 642 if (single_file && !noblit) {
901 generate_filename(outfile_pattern, outfile, sizeof(outfile) - 1, 643 generate_filename(outfile_pattern, outfile, sizeof(outfile) - 1,
902 width, height, 0); 644 vpx_input_ctx.width, vpx_input_ctx.height, 0);
903 out = out_open(outfile, do_md5); 645 out = out_open(outfile, do_md5);
904 } 646 }
905 647
906 if (use_y4m && !noblit) { 648 if (use_y4m && !noblit) {
907 char buffer[128]; 649 char buffer[128];
908 650
909 if (!single_file) { 651 if (!single_file) {
910 fprintf(stderr, "YUV4MPEG2 not supported with output patterns," 652 fprintf(stderr, "YUV4MPEG2 not supported with output patterns,"
911 " try --i420 or --yv12.\n"); 653 " try --i420 or --yv12.\n");
912 return EXIT_FAILURE; 654 return EXIT_FAILURE;
913 } 655 }
914 656
915 if (input.kind == WEBM_FILE) 657 if (vpx_input_ctx.file_type == FILE_TYPE_WEBM)
916 if (webm_guess_framerate(&input, &fps_den, &fps_num)) { 658 if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) {
917 fprintf(stderr, "Failed to guess framerate -- error parsing " 659 fprintf(stderr, "Failed to guess framerate -- error parsing "
918 "webm file?\n"); 660 "webm file?\n");
919 return EXIT_FAILURE; 661 return EXIT_FAILURE;
920 } 662 }
921 663
922 664
923 /*Note: We can't output an aspect ratio here because IVF doesn't 665 /*Note: We can't output an aspect ratio here because IVF doesn't
924 store one, and neither does VP8. 666 store one, and neither does VP8.
925 That will have to wait until these tools support WebM natively.*/ 667 That will have to wait until these tools support WebM natively.*/
926 snprintf(buffer, sizeof(buffer), "YUV4MPEG2 W%u H%u F%u:%u I%c ", 668 snprintf(buffer, sizeof(buffer), "YUV4MPEG2 W%u H%u F%u:%u I%c ",
927 width, height, fps_num, fps_den, 'p'); 669 vpx_input_ctx.width, vpx_input_ctx.height,
670 vpx_input_ctx.framerate.numerator,
671 vpx_input_ctx.framerate.denominator,
672 'p');
928 out_put(out, (unsigned char *)buffer, 673 out_put(out, (unsigned char *)buffer,
929 (unsigned int)strlen(buffer), do_md5); 674 (unsigned int)strlen(buffer), do_md5);
930 } 675 }
931 676
932 /* Try to determine the codec from the fourcc. */ 677 /* Try to determine the codec from the fourcc. */
933 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) 678 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++)
934 if ((fourcc & ifaces[i].fourcc_mask) == ifaces[i].fourcc) { 679 if ((vpx_input_ctx.fourcc & ifaces[i].fourcc_mask) == ifaces[i].fourcc) {
935 vpx_codec_iface_t *ivf_iface = ifaces[i].iface(); 680 vpx_codec_iface_t *vpx_iface = ifaces[i].iface();
936 681
937 if (iface && iface != ivf_iface) 682 if (iface && iface != vpx_iface)
938 fprintf(stderr, "Notice -- IVF header indicates codec: %s\n", 683 warn("Header indicates codec: %s\n", ifaces[i].name);
939 ifaces[i].name);
940 else 684 else
941 iface = ivf_iface; 685 iface = vpx_iface;
942 686
943 break; 687 break;
944 } 688 }
945 689
946 dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) | 690 dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
947 (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0); 691 (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0);
948 if (vpx_codec_dec_init(&decoder, iface ? iface : ifaces[0].iface(), &cfg, 692 if (vpx_codec_dec_init(&decoder, iface ? iface : ifaces[0].iface(), &cfg,
949 dec_flags)) { 693 dec_flags)) {
950 fprintf(stderr, "Failed to initialize decoder: %s\n", vpx_codec_error(&decod er)); 694 fprintf(stderr, "Failed to initialize decoder: %s\n", vpx_codec_error(&decod er));
951 return EXIT_FAILURE; 695 return EXIT_FAILURE;
(...skipping 29 matching lines...) Expand all
981 } 725 }
982 726
983 if (vp8_dbg_display_mv 727 if (vp8_dbg_display_mv
984 && vpx_codec_control(&decoder, VP8_SET_DBG_DISPLAY_MV, vp8_dbg_display_mv) ) { 728 && vpx_codec_control(&decoder, VP8_SET_DBG_DISPLAY_MV, vp8_dbg_display_mv) ) {
985 fprintf(stderr, "Failed to configure motion vector visualizer: %s\n", vpx_co dec_error(&decoder)); 729 fprintf(stderr, "Failed to configure motion vector visualizer: %s\n", vpx_co dec_error(&decoder));
986 return EXIT_FAILURE; 730 return EXIT_FAILURE;
987 } 731 }
988 #endif 732 #endif
989 733
990 734
991 if(arg_skip) 735 if (arg_skip)
992 fprintf(stderr, "Skiping first %d frames.\n", arg_skip); 736 fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
993 while (arg_skip) { 737 while (arg_skip) {
994 if (read_frame(&input, &buf, &buf_sz, &buf_alloc_sz)) 738 if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size))
995 break; 739 break;
996 arg_skip--; 740 arg_skip--;
997 } 741 }
998 742
743 if (num_external_frame_buffers > 0) {
744 // Allocate the frame buffer list, setting all of the values to 0.
745 // Including the size of frame buffers. Libvpx will request the
746 // application to realloc the frame buffer data if the size is too small.
747 frame_buffers = (vpx_codec_frame_buffer_t*)calloc(
748 num_external_frame_buffers, sizeof(*frame_buffers));
749 if (vpx_codec_set_frame_buffers(&decoder, frame_buffers,
750 num_external_frame_buffers,
751 realloc_vp9_frame_buffer,
752 NULL)) {
753 fprintf(stderr, "Failed to configure external frame buffers: %s\n",
754 vpx_codec_error(&decoder));
755 return EXIT_FAILURE;
756 }
757 }
758
759 if (fb_lru_cache > 0 &&
760 vpx_codec_control(&decoder, VP9D_SET_FRAME_BUFFER_LRU_CACHE,
761 fb_lru_cache)) {
762 fprintf(stderr, "Failed to set frame buffer lru cache: %s\n",
763 vpx_codec_error(&decoder));
764 return EXIT_FAILURE;
765 }
766
999 frame_avail = 1; 767 frame_avail = 1;
1000 got_data = 0; 768 got_data = 0;
1001 769
1002 /* Decode file */ 770 /* Decode file */
1003 while (frame_avail || got_data) { 771 while (frame_avail || got_data) {
1004 vpx_codec_iter_t iter = NULL; 772 vpx_codec_iter_t iter = NULL;
1005 vpx_image_t *img; 773 vpx_image_t *img;
1006 struct vpx_usec_timer timer; 774 struct vpx_usec_timer timer;
1007 int corrupted; 775 int corrupted;
1008 776
1009 frame_avail = 0; 777 frame_avail = 0;
1010 if (!stop_after || frame_in < stop_after) { 778 if (!stop_after || frame_in < stop_after) {
1011 if(!read_frame(&input, &buf, &buf_sz, &buf_alloc_sz)) { 779 if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
1012 frame_avail = 1; 780 frame_avail = 1;
1013 frame_in++; 781 frame_in++;
1014 782
1015 vpx_usec_timer_start(&timer); 783 vpx_usec_timer_start(&timer);
1016 784
1017 if (vpx_codec_decode(&decoder, buf, (unsigned int)buf_sz, NULL, 0)) { 785 if (vpx_codec_decode(&decoder, buf, bytes_in_buffer, NULL, 0)) {
1018 const char *detail = vpx_codec_error_detail(&decoder); 786 const char *detail = vpx_codec_error_detail(&decoder);
1019 fprintf(stderr, "Failed to decode frame: %s\n", 787 warn("Failed to decode frame %d: %s",
1020 vpx_codec_error(&decoder)); 788 frame_in, vpx_codec_error(&decoder));
1021 789
1022 if (detail) 790 if (detail)
1023 fprintf(stderr, " Additional information: %s\n", detail); 791 warn("Additional information: %s", detail);
1024 goto fail; 792 goto fail;
1025 } 793 }
1026 794
1027 vpx_usec_timer_mark(&timer); 795 vpx_usec_timer_mark(&timer);
1028 dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer); 796 dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);
1029 } 797 }
1030 } 798 }
1031 799
1032 vpx_usec_timer_start(&timer); 800 vpx_usec_timer_start(&timer);
1033 801
1034 got_data = 0; 802 got_data = 0;
1035 if ((img = vpx_codec_get_frame(&decoder, &iter))) { 803 if ((img = vpx_codec_get_frame(&decoder, &iter))) {
1036 ++frame_out; 804 ++frame_out;
1037 got_data = 1; 805 got_data = 1;
1038 } 806 }
1039 807
1040 vpx_usec_timer_mark(&timer); 808 vpx_usec_timer_mark(&timer);
1041 dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer); 809 dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);
1042 810
1043 if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) { 811 if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
1044 fprintf(stderr, "Failed VP8_GET_FRAME_CORRUPTED: %s\n", 812 warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder));
1045 vpx_codec_error(&decoder));
1046 goto fail; 813 goto fail;
1047 } 814 }
1048 frames_corrupted += corrupted; 815 frames_corrupted += corrupted;
1049 816
1050 if (progress) 817 if (progress)
1051 show_progress(frame_in, frame_out, dx_time); 818 show_progress(frame_in, frame_out, dx_time);
1052 819
1053 if (!noblit) { 820 if (!noblit) {
1054 if (frame_out == 1 && img && use_y4m) { 821 if (frame_out == 1 && img && use_y4m) {
1055 /* Write out the color format to terminate the header line */ 822 /* Write out the color format to terminate the header line */
1056 const char *color = 823 const char *color =
1057 img->fmt == VPX_IMG_FMT_444A ? "C444alpha\n" : 824 img->fmt == VPX_IMG_FMT_444A ? "C444alpha\n" :
1058 img->fmt == VPX_IMG_FMT_I444 ? "C444\n" : 825 img->fmt == VPX_IMG_FMT_I444 ? "C444\n" :
1059 img->fmt == VPX_IMG_FMT_I422 ? "C422\n" : 826 img->fmt == VPX_IMG_FMT_I422 ? "C422\n" :
1060 "C420jpeg\n"; 827 "C420jpeg\n";
1061 828
1062 out_put(out, (const unsigned char*)color, strlen(color), do_md5); 829 out_put(out, (const unsigned char*)color, strlen(color), do_md5);
1063 } 830 }
1064 831
1065 if (do_scale) { 832 if (do_scale) {
833 int stream_w = 0, stream_h = 0;
1066 if (img && frame_out == 1) { 834 if (img && frame_out == 1) {
1067 stream_w = img->d_w; 835 int display_size[2];
1068 stream_h = img->d_h; 836 if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE,
837 display_size)) {
838 // Fallback to use raw image size if display size not available.
839 stream_w = img->d_w;
840 stream_h = img->d_h;
841 } else {
842 stream_w = display_size[0];
843 stream_h = display_size[1];
844 }
1069 scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, 845 scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420,
1070 stream_w, stream_h, 16); 846 stream_w, stream_h, 16);
1071 } 847 }
1072 if (img && (img->d_w != stream_w || img->d_h != stream_h)) { 848 if (img && (img->d_w != stream_w || img->d_h != stream_h)) {
1073 assert(img->fmt == VPX_IMG_FMT_I420); 849 assert(img->fmt == VPX_IMG_FMT_I420);
1074 I420Scale(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], 850 I420Scale(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y],
1075 img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], 851 img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U],
1076 img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], 852 img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V],
1077 img->d_w, img->d_h, 853 img->d_w, img->d_h,
1078 scaled_img->planes[VPX_PLANE_Y], 854 scaled_img->planes[VPX_PLANE_Y],
1079 scaled_img->stride[VPX_PLANE_Y], 855 scaled_img->stride[VPX_PLANE_Y],
1080 scaled_img->planes[VPX_PLANE_U], 856 scaled_img->planes[VPX_PLANE_U],
1081 scaled_img->stride[VPX_PLANE_U], 857 scaled_img->stride[VPX_PLANE_U],
1082 scaled_img->planes[VPX_PLANE_V], 858 scaled_img->planes[VPX_PLANE_V],
1083 scaled_img->stride[VPX_PLANE_V], 859 scaled_img->stride[VPX_PLANE_V],
1084 stream_w, stream_h, 860 stream_w, stream_h,
1085 kFilterBox); 861 kFilterBox);
1086 img = scaled_img; 862 img = scaled_img;
1087 } 863 }
1088 } 864 }
1089
1090 if (img) { 865 if (img) {
1091 unsigned int y; 866 unsigned int y;
1092 char out_fn[PATH_MAX]; 867 char out_fn[PATH_MAX];
1093 uint8_t *buf; 868 uint8_t *buf;
1094 unsigned int c_w = 869 unsigned int c_w =
1095 img->x_chroma_shift ? (1 + img->d_w) >> img->x_chroma_shift 870 img->x_chroma_shift ? (1 + img->d_w) >> img->x_chroma_shift
1096 : img->d_w; 871 : img->d_w;
1097 unsigned int c_h = 872 unsigned int c_h =
1098 img->y_chroma_shift ? (1 + img->d_h) >> img->y_chroma_shift 873 img->y_chroma_shift ? (1 + img->d_h) >> img->y_chroma_shift
1099 : img->d_h; 874 : img->d_h;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 show_progress(frame_in, frame_out, dx_time); 917 show_progress(frame_in, frame_out, dx_time);
1143 fprintf(stderr, "\n"); 918 fprintf(stderr, "\n");
1144 } 919 }
1145 920
1146 if (frames_corrupted) 921 if (frames_corrupted)
1147 fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted); 922 fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);
1148 923
1149 fail: 924 fail:
1150 925
1151 if (vpx_codec_destroy(&decoder)) { 926 if (vpx_codec_destroy(&decoder)) {
1152 fprintf(stderr, "Failed to destroy decoder: %s\n", vpx_codec_error(&decoder) ); 927 fprintf(stderr, "Failed to destroy decoder: %s\n",
928 vpx_codec_error(&decoder));
1153 return EXIT_FAILURE; 929 return EXIT_FAILURE;
1154 } 930 }
1155 931
1156 if (single_file && !noblit) 932 if (single_file && !noblit)
1157 out_close(out, outfile, do_md5); 933 out_close(out, outfile, do_md5);
1158 934
1159 if (input.nestegg_ctx) 935 if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM)
1160 nestegg_destroy(input.nestegg_ctx); 936 webm_free(input.webm_ctx);
1161 if (input.kind != WEBM_FILE) 937 else
1162 free(buf); 938 free(buf);
939
940 if (scaled_img) vpx_img_free(scaled_img);
941 for (i = 0; i < num_external_frame_buffers; ++i) {
942 free(frame_buffers[i].data);
943 }
944 free(frame_buffers);
945
1163 fclose(infile); 946 fclose(infile);
1164 free(argv); 947 free(argv);
1165 948
1166 return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS; 949 return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS;
1167 } 950 }
1168 951
1169 int main(int argc, const char **argv_) { 952 int main(int argc, const char **argv_) {
1170 unsigned int loops = 1, i; 953 unsigned int loops = 1, i;
1171 char **argv, **argi, **argj; 954 char **argv, **argi, **argj;
1172 struct arg arg; 955 struct arg arg;
1173 int error = 0; 956 int error = 0;
1174 957
1175 argv = argv_dup(argc - 1, argv_ + 1); 958 argv = argv_dup(argc - 1, argv_ + 1);
1176 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { 959 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
1177 memset(&arg, 0, sizeof(arg)); 960 memset(&arg, 0, sizeof(arg));
1178 arg.argv_step = 1; 961 arg.argv_step = 1;
1179 962
1180 if (arg_match(&arg, &looparg, argi)) { 963 if (arg_match(&arg, &looparg, argi)) {
1181 loops = arg_parse_uint(&arg); 964 loops = arg_parse_uint(&arg);
1182 break; 965 break;
1183 } 966 }
1184 } 967 }
1185 free(argv); 968 free(argv);
1186 for (i = 0; !error && i < loops; i++) 969 for (i = 0; !error && i < loops; i++)
1187 error = main_loop(argc, argv_); 970 error = main_loop(argc, argv_);
1188 return error; 971 return error;
1189 } 972 }
OLDNEW
« no previous file with comments | « source/libvpx/vpx_scale/yv12config.h ('k') | source/libvpx/vpxenc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698