| OLD | NEW |
| 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 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 #endif | 30 #endif |
| 31 | 31 |
| 32 #include "./md5_utils.h" | 32 #include "./md5_utils.h" |
| 33 | 33 |
| 34 #include "./tools_common.h" | 34 #include "./tools_common.h" |
| 35 #include "./webmdec.h" | 35 #include "./webmdec.h" |
| 36 #include "./y4menc.h" | 36 #include "./y4menc.h" |
| 37 | 37 |
| 38 static const char *exec_name; | 38 static const char *exec_name; |
| 39 | 39 |
| 40 static const struct { | |
| 41 char const *name; | |
| 42 const vpx_codec_iface_t *(*iface)(void); | |
| 43 uint32_t fourcc; | |
| 44 } ifaces[] = { | |
| 45 #if CONFIG_VP8_DECODER | |
| 46 {"vp8", vpx_codec_vp8_dx, VP8_FOURCC}, | |
| 47 #endif | |
| 48 #if CONFIG_VP9_DECODER | |
| 49 {"vp9", vpx_codec_vp9_dx, VP9_FOURCC}, | |
| 50 #endif | |
| 51 }; | |
| 52 | |
| 53 struct VpxDecInputContext { | 40 struct VpxDecInputContext { |
| 54 struct VpxInputContext *vpx_input_ctx; | 41 struct VpxInputContext *vpx_input_ctx; |
| 55 struct WebmInputContext *webm_ctx; | 42 struct WebmInputContext *webm_ctx; |
| 56 }; | 43 }; |
| 57 | 44 |
| 58 static const arg_def_t looparg = ARG_DEF(NULL, "loops", 1, | 45 static const arg_def_t looparg = ARG_DEF(NULL, "loops", 1, |
| 59 "Number of times to decode the file"); | 46 "Number of times to decode the file"); |
| 60 static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, | 47 static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, |
| 61 "Codec to use"); | 48 "Codec to use"); |
| 62 static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, | 49 static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 81 "Output file name pattern (see below
)"); | 68 "Output file name pattern (see below
)"); |
| 82 static const arg_def_t threadsarg = ARG_DEF("t", "threads", 1, | 69 static const arg_def_t threadsarg = ARG_DEF("t", "threads", 1, |
| 83 "Max threads to use"); | 70 "Max threads to use"); |
| 84 static const arg_def_t verbosearg = ARG_DEF("v", "verbose", 0, | 71 static const arg_def_t verbosearg = ARG_DEF("v", "verbose", 0, |
| 85 "Show version string"); | 72 "Show version string"); |
| 86 static const arg_def_t error_concealment = ARG_DEF(NULL, "error-concealment", 0, | 73 static const arg_def_t error_concealment = ARG_DEF(NULL, "error-concealment", 0, |
| 87 "Enable decoder error-conceal
ment"); | 74 "Enable decoder error-conceal
ment"); |
| 88 static const arg_def_t scalearg = ARG_DEF("S", "scale", 0, | 75 static const arg_def_t scalearg = ARG_DEF("S", "scale", 0, |
| 89 "Scale output frames uniformly"); | 76 "Scale output frames uniformly"); |
| 90 | 77 |
| 78 static const arg_def_t fb_arg = |
| 79 ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use"); |
| 91 | 80 |
| 92 static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0, | 81 static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0, |
| 93 "Compute the MD5 sum of the decoded fram
e"); | 82 "Compute the MD5 sum of the decoded fram
e"); |
| 94 | 83 |
| 95 static const arg_def_t *all_args[] = { | 84 static const arg_def_t *all_args[] = { |
| 96 &codecarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg, | 85 &codecarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg, |
| 97 &progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile, | 86 &progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile, |
| 98 &threadsarg, &verbosearg, &scalearg, | 87 &threadsarg, &verbosearg, &scalearg, &fb_arg, |
| 99 &md5arg, | 88 &md5arg, |
| 100 &error_concealment, | 89 &error_concealment, |
| 101 NULL | 90 NULL |
| 102 }; | 91 }; |
| 103 | 92 |
| 104 #if CONFIG_VP8_DECODER | 93 #if CONFIG_VP8_DECODER |
| 105 static const arg_def_t addnoise_level = ARG_DEF(NULL, "noise-level", 1, | 94 static const arg_def_t addnoise_level = ARG_DEF(NULL, "noise-level", 1, |
| 106 "Enable VP8 postproc add noise")
; | 95 "Enable VP8 postproc add noise")
; |
| 107 static const arg_def_t deblock = ARG_DEF(NULL, "deblock", 0, | 96 static const arg_def_t deblock = ARG_DEF(NULL, "deblock", 0, |
| 108 "Enable VP8 deblocking"); | 97 "Enable VP8 deblocking"); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 fprintf(stderr, | 152 fprintf(stderr, |
| 164 "\n\t%%w - Frame width" | 153 "\n\t%%w - Frame width" |
| 165 "\n\t%%h - Frame height" | 154 "\n\t%%h - Frame height" |
| 166 "\n\t%%<n> - Frame number, zero padded to <n> places (1..9)" | 155 "\n\t%%<n> - Frame number, zero padded to <n> places (1..9)" |
| 167 "\n\n Pattern arguments are only supported in conjunction " | 156 "\n\n Pattern arguments are only supported in conjunction " |
| 168 "with the --yv12 and\n --i420 options. If the -o option is " | 157 "with the --yv12 and\n --i420 options. If the -o option is " |
| 169 "not specified, the output will be\n directed to stdout.\n" | 158 "not specified, the output will be\n directed to stdout.\n" |
| 170 ); | 159 ); |
| 171 fprintf(stderr, "\nIncluded decoders:\n\n"); | 160 fprintf(stderr, "\nIncluded decoders:\n\n"); |
| 172 | 161 |
| 173 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) | 162 for (i = 0; i < get_vpx_decoder_count(); ++i) { |
| 163 const VpxInterface *const decoder = get_vpx_decoder_by_index(i); |
| 174 fprintf(stderr, " %-6s - %s\n", | 164 fprintf(stderr, " %-6s - %s\n", |
| 175 ifaces[i].name, | 165 decoder->name, vpx_codec_iface_name(decoder->interface())); |
| 176 vpx_codec_iface_name(ifaces[i].iface())); | 166 } |
| 177 | 167 |
| 178 exit(EXIT_FAILURE); | 168 exit(EXIT_FAILURE); |
| 179 } | 169 } |
| 180 | 170 |
| 181 static int raw_read_frame(FILE *infile, uint8_t **buffer, | 171 static int raw_read_frame(FILE *infile, uint8_t **buffer, |
| 182 size_t *bytes_read, size_t *buffer_size) { | 172 size_t *bytes_read, size_t *buffer_size) { |
| 183 char raw_hdr[RAW_FRAME_HDR_SZ]; | 173 char raw_hdr[RAW_FRAME_HDR_SZ]; |
| 184 size_t frame_size = 0; | 174 size_t frame_size = 0; |
| 185 | 175 |
| 186 if (fread(raw_hdr, RAW_FRAME_HDR_SZ, 1, infile) != 1) { | 176 if (fread(raw_hdr, RAW_FRAME_HDR_SZ, 1, infile) != 1) { |
| 187 if (!feof(infile)) | 177 if (!feof(infile)) |
| 188 warn("Failed to read RAW frame size\n"); | 178 warn("Failed to read RAW frame size\n"); |
| 189 } else { | 179 } else { |
| 190 const int kCorruptFrameThreshold = 256 * 1024 * 1024; | 180 const size_t kCorruptFrameThreshold = 256 * 1024 * 1024; |
| 191 const int kFrameTooSmallThreshold = 256 * 1024; | 181 const size_t kFrameTooSmallThreshold = 256 * 1024; |
| 192 frame_size = mem_get_le32(raw_hdr); | 182 frame_size = mem_get_le32(raw_hdr); |
| 193 | 183 |
| 194 if (frame_size > kCorruptFrameThreshold) { | 184 if (frame_size > kCorruptFrameThreshold) { |
| 195 warn("Read invalid frame size (%u)\n", (unsigned int)frame_size); | 185 warn("Read invalid frame size (%u)\n", (unsigned int)frame_size); |
| 196 frame_size = 0; | 186 frame_size = 0; |
| 197 } | 187 } |
| 198 | 188 |
| 199 if (frame_size < kFrameTooSmallThreshold) { | 189 if (frame_size < kFrameTooSmallThreshold) { |
| 200 warn("Warning: Read invalid frame size (%u) - not a raw file?\n", | 190 warn("Warning: Read invalid frame size (%u) - not a raw file?\n", |
| 201 (unsigned int)frame_size); | 191 (unsigned int)frame_size); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 return raw_read_frame(input->vpx_input_ctx->file, | 224 return raw_read_frame(input->vpx_input_ctx->file, |
| 235 buf, bytes_in_buffer, buffer_size); | 225 buf, bytes_in_buffer, buffer_size); |
| 236 case FILE_TYPE_IVF: | 226 case FILE_TYPE_IVF: |
| 237 return ivf_read_frame(input->vpx_input_ctx->file, | 227 return ivf_read_frame(input->vpx_input_ctx->file, |
| 238 buf, bytes_in_buffer, buffer_size); | 228 buf, bytes_in_buffer, buffer_size); |
| 239 default: | 229 default: |
| 240 return 1; | 230 return 1; |
| 241 } | 231 } |
| 242 } | 232 } |
| 243 | 233 |
| 244 static int get_image_plane_width(int plane, const vpx_image_t *img) { | |
| 245 return (plane > 0 && img->x_chroma_shift > 0) ? | |
| 246 (img->d_w + 1) >> img->x_chroma_shift : | |
| 247 img->d_w; | |
| 248 } | |
| 249 | |
| 250 static int get_image_plane_height(int plane, const vpx_image_t *img) { | |
| 251 return (plane > 0 && img->y_chroma_shift > 0) ? | |
| 252 (img->d_h + 1) >> img->y_chroma_shift : | |
| 253 img->d_h; | |
| 254 } | |
| 255 | |
| 256 static void update_image_md5(const vpx_image_t *img, const int planes[3], | 234 static void update_image_md5(const vpx_image_t *img, const int planes[3], |
| 257 MD5Context *md5) { | 235 MD5Context *md5) { |
| 258 int i, y; | 236 int i, y; |
| 259 | 237 |
| 260 for (i = 0; i < 3; ++i) { | 238 for (i = 0; i < 3; ++i) { |
| 261 const int plane = planes[i]; | 239 const int plane = planes[i]; |
| 262 const unsigned char *buf = img->planes[plane]; | 240 const unsigned char *buf = img->planes[plane]; |
| 263 const int stride = img->stride[plane]; | 241 const int stride = img->stride[plane]; |
| 264 const int w = get_image_plane_width(plane, img); | 242 const int w = vpx_img_plane_width(img, plane); |
| 265 const int h = get_image_plane_height(plane, img); | 243 const int h = vpx_img_plane_height(img, plane); |
| 266 | 244 |
| 267 for (y = 0; y < h; ++y) { | 245 for (y = 0; y < h; ++y) { |
| 268 MD5Update(md5, buf, w); | 246 MD5Update(md5, buf, w); |
| 269 buf += stride; | 247 buf += stride; |
| 270 } | 248 } |
| 271 } | 249 } |
| 272 } | 250 } |
| 273 | 251 |
| 274 static void write_image_file(const vpx_image_t *img, const int planes[3], | 252 static void write_image_file(const vpx_image_t *img, const int planes[3], |
| 275 FILE *file) { | 253 FILE *file) { |
| 276 int i, y; | 254 int i, y; |
| 277 | 255 |
| 278 for (i = 0; i < 3; ++i) { | 256 for (i = 0; i < 3; ++i) { |
| 279 const int plane = planes[i]; | 257 const int plane = planes[i]; |
| 280 const unsigned char *buf = img->planes[plane]; | 258 const unsigned char *buf = img->planes[plane]; |
| 281 const int stride = img->stride[plane]; | 259 const int stride = img->stride[plane]; |
| 282 const int w = get_image_plane_width(plane, img); | 260 const int w = vpx_img_plane_width(img, plane); |
| 283 const int h = get_image_plane_height(plane, img); | 261 const int h = vpx_img_plane_height(img, plane); |
| 284 | 262 |
| 285 for (y = 0; y < h; ++y) { | 263 for (y = 0; y < h; ++y) { |
| 286 fwrite(buf, 1, w, file); | 264 fwrite(buf, 1, w, file); |
| 287 buf += stride; | 265 buf += stride; |
| 288 } | 266 } |
| 289 } | 267 } |
| 290 } | 268 } |
| 291 | 269 |
| 292 int file_is_raw(struct VpxInputContext *input) { | 270 int file_is_raw(struct VpxInputContext *input) { |
| 293 uint8_t buf[32]; | 271 uint8_t buf[32]; |
| 294 int is_raw = 0; | 272 int is_raw = 0; |
| 295 vpx_codec_stream_info_t si; | 273 vpx_codec_stream_info_t si; |
| 296 | 274 |
| 297 si.sz = sizeof(si); | 275 si.sz = sizeof(si); |
| 298 | 276 |
| 299 if (fread(buf, 1, 32, input->file) == 32) { | 277 if (fread(buf, 1, 32, input->file) == 32) { |
| 300 int i; | 278 int i; |
| 301 | 279 |
| 302 if (mem_get_le32(buf) < 256 * 1024 * 1024) { | 280 if (mem_get_le32(buf) < 256 * 1024 * 1024) { |
| 303 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) { | 281 for (i = 0; i < get_vpx_decoder_count(); ++i) { |
| 304 if (!vpx_codec_peek_stream_info(ifaces[i].iface(), | 282 const VpxInterface *const decoder = get_vpx_decoder_by_index(i); |
| 283 if (!vpx_codec_peek_stream_info(decoder->interface(), |
| 305 buf + 4, 32 - 4, &si)) { | 284 buf + 4, 32 - 4, &si)) { |
| 306 is_raw = 1; | 285 is_raw = 1; |
| 307 input->fourcc = ifaces[i].fourcc; | 286 input->fourcc = decoder->fourcc; |
| 308 input->width = si.w; | 287 input->width = si.w; |
| 309 input->height = si.h; | 288 input->height = si.h; |
| 310 input->framerate.numerator = 30; | 289 input->framerate.numerator = 30; |
| 311 input->framerate.denominator = 1; | 290 input->framerate.denominator = 1; |
| 312 break; | 291 break; |
| 313 } | 292 } |
| 314 } | 293 } |
| 315 } | 294 } |
| 316 } | 295 } |
| 317 | 296 |
| 318 rewind(input->file); | 297 rewind(input->file); |
| 319 return is_raw; | 298 return is_raw; |
| 320 } | 299 } |
| 321 | 300 |
| 322 void show_progress(int frame_in, int frame_out, unsigned long dx_time) { | 301 void show_progress(int frame_in, int frame_out, unsigned long dx_time) { |
| 323 fprintf(stderr, "%d decoded frames/%d showed frames in %lu us (%.2f fps)\r", | 302 fprintf(stderr, "%d decoded frames/%d showed frames in %lu us (%.2f fps)\r", |
| 324 frame_in, frame_out, dx_time, | 303 frame_in, frame_out, dx_time, |
| 325 (float)frame_out * 1000000.0 / (float)dx_time); | 304 (float)frame_out * 1000000.0 / (float)dx_time); |
| 326 } | 305 } |
| 327 | 306 |
| 307 struct ExternalFrameBuffer { |
| 308 uint8_t* data; |
| 309 size_t size; |
| 310 int in_use; |
| 311 }; |
| 312 |
| 313 struct ExternalFrameBufferList { |
| 314 int num_external_frame_buffers; |
| 315 struct ExternalFrameBuffer *ext_fb; |
| 316 }; |
| 317 |
| 318 // Callback used by libvpx to request an external frame buffer. |cb_priv| |
| 319 // Application private data passed into the set function. |min_size| is the |
| 320 // minimum size in bytes needed to decode the next frame. |fb| pointer to the |
| 321 // frame buffer. |
| 322 int get_vp9_frame_buffer(void *cb_priv, size_t min_size, |
| 323 vpx_codec_frame_buffer_t *fb) { |
| 324 int i; |
| 325 struct ExternalFrameBufferList *const ext_fb_list = |
| 326 (struct ExternalFrameBufferList *)cb_priv; |
| 327 if (ext_fb_list == NULL) |
| 328 return -1; |
| 329 |
| 330 // Find a free frame buffer. |
| 331 for (i = 0; i < ext_fb_list->num_external_frame_buffers; ++i) { |
| 332 if (!ext_fb_list->ext_fb[i].in_use) |
| 333 break; |
| 334 } |
| 335 |
| 336 if (i == ext_fb_list->num_external_frame_buffers) |
| 337 return -1; |
| 338 |
| 339 if (ext_fb_list->ext_fb[i].size < min_size) { |
| 340 free(ext_fb_list->ext_fb[i].data); |
| 341 ext_fb_list->ext_fb[i].data = (uint8_t *)malloc(min_size); |
| 342 if (!ext_fb_list->ext_fb[i].data) |
| 343 return -1; |
| 344 |
| 345 ext_fb_list->ext_fb[i].size = min_size; |
| 346 } |
| 347 |
| 348 fb->data = ext_fb_list->ext_fb[i].data; |
| 349 fb->size = ext_fb_list->ext_fb[i].size; |
| 350 ext_fb_list->ext_fb[i].in_use = 1; |
| 351 |
| 352 // Set the frame buffer's private data to point at the external frame buffer. |
| 353 fb->priv = &ext_fb_list->ext_fb[i]; |
| 354 return 0; |
| 355 } |
| 356 |
| 357 // Callback used by libvpx when there are no references to the frame buffer. |
| 358 // |cb_priv| user private data passed into the set function. |fb| pointer |
| 359 // to the frame buffer. |
| 360 int release_vp9_frame_buffer(void *cb_priv, |
| 361 vpx_codec_frame_buffer_t *fb) { |
| 362 struct ExternalFrameBuffer *const ext_fb = |
| 363 (struct ExternalFrameBuffer *)fb->priv; |
| 364 (void)cb_priv; |
| 365 ext_fb->in_use = 0; |
| 366 return 0; |
| 367 } |
| 368 |
| 328 void generate_filename(const char *pattern, char *out, size_t q_len, | 369 void generate_filename(const char *pattern, char *out, size_t q_len, |
| 329 unsigned int d_w, unsigned int d_h, | 370 unsigned int d_w, unsigned int d_h, |
| 330 unsigned int frame_in) { | 371 unsigned int frame_in) { |
| 331 const char *p = pattern; | 372 const char *p = pattern; |
| 332 char *q = out; | 373 char *q = out; |
| 333 | 374 |
| 334 do { | 375 do { |
| 335 char *next_pat = strchr(p, '%'); | 376 char *next_pat = strchr(p, '%'); |
| 336 | 377 |
| 337 if (p == next_pat) { | 378 if (p == next_pat) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 FILE *file = fopen(name, "wb"); | 475 FILE *file = fopen(name, "wb"); |
| 435 if (!file) | 476 if (!file) |
| 436 fatal("Failed to output file %s", name); | 477 fatal("Failed to output file %s", name); |
| 437 return file; | 478 return file; |
| 438 } | 479 } |
| 439 } | 480 } |
| 440 | 481 |
| 441 int main_loop(int argc, const char **argv_) { | 482 int main_loop(int argc, const char **argv_) { |
| 442 vpx_codec_ctx_t decoder; | 483 vpx_codec_ctx_t decoder; |
| 443 char *fn = NULL; | 484 char *fn = NULL; |
| 444 int i; | |
| 445 uint8_t *buf = NULL; | 485 uint8_t *buf = NULL; |
| 446 size_t bytes_in_buffer = 0, buffer_size = 0; | 486 size_t bytes_in_buffer = 0, buffer_size = 0; |
| 447 FILE *infile; | 487 FILE *infile; |
| 448 int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0; | 488 int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0; |
| 449 int do_md5 = 0, progress = 0; | 489 int do_md5 = 0, progress = 0; |
| 450 int stop_after = 0, postproc = 0, summary = 0, quiet = 1; | 490 int stop_after = 0, postproc = 0, summary = 0, quiet = 1; |
| 451 int arg_skip = 0; | 491 int arg_skip = 0; |
| 452 int ec_enabled = 0; | 492 int ec_enabled = 0; |
| 453 vpx_codec_iface_t *iface = NULL; | 493 const VpxInterface *interface = NULL; |
| 494 const VpxInterface *fourcc_interface = NULL; |
| 454 unsigned long dx_time = 0; | 495 unsigned long dx_time = 0; |
| 455 struct arg arg; | 496 struct arg arg; |
| 456 char **argv, **argi, **argj; | 497 char **argv, **argi, **argj; |
| 457 | 498 |
| 458 int single_file; | 499 int single_file; |
| 459 int use_y4m = 1; | 500 int use_y4m = 1; |
| 460 vpx_codec_dec_cfg_t cfg = {0}; | 501 vpx_codec_dec_cfg_t cfg = {0}; |
| 461 #if CONFIG_VP8_DECODER | 502 #if CONFIG_VP8_DECODER |
| 462 vp8_postproc_cfg_t vp8_pp_cfg = {0}; | 503 vp8_postproc_cfg_t vp8_pp_cfg = {0}; |
| 463 int vp8_dbg_color_ref_frame = 0; | 504 int vp8_dbg_color_ref_frame = 0; |
| 464 int vp8_dbg_color_mb_modes = 0; | 505 int vp8_dbg_color_mb_modes = 0; |
| 465 int vp8_dbg_color_b_modes = 0; | 506 int vp8_dbg_color_b_modes = 0; |
| 466 int vp8_dbg_display_mv = 0; | 507 int vp8_dbg_display_mv = 0; |
| 467 #endif | 508 #endif |
| 468 int frames_corrupted = 0; | 509 int frames_corrupted = 0; |
| 469 int dec_flags = 0; | 510 int dec_flags = 0; |
| 470 int do_scale = 0; | 511 int do_scale = 0; |
| 471 vpx_image_t *scaled_img = NULL; | 512 vpx_image_t *scaled_img = NULL; |
| 472 int frame_avail, got_data; | 513 int frame_avail, got_data; |
| 514 int num_external_frame_buffers = 0; |
| 515 struct ExternalFrameBufferList ext_fb_list = {0}; |
| 473 | 516 |
| 474 const char *outfile_pattern = NULL; | 517 const char *outfile_pattern = NULL; |
| 475 char outfile_name[PATH_MAX] = {0}; | 518 char outfile_name[PATH_MAX] = {0}; |
| 476 FILE *outfile = NULL; | 519 FILE *outfile = NULL; |
| 477 | 520 |
| 478 MD5Context md5_ctx; | 521 MD5Context md5_ctx; |
| 479 unsigned char md5_digest[16]; | 522 unsigned char md5_digest[16]; |
| 480 | 523 |
| 481 struct VpxDecInputContext input = {0}; | 524 struct VpxDecInputContext input = {0}; |
| 482 struct VpxInputContext vpx_input_ctx = {0}; | 525 struct VpxInputContext vpx_input_ctx = {0}; |
| 483 struct WebmInputContext webm_ctx = {0}; | 526 struct WebmInputContext webm_ctx = {0}; |
| 484 input.vpx_input_ctx = &vpx_input_ctx; | 527 input.vpx_input_ctx = &vpx_input_ctx; |
| 485 input.webm_ctx = &webm_ctx; | 528 input.webm_ctx = &webm_ctx; |
| 486 | 529 |
| 487 /* Parse command line */ | 530 /* Parse command line */ |
| 488 exec_name = argv_[0]; | 531 exec_name = argv_[0]; |
| 489 argv = argv_dup(argc - 1, argv_ + 1); | 532 argv = argv_dup(argc - 1, argv_ + 1); |
| 490 | 533 |
| 491 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { | 534 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { |
| 492 memset(&arg, 0, sizeof(arg)); | 535 memset(&arg, 0, sizeof(arg)); |
| 493 arg.argv_step = 1; | 536 arg.argv_step = 1; |
| 494 | 537 |
| 495 if (arg_match(&arg, &codecarg, argi)) { | 538 if (arg_match(&arg, &codecarg, argi)) { |
| 496 int j, k = -1; | 539 interface = get_vpx_decoder_by_name(arg.val); |
| 497 | 540 if (!interface) |
| 498 for (j = 0; j < sizeof(ifaces) / sizeof(ifaces[0]); j++) | 541 die("Error: Unrecognized argument (%s) to --codec\n", arg.val); |
| 499 if (!strcmp(ifaces[j].name, arg.val)) | |
| 500 k = j; | |
| 501 | |
| 502 if (k >= 0) | |
| 503 iface = ifaces[k].iface(); | |
| 504 else | |
| 505 die("Error: Unrecognized argument (%s) to --codec\n", | |
| 506 arg.val); | |
| 507 } else if (arg_match(&arg, &looparg, argi)) { | 542 } else if (arg_match(&arg, &looparg, argi)) { |
| 508 // no-op | 543 // no-op |
| 509 } else if (arg_match(&arg, &outputfile, argi)) | 544 } else if (arg_match(&arg, &outputfile, argi)) |
| 510 outfile_pattern = arg.val; | 545 outfile_pattern = arg.val; |
| 511 else if (arg_match(&arg, &use_yv12, argi)) { | 546 else if (arg_match(&arg, &use_yv12, argi)) { |
| 512 use_y4m = 0; | 547 use_y4m = 0; |
| 513 flipuv = 1; | 548 flipuv = 1; |
| 514 } else if (arg_match(&arg, &use_i420, argi)) { | 549 } else if (arg_match(&arg, &use_i420, argi)) { |
| 515 use_y4m = 0; | 550 use_y4m = 0; |
| 516 flipuv = 0; | 551 flipuv = 0; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 529 else if (arg_match(&arg, &md5arg, argi)) | 564 else if (arg_match(&arg, &md5arg, argi)) |
| 530 do_md5 = 1; | 565 do_md5 = 1; |
| 531 else if (arg_match(&arg, &summaryarg, argi)) | 566 else if (arg_match(&arg, &summaryarg, argi)) |
| 532 summary = 1; | 567 summary = 1; |
| 533 else if (arg_match(&arg, &threadsarg, argi)) | 568 else if (arg_match(&arg, &threadsarg, argi)) |
| 534 cfg.threads = arg_parse_uint(&arg); | 569 cfg.threads = arg_parse_uint(&arg); |
| 535 else if (arg_match(&arg, &verbosearg, argi)) | 570 else if (arg_match(&arg, &verbosearg, argi)) |
| 536 quiet = 0; | 571 quiet = 0; |
| 537 else if (arg_match(&arg, &scalearg, argi)) | 572 else if (arg_match(&arg, &scalearg, argi)) |
| 538 do_scale = 1; | 573 do_scale = 1; |
| 574 else if (arg_match(&arg, &fb_arg, argi)) |
| 575 num_external_frame_buffers = arg_parse_uint(&arg); |
| 539 | 576 |
| 540 #if CONFIG_VP8_DECODER | 577 #if CONFIG_VP8_DECODER |
| 541 else if (arg_match(&arg, &addnoise_level, argi)) { | 578 else if (arg_match(&arg, &addnoise_level, argi)) { |
| 542 postproc = 1; | 579 postproc = 1; |
| 543 vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE; | 580 vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE; |
| 544 vp8_pp_cfg.noise_level = arg_parse_uint(&arg); | 581 vp8_pp_cfg.noise_level = arg_parse_uint(&arg); |
| 545 } else if (arg_match(&arg, &demacroblock_level, argi)) { | 582 } else if (arg_match(&arg, &demacroblock_level, argi)) { |
| 546 postproc = 1; | 583 postproc = 1; |
| 547 vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK; | 584 vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK; |
| 548 vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg); | 585 vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 | 690 |
| 654 if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) { | 691 if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) { |
| 655 if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) { | 692 if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) { |
| 656 fprintf(stderr, "Failed to guess framerate -- error parsing " | 693 fprintf(stderr, "Failed to guess framerate -- error parsing " |
| 657 "webm file?\n"); | 694 "webm file?\n"); |
| 658 return EXIT_FAILURE; | 695 return EXIT_FAILURE; |
| 659 } | 696 } |
| 660 } | 697 } |
| 661 } | 698 } |
| 662 | 699 |
| 663 /* Try to determine the codec from the fourcc. */ | 700 fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc); |
| 664 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) | 701 if (interface && fourcc_interface && interface != fourcc_interface) |
| 665 if (vpx_input_ctx.fourcc == ifaces[i].fourcc) { | 702 warn("Header indicates codec: %s\n", fourcc_interface->name); |
| 666 vpx_codec_iface_t *vpx_iface = ifaces[i].iface(); | 703 else |
| 704 interface = fourcc_interface; |
| 667 | 705 |
| 668 if (iface && iface != vpx_iface) | 706 if (!interface) |
| 669 warn("Header indicates codec: %s\n", ifaces[i].name); | 707 interface = get_vpx_decoder_by_index(0); |
| 670 else | |
| 671 iface = vpx_iface; | |
| 672 | |
| 673 break; | |
| 674 } | |
| 675 | 708 |
| 676 dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) | | 709 dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) | |
| 677 (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0); | 710 (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0); |
| 678 if (vpx_codec_dec_init(&decoder, iface ? iface : ifaces[0].iface(), &cfg, | 711 if (vpx_codec_dec_init(&decoder, interface->interface(), &cfg, dec_flags)) { |
| 679 dec_flags)) { | 712 fprintf(stderr, "Failed to initialize decoder: %s\n", |
| 680 fprintf(stderr, "Failed to initialize decoder: %s\n", vpx_codec_error(&decod
er)); | 713 vpx_codec_error(&decoder)); |
| 681 return EXIT_FAILURE; | 714 return EXIT_FAILURE; |
| 682 } | 715 } |
| 683 | 716 |
| 684 if (!quiet) | 717 if (!quiet) |
| 685 fprintf(stderr, "%s\n", decoder.name); | 718 fprintf(stderr, "%s\n", decoder.name); |
| 686 | 719 |
| 687 #if CONFIG_VP8_DECODER | 720 #if CONFIG_VP8_DECODER |
| 688 | 721 |
| 689 if (vp8_pp_cfg.post_proc_flag | 722 if (vp8_pp_cfg.post_proc_flag |
| 690 && vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) { | 723 && vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 719 | 752 |
| 720 | 753 |
| 721 if (arg_skip) | 754 if (arg_skip) |
| 722 fprintf(stderr, "Skipping first %d frames.\n", arg_skip); | 755 fprintf(stderr, "Skipping first %d frames.\n", arg_skip); |
| 723 while (arg_skip) { | 756 while (arg_skip) { |
| 724 if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) | 757 if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) |
| 725 break; | 758 break; |
| 726 arg_skip--; | 759 arg_skip--; |
| 727 } | 760 } |
| 728 | 761 |
| 762 if (num_external_frame_buffers > 0) { |
| 763 ext_fb_list.num_external_frame_buffers = num_external_frame_buffers; |
| 764 ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc( |
| 765 num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb)); |
| 766 if (vpx_codec_set_frame_buffer_functions( |
| 767 &decoder, get_vp9_frame_buffer, release_vp9_frame_buffer, |
| 768 &ext_fb_list)) { |
| 769 fprintf(stderr, "Failed to configure external frame buffers: %s\n", |
| 770 vpx_codec_error(&decoder)); |
| 771 return EXIT_FAILURE; |
| 772 } |
| 773 } |
| 774 |
| 729 frame_avail = 1; | 775 frame_avail = 1; |
| 730 got_data = 0; | 776 got_data = 0; |
| 731 | 777 |
| 732 /* Decode file */ | 778 /* Decode file */ |
| 733 while (frame_avail || got_data) { | 779 while (frame_avail || got_data) { |
| 734 vpx_codec_iter_t iter = NULL; | 780 vpx_codec_iter_t iter = NULL; |
| 735 vpx_image_t *img; | 781 vpx_image_t *img; |
| 736 struct vpx_usec_timer timer; | 782 struct vpx_usec_timer timer; |
| 737 int corrupted; | 783 int corrupted; |
| 738 | 784 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 } | 937 } |
| 892 } | 938 } |
| 893 | 939 |
| 894 if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM) | 940 if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM) |
| 895 webm_free(input.webm_ctx); | 941 webm_free(input.webm_ctx); |
| 896 else | 942 else |
| 897 free(buf); | 943 free(buf); |
| 898 | 944 |
| 899 if (scaled_img) vpx_img_free(scaled_img); | 945 if (scaled_img) vpx_img_free(scaled_img); |
| 900 | 946 |
| 947 for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) { |
| 948 free(ext_fb_list.ext_fb[i].data); |
| 949 } |
| 950 free(ext_fb_list.ext_fb); |
| 951 |
| 901 fclose(infile); | 952 fclose(infile); |
| 902 free(argv); | 953 free(argv); |
| 903 | 954 |
| 904 return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS; | 955 return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS; |
| 905 } | 956 } |
| 906 | 957 |
| 907 int main(int argc, const char **argv_) { | 958 int main(int argc, const char **argv_) { |
| 908 unsigned int loops = 1, i; | 959 unsigned int loops = 1, i; |
| 909 char **argv, **argi, **argj; | 960 char **argv, **argi, **argj; |
| 910 struct arg arg; | 961 struct arg arg; |
| 911 int error = 0; | 962 int error = 0; |
| 912 | 963 |
| 913 argv = argv_dup(argc - 1, argv_ + 1); | 964 argv = argv_dup(argc - 1, argv_ + 1); |
| 914 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { | 965 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { |
| 915 memset(&arg, 0, sizeof(arg)); | 966 memset(&arg, 0, sizeof(arg)); |
| 916 arg.argv_step = 1; | 967 arg.argv_step = 1; |
| 917 | 968 |
| 918 if (arg_match(&arg, &looparg, argi)) { | 969 if (arg_match(&arg, &looparg, argi)) { |
| 919 loops = arg_parse_uint(&arg); | 970 loops = arg_parse_uint(&arg); |
| 920 break; | 971 break; |
| 921 } | 972 } |
| 922 } | 973 } |
| 923 free(argv); | 974 free(argv); |
| 924 for (i = 0; !error && i < loops; i++) | 975 for (i = 0; !error && i < loops; i++) |
| 925 error = main_loop(argc, argv_); | 976 error = main_loop(argc, argv_); |
| 926 return error; | 977 return error; |
| 927 } | 978 } |
| OLD | NEW |