| 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 } | 126 } |
| 127 | 127 |
| 128 static const arg_def_t debugmode = ARG_DEF("D", "debug", 0, | 128 static const arg_def_t debugmode = ARG_DEF("D", "debug", 0, |
| 129 "Debug mode (makes output determinist
ic)"); | 129 "Debug mode (makes output determinist
ic)"); |
| 130 static const arg_def_t outputfile = ARG_DEF("o", "output", 1, | 130 static const arg_def_t outputfile = ARG_DEF("o", "output", 1, |
| 131 "Output filename"); | 131 "Output filename"); |
| 132 static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, | 132 static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, |
| 133 "Input file is YV12 "); | 133 "Input file is YV12 "); |
| 134 static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0, | 134 static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0, |
| 135 "Input file is I420 (default)"); | 135 "Input file is I420 (default)"); |
| 136 static const arg_def_t use_i422 = ARG_DEF(NULL, "i422", 0, |
| 137 "Input file is I422"); |
| 138 static const arg_def_t use_i444 = ARG_DEF(NULL, "i444", 0, |
| 139 "Input file is I444"); |
| 136 static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, | 140 static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, |
| 137 "Codec to use"); | 141 "Codec to use"); |
| 138 static const arg_def_t passes = ARG_DEF("p", "passes", 1, | 142 static const arg_def_t passes = ARG_DEF("p", "passes", 1, |
| 139 "Number of passes (1/2)"); | 143 "Number of passes (1/2)"); |
| 140 static const arg_def_t pass_arg = ARG_DEF(NULL, "pass", 1, | 144 static const arg_def_t pass_arg = ARG_DEF(NULL, "pass", 1, |
| 141 "Pass to execute (1/2)"); | 145 "Pass to execute (1/2)"); |
| 142 static const arg_def_t fpf_name = ARG_DEF(NULL, "fpf", 1, | 146 static const arg_def_t fpf_name = ARG_DEF(NULL, "fpf", 1, |
| 143 "First pass statistics file na
me"); | 147 "First pass statistics file na
me"); |
| 148 #if CONFIG_FP_MB_STATS |
| 149 static const arg_def_t fpmbf_name = ARG_DEF(NULL, "fpmbf", 1, |
| 150 "First pass block statistics file name"); |
| 151 #endif |
| 144 static const arg_def_t limit = ARG_DEF(NULL, "limit", 1, | 152 static const arg_def_t limit = ARG_DEF(NULL, "limit", 1, |
| 145 "Stop encoding after n input frames"); | 153 "Stop encoding after n input frames"); |
| 146 static const arg_def_t skip = ARG_DEF(NULL, "skip", 1, | 154 static const arg_def_t skip = ARG_DEF(NULL, "skip", 1, |
| 147 "Skip the first n input frames"); | 155 "Skip the first n input frames"); |
| 148 static const arg_def_t deadline = ARG_DEF("d", "deadline", 1, | 156 static const arg_def_t deadline = ARG_DEF("d", "deadline", 1, |
| 149 "Deadline per frame (usec)"); | 157 "Deadline per frame (usec)"); |
| 150 static const arg_def_t best_dl = ARG_DEF(NULL, "best", 0, | 158 static const arg_def_t best_dl = ARG_DEF(NULL, "best", 0, |
| 151 "Use Best Quality Deadline"); | 159 "Use Best Quality Deadline"); |
| 152 static const arg_def_t good_dl = ARG_DEF(NULL, "good", 0, | 160 static const arg_def_t good_dl = ARG_DEF(NULL, "good", 0, |
| 153 "Use Good Quality Deadline"); | 161 "Use Good Quality Deadline"); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 "Stereo 3D video format",
stereo_mode_enum); | 230 "Stereo 3D video format",
stereo_mode_enum); |
| 223 #endif | 231 #endif |
| 224 static const arg_def_t timebase = ARG_DEF(NULL, "timebase", 1, | 232 static const arg_def_t timebase = ARG_DEF(NULL, "timebase", 1, |
| 225 "Output timestamp precision (f
ractional seconds)"); | 233 "Output timestamp precision (f
ractional seconds)"); |
| 226 static const arg_def_t error_resilient = ARG_DEF(NULL, "error-resilient", 1, | 234 static const arg_def_t error_resilient = ARG_DEF(NULL, "error-resilient", 1, |
| 227 "Enable error resiliency featu
res"); | 235 "Enable error resiliency featu
res"); |
| 228 static const arg_def_t lag_in_frames = ARG_DEF(NULL, "lag-in-frames", 1, | 236 static const arg_def_t lag_in_frames = ARG_DEF(NULL, "lag-in-frames", 1, |
| 229 "Max number of frames to lag")
; | 237 "Max number of frames to lag")
; |
| 230 | 238 |
| 231 static const arg_def_t *global_args[] = { | 239 static const arg_def_t *global_args[] = { |
| 232 &use_yv12, &use_i420, &usage, &threads, &profile, | 240 &use_yv12, &use_i420, &use_i422, &use_i444, |
| 241 &usage, &threads, &profile, |
| 233 &width, &height, | 242 &width, &height, |
| 234 #if CONFIG_WEBM_IO | 243 #if CONFIG_WEBM_IO |
| 235 &stereo_mode, | 244 &stereo_mode, |
| 236 #endif | 245 #endif |
| 237 &timebase, &framerate, | 246 &timebase, &framerate, |
| 238 &error_resilient, | 247 &error_resilient, |
| 239 &lag_in_frames, NULL | 248 &lag_in_frames, NULL |
| 240 }; | 249 }; |
| 241 | 250 |
| 242 static const arg_def_t dropframe_thresh = ARG_DEF(NULL, "drop-frame", 1, | 251 static const arg_def_t dropframe_thresh = ARG_DEF(NULL, "drop-frame", 1, |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 arg_show_usage(stderr, vp9_args); | 424 arg_show_usage(stderr, vp9_args); |
| 416 #endif | 425 #endif |
| 417 fprintf(stderr, "\nStream timebase (--timebase):\n" | 426 fprintf(stderr, "\nStream timebase (--timebase):\n" |
| 418 " The desired precision of timestamps in the output, expressed\n" | 427 " The desired precision of timestamps in the output, expressed\n" |
| 419 " in fractional seconds. Default is 1/1000.\n"); | 428 " in fractional seconds. Default is 1/1000.\n"); |
| 420 fprintf(stderr, "\nIncluded encoders:\n\n"); | 429 fprintf(stderr, "\nIncluded encoders:\n\n"); |
| 421 | 430 |
| 422 for (i = 0; i < get_vpx_encoder_count(); ++i) { | 431 for (i = 0; i < get_vpx_encoder_count(); ++i) { |
| 423 const VpxInterface *const encoder = get_vpx_encoder_by_index(i); | 432 const VpxInterface *const encoder = get_vpx_encoder_by_index(i); |
| 424 fprintf(stderr, " %-6s - %s\n", | 433 fprintf(stderr, " %-6s - %s\n", |
| 425 encoder->name, vpx_codec_iface_name(encoder->interface())); | 434 encoder->name, vpx_codec_iface_name(encoder->codec_interface())); |
| 426 } | 435 } |
| 427 | 436 |
| 428 exit(EXIT_FAILURE); | 437 exit(EXIT_FAILURE); |
| 429 } | 438 } |
| 430 | 439 |
| 431 #define mmin(a, b) ((a) < (b) ? (a) : (b)) | 440 #define mmin(a, b) ((a) < (b) ? (a) : (b)) |
| 432 static void find_mismatch(const vpx_image_t *const img1, | 441 static void find_mismatch(const vpx_image_t *const img1, |
| 433 const vpx_image_t *const img2, | 442 const vpx_image_t *const img2, |
| 434 int yloc[4], int uloc[4], int vloc[4]) { | 443 int yloc[4], int uloc[4], int vloc[4]) { |
| 435 const uint32_t bsize = 64; | 444 const uint32_t bsize = 64; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 #if !CONFIG_WEBM_IO | 574 #if !CONFIG_WEBM_IO |
| 566 typedef int stereo_format_t; | 575 typedef int stereo_format_t; |
| 567 struct EbmlGlobal { int debug; }; | 576 struct EbmlGlobal { int debug; }; |
| 568 #endif | 577 #endif |
| 569 | 578 |
| 570 /* Per-stream configuration */ | 579 /* Per-stream configuration */ |
| 571 struct stream_config { | 580 struct stream_config { |
| 572 struct vpx_codec_enc_cfg cfg; | 581 struct vpx_codec_enc_cfg cfg; |
| 573 const char *out_fn; | 582 const char *out_fn; |
| 574 const char *stats_fn; | 583 const char *stats_fn; |
| 584 #if CONFIG_FP_MB_STATS |
| 585 const char *fpmb_stats_fn; |
| 586 #endif |
| 575 stereo_format_t stereo_fmt; | 587 stereo_format_t stereo_fmt; |
| 576 int arg_ctrls[ARG_CTRL_CNT_MAX][2]; | 588 int arg_ctrls[ARG_CTRL_CNT_MAX][2]; |
| 577 int arg_ctrl_cnt; | 589 int arg_ctrl_cnt; |
| 578 int write_webm; | 590 int write_webm; |
| 579 int have_kf_max_dist; | 591 int have_kf_max_dist; |
| 580 }; | 592 }; |
| 581 | 593 |
| 582 | 594 |
| 583 struct stream_state { | 595 struct stream_state { |
| 584 int index; | 596 int index; |
| 585 struct stream_state *next; | 597 struct stream_state *next; |
| 586 struct stream_config config; | 598 struct stream_config config; |
| 587 FILE *file; | 599 FILE *file; |
| 588 struct rate_hist *rate_hist; | 600 struct rate_hist *rate_hist; |
| 589 struct EbmlGlobal ebml; | 601 struct EbmlGlobal ebml; |
| 590 uint64_t psnr_sse_total; | 602 uint64_t psnr_sse_total; |
| 591 uint64_t psnr_samples_total; | 603 uint64_t psnr_samples_total; |
| 592 double psnr_totals[4]; | 604 double psnr_totals[4]; |
| 593 int psnr_count; | 605 int psnr_count; |
| 594 int counts[64]; | 606 int counts[64]; |
| 595 vpx_codec_ctx_t encoder; | 607 vpx_codec_ctx_t encoder; |
| 596 unsigned int frames_out; | 608 unsigned int frames_out; |
| 597 uint64_t cx_time; | 609 uint64_t cx_time; |
| 598 size_t nbytes; | 610 size_t nbytes; |
| 599 stats_io_t stats; | 611 stats_io_t stats; |
| 612 #if CONFIG_FP_MB_STATS |
| 613 stats_io_t fpmb_stats; |
| 614 #endif |
| 600 struct vpx_image *img; | 615 struct vpx_image *img; |
| 601 vpx_codec_ctx_t decoder; | 616 vpx_codec_ctx_t decoder; |
| 602 int mismatch_seen; | 617 int mismatch_seen; |
| 603 }; | 618 }; |
| 604 | 619 |
| 605 | 620 |
| 606 void validate_positive_rational(const char *msg, | 621 void validate_positive_rational(const char *msg, |
| 607 struct vpx_rational *rat) { | 622 struct vpx_rational *rat) { |
| 608 if (rat->den < 0) { | 623 if (rat->den < 0) { |
| 609 rat->num *= -1; | 624 rat->num *= -1; |
| 610 rat->den *= -1; | 625 rat->den *= -1; |
| 611 } | 626 } |
| 612 | 627 |
| 613 if (rat->num < 0) | 628 if (rat->num < 0) |
| 614 die("Error: %s must be positive\n", msg); | 629 die("Error: %s must be positive\n", msg); |
| 615 | 630 |
| 616 if (!rat->den) | 631 if (!rat->den) |
| 617 die("Error: %s has zero denominator\n", msg); | 632 die("Error: %s has zero denominator\n", msg); |
| 618 } | 633 } |
| 619 | 634 |
| 620 | 635 |
| 621 static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { | 636 static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { |
| 622 char **argi, **argj; | 637 char **argi, **argj; |
| 623 struct arg arg; | 638 struct arg arg; |
| 624 | 639 |
| 625 /* Initialize default parameters */ | 640 /* Initialize default parameters */ |
| 626 memset(global, 0, sizeof(*global)); | 641 memset(global, 0, sizeof(*global)); |
| 627 global->codec = get_vpx_encoder_by_index(0); | 642 global->codec = get_vpx_encoder_by_index(0); |
| 628 global->passes = 0; | 643 global->passes = 0; |
| 629 global->use_i420 = 1; | 644 global->color_type = I420; |
| 630 /* Assign default deadline to good quality */ | 645 /* Assign default deadline to good quality */ |
| 631 global->deadline = VPX_DL_GOOD_QUALITY; | 646 global->deadline = VPX_DL_GOOD_QUALITY; |
| 632 | 647 |
| 633 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { | 648 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { |
| 634 arg.argv_step = 1; | 649 arg.argv_step = 1; |
| 635 | 650 |
| 636 if (arg_match(&arg, &codecarg, argi)) { | 651 if (arg_match(&arg, &codecarg, argi)) { |
| 637 global->codec = get_vpx_encoder_by_name(arg.val); | 652 global->codec = get_vpx_encoder_by_name(arg.val); |
| 638 if (!global->codec) | 653 if (!global->codec) |
| 639 die("Error: Unrecognized argument (%s) to --codec\n", arg.val); | 654 die("Error: Unrecognized argument (%s) to --codec\n", arg.val); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 652 global->usage = arg_parse_uint(&arg); | 667 global->usage = arg_parse_uint(&arg); |
| 653 else if (arg_match(&arg, &deadline, argi)) | 668 else if (arg_match(&arg, &deadline, argi)) |
| 654 global->deadline = arg_parse_uint(&arg); | 669 global->deadline = arg_parse_uint(&arg); |
| 655 else if (arg_match(&arg, &best_dl, argi)) | 670 else if (arg_match(&arg, &best_dl, argi)) |
| 656 global->deadline = VPX_DL_BEST_QUALITY; | 671 global->deadline = VPX_DL_BEST_QUALITY; |
| 657 else if (arg_match(&arg, &good_dl, argi)) | 672 else if (arg_match(&arg, &good_dl, argi)) |
| 658 global->deadline = VPX_DL_GOOD_QUALITY; | 673 global->deadline = VPX_DL_GOOD_QUALITY; |
| 659 else if (arg_match(&arg, &rt_dl, argi)) | 674 else if (arg_match(&arg, &rt_dl, argi)) |
| 660 global->deadline = VPX_DL_REALTIME; | 675 global->deadline = VPX_DL_REALTIME; |
| 661 else if (arg_match(&arg, &use_yv12, argi)) | 676 else if (arg_match(&arg, &use_yv12, argi)) |
| 662 global->use_i420 = 0; | 677 global->color_type = YV12; |
| 663 else if (arg_match(&arg, &use_i420, argi)) | 678 else if (arg_match(&arg, &use_i420, argi)) |
| 664 global->use_i420 = 1; | 679 global->color_type = I420; |
| 680 else if (arg_match(&arg, &use_i422, argi)) |
| 681 global->color_type = I422; |
| 682 else if (arg_match(&arg, &use_i444, argi)) |
| 683 global->color_type = I444; |
| 665 else if (arg_match(&arg, &quietarg, argi)) | 684 else if (arg_match(&arg, &quietarg, argi)) |
| 666 global->quiet = 1; | 685 global->quiet = 1; |
| 667 else if (arg_match(&arg, &verbosearg, argi)) | 686 else if (arg_match(&arg, &verbosearg, argi)) |
| 668 global->verbose = 1; | 687 global->verbose = 1; |
| 669 else if (arg_match(&arg, &limit, argi)) | 688 else if (arg_match(&arg, &limit, argi)) |
| 670 global->limit = arg_parse_uint(&arg); | 689 global->limit = arg_parse_uint(&arg); |
| 671 else if (arg_match(&arg, &skip, argi)) | 690 else if (arg_match(&arg, &skip, argi)) |
| 672 global->skip_frames = arg_parse_uint(&arg); | 691 global->skip_frames = arg_parse_uint(&arg); |
| 673 else if (arg_match(&arg, &psnrarg, argi)) | 692 else if (arg_match(&arg, &psnrarg, argi)) |
| 674 global->show_psnr = 1; | 693 global->show_psnr = 1; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 if (!stream) | 800 if (!stream) |
| 782 fatal("Failed to allocate new stream."); | 801 fatal("Failed to allocate new stream."); |
| 783 if (prev) { | 802 if (prev) { |
| 784 memcpy(stream, prev, sizeof(*stream)); | 803 memcpy(stream, prev, sizeof(*stream)); |
| 785 stream->index++; | 804 stream->index++; |
| 786 prev->next = stream; | 805 prev->next = stream; |
| 787 } else { | 806 } else { |
| 788 vpx_codec_err_t res; | 807 vpx_codec_err_t res; |
| 789 | 808 |
| 790 /* Populate encoder configuration */ | 809 /* Populate encoder configuration */ |
| 791 res = vpx_codec_enc_config_default(global->codec->interface(), | 810 res = vpx_codec_enc_config_default(global->codec->codec_interface(), |
| 792 &stream->config.cfg, | 811 &stream->config.cfg, |
| 793 global->usage); | 812 global->usage); |
| 794 if (res) | 813 if (res) |
| 795 fatal("Failed to get config: %s\n", vpx_codec_err_to_string(res)); | 814 fatal("Failed to get config: %s\n", vpx_codec_err_to_string(res)); |
| 796 | 815 |
| 797 /* Change the default timebase to a high enough value so that the | 816 /* Change the default timebase to a high enough value so that the |
| 798 * encoder will always create strictly increasing timestamps. | 817 * encoder will always create strictly increasing timestamps. |
| 799 */ | 818 */ |
| 800 stream->config.cfg.g_timebase.den = 1000; | 819 stream->config.cfg.g_timebase.den = 1000; |
| 801 | 820 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 } else if (!strcmp(*argj, "--")) { | 885 } else if (!strcmp(*argj, "--")) { |
| 867 eos_mark_found = 1; | 886 eos_mark_found = 1; |
| 868 continue; | 887 continue; |
| 869 } | 888 } |
| 870 | 889 |
| 871 if (0) { | 890 if (0) { |
| 872 } else if (arg_match(&arg, &outputfile, argi)) { | 891 } else if (arg_match(&arg, &outputfile, argi)) { |
| 873 config->out_fn = arg.val; | 892 config->out_fn = arg.val; |
| 874 } else if (arg_match(&arg, &fpf_name, argi)) { | 893 } else if (arg_match(&arg, &fpf_name, argi)) { |
| 875 config->stats_fn = arg.val; | 894 config->stats_fn = arg.val; |
| 895 #if CONFIG_FP_MB_STATS |
| 896 } else if (arg_match(&arg, &fpmbf_name, argi)) { |
| 897 config->fpmb_stats_fn = arg.val; |
| 898 #endif |
| 876 } else if (arg_match(&arg, &use_ivf, argi)) { | 899 } else if (arg_match(&arg, &use_ivf, argi)) { |
| 877 config->write_webm = 0; | 900 config->write_webm = 0; |
| 878 } else if (arg_match(&arg, &threads, argi)) { | 901 } else if (arg_match(&arg, &threads, argi)) { |
| 879 config->cfg.g_threads = arg_parse_uint(&arg); | 902 config->cfg.g_threads = arg_parse_uint(&arg); |
| 880 } else if (arg_match(&arg, &profile, argi)) { | 903 } else if (arg_match(&arg, &profile, argi)) { |
| 881 config->cfg.g_profile = arg_parse_uint(&arg); | 904 config->cfg.g_profile = arg_parse_uint(&arg); |
| 882 } else if (arg_match(&arg, &width, argi)) { | 905 } else if (arg_match(&arg, &width, argi)) { |
| 883 config->cfg.g_w = arg_parse_uint(&arg); | 906 config->cfg.g_w = arg_parse_uint(&arg); |
| 884 } else if (arg_match(&arg, &height, argi)) { | 907 } else if (arg_match(&arg, &height, argi)) { |
| 885 config->cfg.g_h = arg_parse_uint(&arg); | 908 config->cfg.g_h = arg_parse_uint(&arg); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 958 match = 1; | 981 match = 1; |
| 959 | 982 |
| 960 /* Point either to the next free element or the first | 983 /* Point either to the next free element or the first |
| 961 * instance of this control. | 984 * instance of this control. |
| 962 */ | 985 */ |
| 963 for (j = 0; j < config->arg_ctrl_cnt; j++) | 986 for (j = 0; j < config->arg_ctrl_cnt; j++) |
| 964 if (config->arg_ctrls[j][0] == ctrl_args_map[i]) | 987 if (config->arg_ctrls[j][0] == ctrl_args_map[i]) |
| 965 break; | 988 break; |
| 966 | 989 |
| 967 /* Update/insert */ | 990 /* Update/insert */ |
| 968 assert(j < ARG_CTRL_CNT_MAX); | 991 assert(j < (int)ARG_CTRL_CNT_MAX); |
| 969 if (j < ARG_CTRL_CNT_MAX) { | 992 if (j < (int)ARG_CTRL_CNT_MAX) { |
| 970 config->arg_ctrls[j][0] = ctrl_args_map[i]; | 993 config->arg_ctrls[j][0] = ctrl_args_map[i]; |
| 971 config->arg_ctrls[j][1] = arg_parse_enum_or_int(&arg); | 994 config->arg_ctrls[j][1] = arg_parse_enum_or_int(&arg); |
| 972 if (j == config->arg_ctrl_cnt) | 995 if (j == config->arg_ctrl_cnt) |
| 973 config->arg_ctrl_cnt++; | 996 config->arg_ctrl_cnt++; |
| 974 } | 997 } |
| 975 | 998 |
| 976 } | 999 } |
| 977 } | 1000 } |
| 978 if (!match) | 1001 if (!match) |
| 979 argj++; | 1002 argj++; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 } | 1045 } |
| 1023 | 1046 |
| 1024 /* Check for two streams sharing a stats file. */ | 1047 /* Check for two streams sharing a stats file. */ |
| 1025 if (streami != stream) { | 1048 if (streami != stream) { |
| 1026 const char *a = stream->config.stats_fn; | 1049 const char *a = stream->config.stats_fn; |
| 1027 const char *b = streami->config.stats_fn; | 1050 const char *b = streami->config.stats_fn; |
| 1028 if (a && b && !strcmp(a, b)) | 1051 if (a && b && !strcmp(a, b)) |
| 1029 fatal("Stream %d: duplicate stats file (from stream %d)", | 1052 fatal("Stream %d: duplicate stats file (from stream %d)", |
| 1030 streami->index, stream->index); | 1053 streami->index, stream->index); |
| 1031 } | 1054 } |
| 1055 |
| 1056 #if CONFIG_FP_MB_STATS |
| 1057 /* Check for two streams sharing a mb stats file. */ |
| 1058 if (streami != stream) { |
| 1059 const char *a = stream->config.fpmb_stats_fn; |
| 1060 const char *b = streami->config.fpmb_stats_fn; |
| 1061 if (a && b && !strcmp(a, b)) |
| 1062 fatal("Stream %d: duplicate mb stats file (from stream %d)", |
| 1063 streami->index, stream->index); |
| 1064 } |
| 1065 #endif |
| 1032 } | 1066 } |
| 1033 } | 1067 } |
| 1034 | 1068 |
| 1035 | 1069 |
| 1036 static void set_stream_dimensions(struct stream_state *stream, | 1070 static void set_stream_dimensions(struct stream_state *stream, |
| 1037 unsigned int w, | 1071 unsigned int w, |
| 1038 unsigned int h) { | 1072 unsigned int h) { |
| 1039 if (!stream->config.cfg.g_w) { | 1073 if (!stream->config.cfg.g_w) { |
| 1040 if (!stream->config.cfg.g_h) | 1074 if (!stream->config.cfg.g_h) |
| 1041 stream->config.cfg.g_w = w; | 1075 stream->config.cfg.g_w = w; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 | 1114 |
| 1081 static void show_stream_config(struct stream_state *stream, | 1115 static void show_stream_config(struct stream_state *stream, |
| 1082 struct VpxEncoderConfig *global, | 1116 struct VpxEncoderConfig *global, |
| 1083 struct VpxInputContext *input) { | 1117 struct VpxInputContext *input) { |
| 1084 | 1118 |
| 1085 #define SHOW(field) \ | 1119 #define SHOW(field) \ |
| 1086 fprintf(stderr, " %-28s = %d\n", #field, stream->config.cfg.field) | 1120 fprintf(stderr, " %-28s = %d\n", #field, stream->config.cfg.field) |
| 1087 | 1121 |
| 1088 if (stream->index == 0) { | 1122 if (stream->index == 0) { |
| 1089 fprintf(stderr, "Codec: %s\n", | 1123 fprintf(stderr, "Codec: %s\n", |
| 1090 vpx_codec_iface_name(global->codec->interface())); | 1124 vpx_codec_iface_name(global->codec->codec_interface())); |
| 1091 fprintf(stderr, "Source file: %s File Type: %s Format: %s\n", | 1125 fprintf(stderr, "Source file: %s File Type: %s Format: %s\n", |
| 1092 input->filename, | 1126 input->filename, |
| 1093 file_type_to_string(input->file_type), | 1127 file_type_to_string(input->file_type), |
| 1094 image_format_to_string(input->fmt)); | 1128 image_format_to_string(input->fmt)); |
| 1095 } | 1129 } |
| 1096 if (stream->next || stream->index) | 1130 if (stream->next || stream->index) |
| 1097 fprintf(stderr, "\nStream Index: %d\n", stream->index); | 1131 fprintf(stderr, "\nStream Index: %d\n", stream->index); |
| 1098 fprintf(stderr, "Destination file: %s\n", stream->config.out_fn); | 1132 fprintf(stderr, "Destination file: %s\n", stream->config.out_fn); |
| 1099 fprintf(stderr, "Encoder parameters:\n"); | 1133 fprintf(stderr, "Encoder parameters:\n"); |
| 1100 | 1134 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 int pass) { | 1227 int pass) { |
| 1194 if (stream->config.stats_fn) { | 1228 if (stream->config.stats_fn) { |
| 1195 if (!stats_open_file(&stream->stats, stream->config.stats_fn, | 1229 if (!stats_open_file(&stream->stats, stream->config.stats_fn, |
| 1196 pass)) | 1230 pass)) |
| 1197 fatal("Failed to open statistics store"); | 1231 fatal("Failed to open statistics store"); |
| 1198 } else { | 1232 } else { |
| 1199 if (!stats_open_mem(&stream->stats, pass)) | 1233 if (!stats_open_mem(&stream->stats, pass)) |
| 1200 fatal("Failed to open statistics store"); | 1234 fatal("Failed to open statistics store"); |
| 1201 } | 1235 } |
| 1202 | 1236 |
| 1237 #if CONFIG_FP_MB_STATS |
| 1238 if (stream->config.fpmb_stats_fn) { |
| 1239 if (!stats_open_file(&stream->fpmb_stats, |
| 1240 stream->config.fpmb_stats_fn, pass)) |
| 1241 fatal("Failed to open mb statistics store"); |
| 1242 } else { |
| 1243 if (!stats_open_mem(&stream->fpmb_stats, pass)) |
| 1244 fatal("Failed to open mb statistics store"); |
| 1245 } |
| 1246 #endif |
| 1247 |
| 1203 stream->config.cfg.g_pass = global->passes == 2 | 1248 stream->config.cfg.g_pass = global->passes == 2 |
| 1204 ? pass ? VPX_RC_LAST_PASS : VPX_RC_FIRST_PASS | 1249 ? pass ? VPX_RC_LAST_PASS : VPX_RC_FIRST_PASS |
| 1205 : VPX_RC_ONE_PASS; | 1250 : VPX_RC_ONE_PASS; |
| 1206 if (pass) | 1251 if (pass) { |
| 1207 stream->config.cfg.rc_twopass_stats_in = stats_get(&stream->stats); | 1252 stream->config.cfg.rc_twopass_stats_in = stats_get(&stream->stats); |
| 1253 #if CONFIG_FP_MB_STATS |
| 1254 stream->config.cfg.rc_firstpass_mb_stats_in = |
| 1255 stats_get(&stream->fpmb_stats); |
| 1256 #endif |
| 1257 } |
| 1208 | 1258 |
| 1209 stream->cx_time = 0; | 1259 stream->cx_time = 0; |
| 1210 stream->nbytes = 0; | 1260 stream->nbytes = 0; |
| 1211 stream->frames_out = 0; | 1261 stream->frames_out = 0; |
| 1212 } | 1262 } |
| 1213 | 1263 |
| 1214 | 1264 |
| 1215 static void initialize_encoder(struct stream_state *stream, | 1265 static void initialize_encoder(struct stream_state *stream, |
| 1216 struct VpxEncoderConfig *global) { | 1266 struct VpxEncoderConfig *global) { |
| 1217 int i; | 1267 int i; |
| 1218 int flags = 0; | 1268 int flags = 0; |
| 1219 | 1269 |
| 1220 flags |= global->show_psnr ? VPX_CODEC_USE_PSNR : 0; | 1270 flags |= global->show_psnr ? VPX_CODEC_USE_PSNR : 0; |
| 1221 flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0; | 1271 flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0; |
| 1222 | 1272 |
| 1223 /* Construct Encoder Context */ | 1273 /* Construct Encoder Context */ |
| 1224 vpx_codec_enc_init(&stream->encoder, global->codec->interface(), | 1274 vpx_codec_enc_init(&stream->encoder, global->codec->codec_interface(), |
| 1225 &stream->config.cfg, flags); | 1275 &stream->config.cfg, flags); |
| 1226 ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder"); | 1276 ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder"); |
| 1227 | 1277 |
| 1228 /* Note that we bypass the vpx_codec_control wrapper macro because | 1278 /* Note that we bypass the vpx_codec_control wrapper macro because |
| 1229 * we're being clever to store the control IDs in an array. Real | 1279 * we're being clever to store the control IDs in an array. Real |
| 1230 * applications will want to make use of the enumerations directly | 1280 * applications will want to make use of the enumerations directly |
| 1231 */ | 1281 */ |
| 1232 for (i = 0; i < stream->config.arg_ctrl_cnt; i++) { | 1282 for (i = 0; i < stream->config.arg_ctrl_cnt; i++) { |
| 1233 int ctrl = stream->config.arg_ctrls[i][0]; | 1283 int ctrl = stream->config.arg_ctrls[i][0]; |
| 1234 int value = stream->config.arg_ctrls[i][1]; | 1284 int value = stream->config.arg_ctrls[i][1]; |
| 1235 if (vpx_codec_control_(&stream->encoder, ctrl, value)) | 1285 if (vpx_codec_control_(&stream->encoder, ctrl, value)) |
| 1236 fprintf(stderr, "Error: Tried to set control %d = %d\n", | 1286 fprintf(stderr, "Error: Tried to set control %d = %d\n", |
| 1237 ctrl, value); | 1287 ctrl, value); |
| 1238 | 1288 |
| 1239 ctx_exit_on_error(&stream->encoder, "Failed to control codec"); | 1289 ctx_exit_on_error(&stream->encoder, "Failed to control codec"); |
| 1240 } | 1290 } |
| 1241 | 1291 |
| 1242 #if CONFIG_DECODERS | 1292 #if CONFIG_DECODERS |
| 1243 if (global->test_decode != TEST_DECODE_OFF) { | 1293 if (global->test_decode != TEST_DECODE_OFF) { |
| 1244 const VpxInterface *decoder = get_vpx_decoder_by_name(global->codec->name); | 1294 const VpxInterface *decoder = get_vpx_decoder_by_name(global->codec->name); |
| 1245 vpx_codec_dec_init(&stream->decoder, decoder->interface(), NULL, 0); | 1295 vpx_codec_dec_init(&stream->decoder, decoder->codec_interface(), NULL, 0); |
| 1246 } | 1296 } |
| 1247 #endif | 1297 #endif |
| 1248 } | 1298 } |
| 1249 | 1299 |
| 1250 | 1300 |
| 1251 static void encode_frame(struct stream_state *stream, | 1301 static void encode_frame(struct stream_state *stream, |
| 1252 struct VpxEncoderConfig *global, | 1302 struct VpxEncoderConfig *global, |
| 1253 struct vpx_image *img, | 1303 struct vpx_image *img, |
| 1254 unsigned int frames_in) { | 1304 unsigned int frames_in) { |
| 1255 vpx_codec_pts_t frame_start, next_frame_start; | 1305 vpx_codec_pts_t frame_start, next_frame_start; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 } | 1431 } |
| 1382 #endif | 1432 #endif |
| 1383 break; | 1433 break; |
| 1384 case VPX_CODEC_STATS_PKT: | 1434 case VPX_CODEC_STATS_PKT: |
| 1385 stream->frames_out++; | 1435 stream->frames_out++; |
| 1386 stats_write(&stream->stats, | 1436 stats_write(&stream->stats, |
| 1387 pkt->data.twopass_stats.buf, | 1437 pkt->data.twopass_stats.buf, |
| 1388 pkt->data.twopass_stats.sz); | 1438 pkt->data.twopass_stats.sz); |
| 1389 stream->nbytes += pkt->data.raw.sz; | 1439 stream->nbytes += pkt->data.raw.sz; |
| 1390 break; | 1440 break; |
| 1441 #if CONFIG_FP_MB_STATS |
| 1442 case VPX_CODEC_FPMB_STATS_PKT: |
| 1443 stats_write(&stream->fpmb_stats, |
| 1444 pkt->data.firstpass_mb_stats.buf, |
| 1445 pkt->data.firstpass_mb_stats.sz); |
| 1446 stream->nbytes += pkt->data.raw.sz; |
| 1447 break; |
| 1448 #endif |
| 1391 case VPX_CODEC_PSNR_PKT: | 1449 case VPX_CODEC_PSNR_PKT: |
| 1392 | 1450 |
| 1393 if (global->show_psnr) { | 1451 if (global->show_psnr) { |
| 1394 int i; | 1452 int i; |
| 1395 | 1453 |
| 1396 stream->psnr_sse_total += pkt->data.psnr.sse[0]; | 1454 stream->psnr_sse_total += pkt->data.psnr.sse[0]; |
| 1397 stream->psnr_samples_total += pkt->data.psnr.samples[0]; | 1455 stream->psnr_samples_total += pkt->data.psnr.samples[0]; |
| 1398 for (i = 0; i < 4; i++) { | 1456 for (i = 0; i < 4; i++) { |
| 1399 if (!global->quiet) | 1457 if (!global->quiet) |
| 1400 fprintf(stderr, "%.3f ", pkt->data.psnr.psnr[i]); | 1458 fprintf(stderr, "%.3f ", pkt->data.psnr.psnr[i]); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1510 fprintf(stderr, "[%3s unknown] ", label); | 1568 fprintf(stderr, "[%3s unknown] ", label); |
| 1511 } | 1569 } |
| 1512 } | 1570 } |
| 1513 | 1571 |
| 1514 | 1572 |
| 1515 int main(int argc, const char **argv_) { | 1573 int main(int argc, const char **argv_) { |
| 1516 int pass; | 1574 int pass; |
| 1517 vpx_image_t raw; | 1575 vpx_image_t raw; |
| 1518 int frame_avail, got_data; | 1576 int frame_avail, got_data; |
| 1519 | 1577 |
| 1520 struct VpxInputContext input = {0}; | 1578 struct VpxInputContext input; |
| 1521 struct VpxEncoderConfig global; | 1579 struct VpxEncoderConfig global; |
| 1522 struct stream_state *streams = NULL; | 1580 struct stream_state *streams = NULL; |
| 1523 char **argv, **argi; | 1581 char **argv, **argi; |
| 1524 uint64_t cx_time = 0; | 1582 uint64_t cx_time = 0; |
| 1525 int stream_cnt = 0; | 1583 int stream_cnt = 0; |
| 1526 int res = 0; | 1584 int res = 0; |
| 1527 | 1585 |
| 1586 memset(&input, 0, sizeof(input)); |
| 1528 exec_name = argv_[0]; | 1587 exec_name = argv_[0]; |
| 1529 | 1588 |
| 1530 if (argc < 3) | 1589 if (argc < 3) |
| 1531 usage_exit(); | 1590 usage_exit(); |
| 1532 | 1591 |
| 1533 /* Setup default input stream settings */ | 1592 /* Setup default input stream settings */ |
| 1534 input.framerate.numerator = 30; | 1593 input.framerate.numerator = 30; |
| 1535 input.framerate.denominator = 1; | 1594 input.framerate.denominator = 1; |
| 1536 input.only_i420 = 1; | 1595 input.only_i420 = 1; |
| 1537 input.bit_depth = 0; | 1596 input.bit_depth = 0; |
| 1538 | 1597 |
| 1539 /* First parse the global configuration values, because we want to apply | 1598 /* First parse the global configuration values, because we want to apply |
| 1540 * other parameters on top of the default configuration provided by the | 1599 * other parameters on top of the default configuration provided by the |
| 1541 * codec. | 1600 * codec. |
| 1542 */ | 1601 */ |
| 1543 argv = argv_dup(argc - 1, argv_ + 1); | 1602 argv = argv_dup(argc - 1, argv_ + 1); |
| 1544 parse_global_config(&global, argv); | 1603 parse_global_config(&global, argv); |
| 1545 | 1604 |
| 1546 input.fmt = global.use_i420 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_YV12; | 1605 switch (global.color_type) { |
| 1606 case I420: |
| 1607 input.fmt = VPX_IMG_FMT_I420; |
| 1608 break; |
| 1609 case I422: |
| 1610 input.fmt = VPX_IMG_FMT_I422; |
| 1611 break; |
| 1612 case I444: |
| 1613 input.fmt = VPX_IMG_FMT_I444; |
| 1614 break; |
| 1615 case YV12: |
| 1616 input.fmt = VPX_IMG_FMT_YV12; |
| 1617 break; |
| 1618 } |
| 1547 | 1619 |
| 1548 { | 1620 { |
| 1549 /* Now parse each stream's parameters. Using a local scope here | 1621 /* Now parse each stream's parameters. Using a local scope here |
| 1550 * due to the use of 'stream' as loop variable in FOREACH_STREAM | 1622 * due to the use of 'stream' as loop variable in FOREACH_STREAM |
| 1551 * loops | 1623 * loops |
| 1552 */ | 1624 */ |
| 1553 struct stream_state *stream = NULL; | 1625 struct stream_state *stream = NULL; |
| 1554 | 1626 |
| 1555 do { | 1627 do { |
| 1556 stream = new_stream(&global, stream); | 1628 stream = new_stream(&global, stream); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 | 1842 |
| 1771 close_input_file(&input); | 1843 close_input_file(&input); |
| 1772 | 1844 |
| 1773 if (global.test_decode == TEST_DECODE_FATAL) { | 1845 if (global.test_decode == TEST_DECODE_FATAL) { |
| 1774 FOREACH_STREAM(res |= stream->mismatch_seen); | 1846 FOREACH_STREAM(res |= stream->mismatch_seen); |
| 1775 } | 1847 } |
| 1776 FOREACH_STREAM(close_output_file(stream, global.codec->fourcc)); | 1848 FOREACH_STREAM(close_output_file(stream, global.codec->fourcc)); |
| 1777 | 1849 |
| 1778 FOREACH_STREAM(stats_close(&stream->stats, global.passes - 1)); | 1850 FOREACH_STREAM(stats_close(&stream->stats, global.passes - 1)); |
| 1779 | 1851 |
| 1852 #if CONFIG_FP_MB_STATS |
| 1853 FOREACH_STREAM(stats_close(&stream->fpmb_stats, global.passes - 1)); |
| 1854 #endif |
| 1855 |
| 1780 if (global.pass) | 1856 if (global.pass) |
| 1781 break; | 1857 break; |
| 1782 } | 1858 } |
| 1783 | 1859 |
| 1784 if (global.show_q_hist_buckets) | 1860 if (global.show_q_hist_buckets) |
| 1785 FOREACH_STREAM(show_q_histogram(stream->counts, | 1861 FOREACH_STREAM(show_q_histogram(stream->counts, |
| 1786 global.show_q_hist_buckets)); | 1862 global.show_q_hist_buckets)); |
| 1787 | 1863 |
| 1788 if (global.show_rate_hist_buckets) | 1864 if (global.show_rate_hist_buckets) |
| 1789 FOREACH_STREAM(show_rate_histogram(stream->rate_hist, | 1865 FOREACH_STREAM(show_rate_histogram(stream->rate_hist, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1806 } | 1882 } |
| 1807 fclose(f); | 1883 fclose(f); |
| 1808 }); | 1884 }); |
| 1809 #endif | 1885 #endif |
| 1810 | 1886 |
| 1811 vpx_img_free(&raw); | 1887 vpx_img_free(&raw); |
| 1812 free(argv); | 1888 free(argv); |
| 1813 free(streams); | 1889 free(streams); |
| 1814 return res ? EXIT_FAILURE : EXIT_SUCCESS; | 1890 return res ? EXIT_FAILURE : EXIT_SUCCESS; |
| 1815 } | 1891 } |
| OLD | NEW |