/* * Copyright (c) 2010 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
if (shorthelp) {
fprintf(fout, "Use --help to see the full list of options.\n"); return;
}
fprintf(fout, "Options:\n");
arg_show_usage(fout, all_args); #if CONFIG_VP8_DECODER
fprintf(fout, "\nVP8 Postprocessing Options:\n");
arg_show_usage(fout, vp8_pp_args); #endif
fprintf(fout, "\nOutput File Patterns:\n\n" " The -o argument specifies the name of the file(s) to " "write to. If the\n argument does not include any escape " "characters, the output will be\n written to a single file. " "Otherwise, the filename will be calculated by\n expanding " "the following escape characters:\n");
fprintf(fout, "\n\t%%w - Frame width" "\n\t%%h - Frame height" "\n\t%%<n> - Frame number, zero padded to <n> places (1..9)" "\n\n Pattern arguments are only supported in conjunction " "with the --yv12 and\n --i420 options. If the -o option is " "not specified, the output will be\n directed to stdout.\n");
fprintf(fout, "\nIncluded decoders:\n\n");
for (i = 0; i < get_vpx_decoder_count(); ++i) { const VpxInterface *const decoder = get_vpx_decoder_by_index(i);
fprintf(fout, " %-6s - %s\n", decoder->name,
vpx_codec_iface_name(decoder->codec_interface()));
}
}
staticvoid show_progress(int frame_in, int frame_out, uint64_t dx_time) {
fprintf(stderr, "%d decoded frames/%d showed frames in %" PRId64 " us (%.2f fps)\r",
frame_in, frame_out, dx_time,
(double)frame_out * 1000000.0 / (double)dx_time);
}
struct ExternalFrameBuffer {
uint8_t *data;
size_t size; int in_use;
};
struct ExternalFrameBufferList { int num_external_frame_buffers; struct ExternalFrameBuffer *ext_fb;
};
// Callback used by libvpx to request an external frame buffer. |cb_priv| // Application private data passed into the set function. |min_size| is the // minimum size in bytes needed to decode the next frame. |fb| pointer to the // frame buffer. staticint get_vp9_frame_buffer(void *cb_priv, size_t min_size,
vpx_codec_frame_buffer_t *fb) { int i; struct ExternalFrameBufferList *const ext_fb_list =
(struct ExternalFrameBufferList *)cb_priv; if (ext_fb_list == NULL) return -1;
// Find a free frame buffer. for (i = 0; i < ext_fb_list->num_external_frame_buffers; ++i) { if (!ext_fb_list->ext_fb[i].in_use) break;
}
if (i == ext_fb_list->num_external_frame_buffers) return -1;
if (ext_fb_list->ext_fb[i].size < min_size) {
free(ext_fb_list->ext_fb[i].data);
ext_fb_list->ext_fb[i].data = (uint8_t *)calloc(min_size, sizeof(uint8_t)); if (!ext_fb_list->ext_fb[i].data) return -1;
// Set the frame buffer's private data to point at the external frame buffer.
fb->priv = &ext_fb_list->ext_fb[i]; return 0;
}
// Callback used by libvpx when there are no references to the frame buffer. // |cb_priv| user private data passed into the set function. |fb| pointer // to the frame buffer. staticint release_vp9_frame_buffer(void *cb_priv,
vpx_codec_frame_buffer_t *fb) { struct ExternalFrameBuffer *const ext_fb =
(struct ExternalFrameBuffer *)fb->priv;
(void)cb_priv;
ext_fb->in_use = 0; return 0;
}
do {
p = strchr(p, '%'); if (p && p[1] >= '1' && p[1] <= '9') return 0; // pattern contains sequence number, so it's not unique if (p) p++;
} while (p);
return 1;
}
staticvoid print_md5(unsignedchar digest[16], constchar *filename) { int i;
for (i = 0; i < 16; ++i) printf("%02x", digest[i]);
printf(" %s\n", filename);
}
static FILE *open_outfile(constchar *name) { if (strcmp("-", name) == 0) {
set_binary_mode(stdout); return stdout;
} else {
FILE *file = fopen(name, "wb"); if (!file) fatal("Failed to open output file '%s'", name); return file;
}
}
if (!noblit && single_file) {
generate_filename(outfile_pattern, outfile_name, PATH_MAX,
vpx_input_ctx.width, vpx_input_ctx.height, 0); if (do_md5)
MD5Init(&md5_ctx); else
outfile = open_outfile(outfile_name);
}
if (use_y4m && !noblit) { if (!single_file) {
fprintf(stderr, "YUV4MPEG2 not supported with output patterns," " try --i420 or --yv12 or --rawvideo.\n"); return EXIT_FAILURE;
}
#if CONFIG_WEBM_IO if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) { if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) {
fprintf(stderr, "Failed to guess framerate -- error parsing " "webm file?\n"); return EXIT_FAILURE;
}
} #endif
}
if (!interface) interface = get_vpx_decoder_by_index(0);
dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
(ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0); if (vpx_codec_dec_init(&decoder, interface->codec_interface(), &cfg,
dec_flags)) {
fprintf(stderr, "Failed to initialize decoder: %s\n",
vpx_codec_error(&decoder)); goto fail2;
} if (svc_decoding) { if (vpx_codec_control(&decoder, VP9_DECODE_SVC_SPATIAL_LAYER,
svc_spatial_layer)) {
fprintf(stderr, "Failed to set spatial layer for svc decode: %s\n",
vpx_codec_error(&decoder)); goto fail;
}
} if (interface->fourcc == VP9_FOURCC &&
vpx_codec_control(&decoder, VP9D_SET_ROW_MT, enable_row_mt)) {
fprintf(stderr, "Failed to set decoder in row multi-thread mode: %s\n",
vpx_codec_error(&decoder)); goto fail;
} if (interface->fourcc == VP9_FOURCC &&
vpx_codec_control(&decoder, VP9D_SET_LOOP_FILTER_OPT, enable_lpf_opt)) {
fprintf(stderr, "Failed to set decoder in optimized loopfilter mode: %s\n",
vpx_codec_error(&decoder)); goto fail;
} if (!quiet) fprintf(stderr, "%s\n", decoder.name);
#if CONFIG_VP8_DECODER if (vp8_pp_cfg.post_proc_flag &&
vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) {
fprintf(stderr, "Failed to configure postproc: %s\n",
vpx_codec_error(&decoder)); goto fail;
} #endif
if (arg_skip) fprintf(stderr, "Skipping first %d frames.\n", arg_skip); while (arg_skip) { if (dec_read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) break;
arg_skip--;
}
if (num_external_frame_buffers > 0) {
ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb)); if (!ext_fb_list.ext_fb) {
fprintf(stderr, "Failed to allocate ExternalFrameBuffer\n"); goto fail;
} if (vpx_codec_set_frame_buffer_functions(&decoder, get_vp9_frame_buffer,
release_vp9_frame_buffer,
&ext_fb_list)) {
fprintf(stderr, "Failed to configure external frame buffers: %s\n",
vpx_codec_error(&decoder)); goto fail;
}
}
frame_avail = 1;
got_data = 0;
if (framestats_file) fprintf(framestats_file, "bytes,qp\n");
/* Decode file */ while (frame_avail || got_data) {
vpx_codec_iter_t iter = NULL;
vpx_image_t *img; struct vpx_usec_timer timer; int corrupted = 0;
frame_avail = 0; if (!stop_after || frame_in < stop_after) { if (!dec_read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
frame_avail = 1;
frame_in++;
vpx_usec_timer_start(&timer);
if (vpx_codec_decode(&decoder, buf, (unsignedint)bytes_in_buffer, NULL,
0)) { constchar *detail = vpx_codec_error_detail(&decoder);
warn("Failed to decode frame %d: %s", frame_in,
vpx_codec_error(&decoder)); if (detail) warn("Additional information: %s", detail);
corrupted = 1; if (!keep_going) goto fail;
}
if (framestats_file) { int qp; if (vpx_codec_control(&decoder, VPXD_GET_LAST_QUANTIZER, &qp)) {
warn("Failed VPXD_GET_LAST_QUANTIZER: %s",
vpx_codec_error(&decoder)); if (!keep_going) goto fail;
}
fprintf(framestats_file, "%d,%d\n", (int)bytes_in_buffer, qp);
}
if (do_scale) { if (frame_out == 1) { // If the output frames are to be scaled to a fixed display size then // use the width and height specified in the container. If either of // these is set to 0, use the display size set in the first frame // header. If that is unavailable, use the raw decoded size of the // first decoded frame. int render_width = vpx_input_ctx.width; int render_height = vpx_input_ctx.height; if (!render_width || !render_height) { int render_size[2]; if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE,
render_size)) { // As last resort use size of first frame as display size.
render_width = img->d_w;
render_height = img->d_h;
} else {
render_width = render_size[0];
render_height = render_size[1];
}
}
scaled_img =
vpx_img_alloc(NULL, img->fmt, render_width, render_height, 16); if (!scaled_img) {
fprintf(stderr, "Failed to allocate scaled image (%d x %d)\n",
render_width, render_height); goto fail;
}
scaled_img->bit_depth = img->bit_depth;
}
if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) { #if CONFIG_LIBYUV
libyuv_scale(img, scaled_img, kFilterBox);
img = scaled_img; #else
fprintf(stderr, "Failed to scale output frame: %s.\n" "Scaling is disabled in this configuration. " "To enable scaling, configure with --enable-libyuv\n",
vpx_codec_error(&decoder)); goto fail; #endif
}
} #if CONFIG_VP9_HIGHBITDEPTH // Default to codec bit depth if output bit depth not set if (!output_bit_depth && single_file && !do_md5) {
output_bit_depth = img->bit_depth;
} // Shift up or down if necessary if (output_bit_depth != 0 && output_bit_depth != img->bit_depth) { const vpx_img_fmt_t shifted_fmt =
output_bit_depth == 8
? img->fmt ^ (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH)
: img->fmt | VPX_IMG_FMT_HIGHBITDEPTH; if (img_shifted &&
img_shifted_realloc_required(img, img_shifted, shifted_fmt)) {
vpx_img_free(img_shifted);
img_shifted = NULL;
} if (!img_shifted) {
img_shifted =
vpx_img_alloc(NULL, shifted_fmt, img->d_w, img->d_h, 16); if (!img_shifted) {
fprintf(stderr, "Failed to allocate image\n"); goto fail;
}
img_shifted->bit_depth = output_bit_depth;
} if (output_bit_depth > img->bit_depth) {
vpx_img_upshift(img_shifted, img, output_bit_depth - img->bit_depth);
} else {
vpx_img_downshift(img_shifted, img,
img->bit_depth - output_bit_depth);
}
img = img_shifted;
} #endif
if (single_file) { if (use_y4m) { char y4m_buf[Y4M_BUFFER_SIZE] = { 0 };
size_t len = 0; if (img->fmt == VPX_IMG_FMT_I440 || img->fmt == VPX_IMG_FMT_I44016) {
fprintf(stderr, "Cannot produce y4m output for 440 sampling.\n"); goto fail;
} if (frame_out == 1) { // Y4M file header
len = y4m_write_file_header(
y4m_buf, sizeof(y4m_buf), vpx_input_ctx.width,
vpx_input_ctx.height, &vpx_input_ctx.framerate, img->fmt,
img->bit_depth); if (do_md5) {
MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsignedint)len);
} else {
fputs(y4m_buf, outfile);
}
}
// Y4M frame header
len = y4m_write_frame_header(y4m_buf, sizeof(y4m_buf)); if (do_md5) {
MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsignedint)len);
} else {
fputs(y4m_buf, outfile);
}
} else { if (frame_out == 1) { // Check if --yv12 or --i420 options are consistent with the // bit-stream decoded if (opt_i420) { if (img->fmt != VPX_IMG_FMT_I420 &&
img->fmt != VPX_IMG_FMT_I42016) {
fprintf(stderr, "Cannot produce i420 output for bit-stream.\n"); goto fail;
}
} if (opt_yv12) { if ((img->fmt != VPX_IMG_FMT_I420 &&
img->fmt != VPX_IMG_FMT_YV12) ||
img->bit_depth != 8) {
fprintf(stderr, "Cannot produce yv12 output for bit-stream.\n"); goto fail;
}
}
}
}
if (arg_match(&arg, &looparg, argi)) {
loops = arg_parse_uint(&arg); break;
}
}
free(argv); for (i = 0; !error && i < loops; i++) error = main_loop(argc, argv_); return error;
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.15Bemerkung:
(vorverarbeitet am 2026-04-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.