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 |