| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 double layer_encoding_bitrate[VPX_TS_MAX_LAYERS]; | 63 double layer_encoding_bitrate[VPX_TS_MAX_LAYERS]; |
| 64 // Average of the short-time encoder actual bitrate. | 64 // Average of the short-time encoder actual bitrate. |
| 65 // TODO(marpan): Should we add these short-time stats for each layer? | 65 // TODO(marpan): Should we add these short-time stats for each layer? |
| 66 double avg_st_encoding_bitrate; | 66 double avg_st_encoding_bitrate; |
| 67 // Variance of the short-time encoder actual bitrate. | 67 // Variance of the short-time encoder actual bitrate. |
| 68 double variance_st_encoding_bitrate; | 68 double variance_st_encoding_bitrate; |
| 69 // Window (number of frames) for computing short-timee encoding bitrate. | 69 // Window (number of frames) for computing short-timee encoding bitrate. |
| 70 int window_size; | 70 int window_size; |
| 71 // Number of window measurements. | 71 // Number of window measurements. |
| 72 int window_count; | 72 int window_count; |
| 73 int layer_target_bitrate[VPX_MAX_LAYERS]; |
| 73 }; | 74 }; |
| 74 | 75 |
| 75 // Note: these rate control metrics assume only 1 key frame in the | 76 // Note: these rate control metrics assume only 1 key frame in the |
| 76 // sequence (i.e., first frame only). So for temporal pattern# 7 | 77 // sequence (i.e., first frame only). So for temporal pattern# 7 |
| 77 // (which has key frame for every frame on base layer), the metrics | 78 // (which has key frame for every frame on base layer), the metrics |
| 78 // computation will be off/wrong. | 79 // computation will be off/wrong. |
| 79 // TODO(marpan): Update these metrics to account for multiple key frames | 80 // TODO(marpan): Update these metrics to account for multiple key frames |
| 80 // in the stream. | 81 // in the stream. |
| 81 static void set_rate_control_metrics(struct RateControlMetrics *rc, | 82 static void set_rate_control_metrics(struct RateControlMetrics *rc, |
| 82 vpx_codec_enc_cfg_t *cfg) { | 83 vpx_codec_enc_cfg_t *cfg) { |
| 83 unsigned int i = 0; | 84 unsigned int i = 0; |
| 84 // Set the layer (cumulative) framerate and the target layer (non-cumulative) | 85 // Set the layer (cumulative) framerate and the target layer (non-cumulative) |
| 85 // per-frame-bandwidth, for the rate control encoding stats below. | 86 // per-frame-bandwidth, for the rate control encoding stats below. |
| 86 const double framerate = cfg->g_timebase.den / cfg->g_timebase.num; | 87 const double framerate = cfg->g_timebase.den / cfg->g_timebase.num; |
| 87 rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0]; | 88 rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0]; |
| 88 rc->layer_pfb[0] = 1000.0 * cfg->ts_target_bitrate[0] / | 89 rc->layer_pfb[0] = 1000.0 * rc->layer_target_bitrate[0] / |
| 89 rc->layer_framerate[0]; | 90 rc->layer_framerate[0]; |
| 90 for (i = 0; i < cfg->ts_number_layers; ++i) { | 91 for (i = 0; i < cfg->ts_number_layers; ++i) { |
| 91 if (i > 0) { | 92 if (i > 0) { |
| 92 rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i]; | 93 rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i]; |
| 93 rc->layer_pfb[i] = 1000.0 * | 94 rc->layer_pfb[i] = 1000.0 * |
| 94 (cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) / | 95 (rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) / |
| 95 (rc->layer_framerate[i] - rc->layer_framerate[i - 1]); | 96 (rc->layer_framerate[i] - rc->layer_framerate[i - 1]); |
| 96 } | 97 } |
| 97 rc->layer_input_frames[i] = 0; | 98 rc->layer_input_frames[i] = 0; |
| 98 rc->layer_enc_frames[i] = 0; | 99 rc->layer_enc_frames[i] = 0; |
| 99 rc->layer_tot_enc_frames[i] = 0; | 100 rc->layer_tot_enc_frames[i] = 0; |
| 100 rc->layer_encoding_bitrate[i] = 0.0; | 101 rc->layer_encoding_bitrate[i] = 0.0; |
| 101 rc->layer_avg_frame_size[i] = 0.0; | 102 rc->layer_avg_frame_size[i] = 0.0; |
| 102 rc->layer_avg_rate_mismatch[i] = 0.0; | 103 rc->layer_avg_rate_mismatch[i] = 0.0; |
| 103 } | 104 } |
| 104 rc->window_count = 0; | 105 rc->window_count = 0; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 121 (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) : | 122 (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) : |
| 122 (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1); | 123 (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1); |
| 123 tot_num_frames += rc->layer_input_frames[i]; | 124 tot_num_frames += rc->layer_input_frames[i]; |
| 124 rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] * | 125 rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] * |
| 125 rc->layer_encoding_bitrate[i] / tot_num_frames; | 126 rc->layer_encoding_bitrate[i] / tot_num_frames; |
| 126 rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] / | 127 rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] / |
| 127 rc->layer_enc_frames[i]; | 128 rc->layer_enc_frames[i]; |
| 128 rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] / | 129 rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] / |
| 129 rc->layer_enc_frames[i]; | 130 rc->layer_enc_frames[i]; |
| 130 printf("For layer#: %d \n", i); | 131 printf("For layer#: %d \n", i); |
| 131 printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i], | 132 printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i], |
| 132 rc->layer_encoding_bitrate[i]); | 133 rc->layer_encoding_bitrate[i]); |
| 133 printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], | 134 printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], |
| 134 rc->layer_avg_frame_size[i]); | 135 rc->layer_avg_frame_size[i]); |
| 135 printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]); | 136 printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]); |
| 136 printf("Number of input frames, encoded (non-key) frames, " | 137 printf("Number of input frames, encoded (non-key) frames, " |
| 137 "and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i], | 138 "and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i], |
| 138 rc->layer_enc_frames[i], | 139 rc->layer_enc_frames[i], |
| 139 100.0 * num_dropped / rc->layer_input_frames[i]); | 140 100.0 * num_dropped / rc->layer_input_frames[i]); |
| 140 printf("\n"); | 141 printf("\n"); |
| 141 } | 142 } |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 cfg.g_timebase.den = strtol(argv[7], NULL, 0); | 591 cfg.g_timebase.den = strtol(argv[7], NULL, 0); |
| 591 | 592 |
| 592 speed = strtol(argv[8], NULL, 0); | 593 speed = strtol(argv[8], NULL, 0); |
| 593 if (speed < 0) { | 594 if (speed < 0) { |
| 594 die("Invalid speed setting: must be positive"); | 595 die("Invalid speed setting: must be positive"); |
| 595 } | 596 } |
| 596 | 597 |
| 597 for (i = min_args_base; | 598 for (i = min_args_base; |
| 598 (int)i < min_args_base + mode_to_num_layers[layering_mode]; | 599 (int)i < min_args_base + mode_to_num_layers[layering_mode]; |
| 599 ++i) { | 600 ++i) { |
| 600 cfg.ts_target_bitrate[i - 11] = strtol(argv[i], NULL, 0); | 601 rc.layer_target_bitrate[i - 11] = strtol(argv[i], NULL, 0); |
| 602 if (strncmp(encoder->name, "vp8", 3) == 0) |
| 603 cfg.ts_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11]; |
| 604 else if (strncmp(encoder->name, "vp9", 3) == 0) |
| 605 cfg.layer_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11]; |
| 601 } | 606 } |
| 602 | 607 |
| 603 // Real time parameters. | 608 // Real time parameters. |
| 604 cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0); | 609 cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0); |
| 605 cfg.rc_end_usage = VPX_CBR; | 610 cfg.rc_end_usage = VPX_CBR; |
| 606 cfg.rc_resize_allowed = 0; | 611 cfg.rc_resize_allowed = 0; |
| 607 cfg.rc_min_quantizer = 2; | 612 cfg.rc_min_quantizer = 2; |
| 608 cfg.rc_max_quantizer = 56; | 613 cfg.rc_max_quantizer = 56; |
| 609 if (strncmp(encoder->name, "vp9", 3) == 0) | 614 if (strncmp(encoder->name, "vp9", 3) == 0) |
| 610 cfg.rc_max_quantizer = 52; | 615 cfg.rc_max_quantizer = 52; |
| 611 cfg.rc_undershoot_pct = 50; | 616 cfg.rc_undershoot_pct = 50; |
| 612 cfg.rc_overshoot_pct = 50; | 617 cfg.rc_overshoot_pct = 50; |
| 613 cfg.rc_buf_initial_sz = 500; | 618 cfg.rc_buf_initial_sz = 500; |
| 614 cfg.rc_buf_optimal_sz = 600; | 619 cfg.rc_buf_optimal_sz = 600; |
| 615 cfg.rc_buf_sz = 1000; | 620 cfg.rc_buf_sz = 1000; |
| 616 | 621 |
| 617 // Use 1 thread as default. | 622 // Use 1 thread as default. |
| 618 cfg.g_threads = 1; | 623 cfg.g_threads = 1; |
| 619 | 624 |
| 620 // Enable error resilient mode. | 625 // Enable error resilient mode. |
| 621 cfg.g_error_resilient = 1; | 626 cfg.g_error_resilient = 1; |
| 622 cfg.g_lag_in_frames = 0; | 627 cfg.g_lag_in_frames = 0; |
| 623 cfg.kf_mode = VPX_KF_AUTO; | 628 cfg.kf_mode = VPX_KF_AUTO; |
| 624 | 629 |
| 625 // Disable automatic keyframe placement. | 630 // Disable automatic keyframe placement. |
| 626 cfg.kf_min_dist = cfg.kf_max_dist = 3000; | 631 cfg.kf_min_dist = cfg.kf_max_dist = 3000; |
| 627 | 632 |
| 633 cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; |
| 634 |
| 628 set_temporal_layer_pattern(layering_mode, | 635 set_temporal_layer_pattern(layering_mode, |
| 629 &cfg, | 636 &cfg, |
| 630 layer_flags, | 637 layer_flags, |
| 631 &flag_periodicity); | 638 &flag_periodicity); |
| 632 | 639 |
| 633 set_rate_control_metrics(&rc, &cfg); | 640 set_rate_control_metrics(&rc, &cfg); |
| 634 | 641 |
| 635 // Target bandwidth for the whole stream. | 642 // Target bandwidth for the whole stream. |
| 636 // Set to ts_target_bitrate for highest layer (total bitrate). | 643 // Set to layer_target_bitrate for highest layer (total bitrate). |
| 637 cfg.rc_target_bitrate = cfg.ts_target_bitrate[cfg.ts_number_layers - 1]; | 644 cfg.rc_target_bitrate = rc.layer_target_bitrate[cfg.ts_number_layers - 1]; |
| 638 | 645 |
| 639 // Open input file. | 646 // Open input file. |
| 640 if (!(infile = fopen(argv[1], "rb"))) { | 647 if (!(infile = fopen(argv[1], "rb"))) { |
| 641 die("Failed to open %s for reading", argv[1]); | 648 die("Failed to open %s for reading", argv[1]); |
| 642 } | 649 } |
| 643 | 650 |
| 644 framerate = cfg.g_timebase.den / cfg.g_timebase.num; | 651 framerate = cfg.g_timebase.den / cfg.g_timebase.num; |
| 645 // Open an output file for each stream. | 652 // Open an output file for each stream. |
| 646 for (i = 0; i < cfg.ts_number_layers; ++i) { | 653 for (i = 0; i < cfg.ts_number_layers; ++i) { |
| 647 char file_name[PATH_MAX]; | 654 char file_name[PATH_MAX]; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 670 #else | 677 #else |
| 671 if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) | 678 if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) |
| 672 #endif // CONFIG_VP9_HIGHBITDEPTH | 679 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 673 die_codec(&codec, "Failed to initialize encoder"); | 680 die_codec(&codec, "Failed to initialize encoder"); |
| 674 | 681 |
| 675 if (strncmp(encoder->name, "vp8", 3) == 0) { | 682 if (strncmp(encoder->name, "vp8", 3) == 0) { |
| 676 vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed); | 683 vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed); |
| 677 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff); | 684 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff); |
| 678 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 0); | 685 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 0); |
| 679 } else if (strncmp(encoder->name, "vp9", 3) == 0) { | 686 } else if (strncmp(encoder->name, "vp9", 3) == 0) { |
| 680 vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); | 687 vpx_svc_extra_cfg_t svc_params; |
| 681 vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); | 688 vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); |
| 682 vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0); | 689 vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); |
| 683 vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0); | 690 vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0); |
| 684 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 0); | 691 vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0); |
| 685 vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1)); | 692 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 0); |
| 686 if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1: 0)) { | 693 vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1)); |
| 687 die_codec(&codec, "Failed to set SVC"); | 694 if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1: 0)) |
| 695 die_codec(&codec, "Failed to set SVC"); |
| 696 for (i = 0; i < cfg.ts_number_layers; ++i) { |
| 697 svc_params.max_quantizers[i] = cfg.rc_max_quantizer; |
| 698 svc_params.min_quantizers[i] = cfg.rc_min_quantizer; |
| 688 } | 699 } |
| 700 svc_params.scaling_factor_num[0] = cfg.g_h; |
| 701 svc_params.scaling_factor_den[0] = cfg.g_h; |
| 702 vpx_codec_control(&codec, VP9E_SET_SVC_PARAMETERS, &svc_params); |
| 689 } | 703 } |
| 690 if (strncmp(encoder->name, "vp8", 3) == 0) { | 704 if (strncmp(encoder->name, "vp8", 3) == 0) { |
| 691 vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0); | 705 vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0); |
| 692 } | 706 } |
| 693 vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); | 707 vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); |
| 694 // This controls the maximum target size of the key frame. | 708 // This controls the maximum target size of the key frame. |
| 695 // For generating smaller key frames, use a smaller max_intra_size_pct | 709 // For generating smaller key frames, use a smaller max_intra_size_pct |
| 696 // value, like 100 or 200. | 710 // value, like 100 or 200. |
| 697 { | 711 { |
| 698 const int max_intra_size_pct = 900; | 712 const int max_intra_size_pct = 900; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 if (vpx_codec_destroy(&codec)) | 815 if (vpx_codec_destroy(&codec)) |
| 802 die_codec(&codec, "Failed to destroy codec"); | 816 die_codec(&codec, "Failed to destroy codec"); |
| 803 | 817 |
| 804 // Try to rewrite the output file headers with the actual frame count. | 818 // Try to rewrite the output file headers with the actual frame count. |
| 805 for (i = 0; i < cfg.ts_number_layers; ++i) | 819 for (i = 0; i < cfg.ts_number_layers; ++i) |
| 806 vpx_video_writer_close(outfile[i]); | 820 vpx_video_writer_close(outfile[i]); |
| 807 | 821 |
| 808 vpx_img_free(&raw); | 822 vpx_img_free(&raw); |
| 809 return EXIT_SUCCESS; | 823 return EXIT_SUCCESS; |
| 810 } | 824 } |
| OLD | NEW |