| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 // Framerate per layer layer (cumulative). | 54 // Framerate per layer layer (cumulative). |
| 55 double layer_framerate[VPX_TS_MAX_LAYERS]; | 55 double layer_framerate[VPX_TS_MAX_LAYERS]; |
| 56 // Target average frame size per layer (per-frame-bandwidth per layer). | 56 // Target average frame size per layer (per-frame-bandwidth per layer). |
| 57 double layer_pfb[VPX_TS_MAX_LAYERS]; | 57 double layer_pfb[VPX_TS_MAX_LAYERS]; |
| 58 // Actual average frame size per layer. | 58 // Actual average frame size per layer. |
| 59 double layer_avg_frame_size[VPX_TS_MAX_LAYERS]; | 59 double layer_avg_frame_size[VPX_TS_MAX_LAYERS]; |
| 60 // Average rate mismatch per layer (|target - actual| / target). | 60 // Average rate mismatch per layer (|target - actual| / target). |
| 61 double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS]; | 61 double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS]; |
| 62 // Actual encoding bitrate per layer (cumulative). | 62 // Actual encoding bitrate per layer (cumulative). |
| 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. |
| 65 // TODO(marpan): Should we add these short-time stats for each layer? |
| 66 double avg_st_encoding_bitrate; |
| 67 // Variance of the short-time encoder actual bitrate. |
| 68 double variance_st_encoding_bitrate; |
| 69 // Window (number of frames) for computing short-timee encoding bitrate. |
| 70 int window_size; |
| 71 // Number of window measurements. |
| 72 int window_count; |
| 64 }; | 73 }; |
| 65 | 74 |
| 66 // Note: these rate control metrics assume only 1 key frame in the | 75 // Note: these rate control metrics assume only 1 key frame in the |
| 67 // sequence (i.e., first frame only). So for temporal pattern# 7 | 76 // sequence (i.e., first frame only). So for temporal pattern# 7 |
| 68 // (which has key frame for every frame on base layer), the metrics | 77 // (which has key frame for every frame on base layer), the metrics |
| 69 // computation will be off/wrong. | 78 // computation will be off/wrong. |
| 70 // TODO(marpan): Update these metrics to account for multiple key frames | 79 // TODO(marpan): Update these metrics to account for multiple key frames |
| 71 // in the stream. | 80 // in the stream. |
| 72 static void set_rate_control_metrics(struct RateControlMetrics *rc, | 81 static void set_rate_control_metrics(struct RateControlMetrics *rc, |
| 73 vpx_codec_enc_cfg_t *cfg) { | 82 vpx_codec_enc_cfg_t *cfg) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 85 (cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) / | 94 (cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) / |
| 86 (rc->layer_framerate[i] - rc->layer_framerate[i - 1]); | 95 (rc->layer_framerate[i] - rc->layer_framerate[i - 1]); |
| 87 } | 96 } |
| 88 rc->layer_input_frames[i] = 0; | 97 rc->layer_input_frames[i] = 0; |
| 89 rc->layer_enc_frames[i] = 0; | 98 rc->layer_enc_frames[i] = 0; |
| 90 rc->layer_tot_enc_frames[i] = 0; | 99 rc->layer_tot_enc_frames[i] = 0; |
| 91 rc->layer_encoding_bitrate[i] = 0.0; | 100 rc->layer_encoding_bitrate[i] = 0.0; |
| 92 rc->layer_avg_frame_size[i] = 0.0; | 101 rc->layer_avg_frame_size[i] = 0.0; |
| 93 rc->layer_avg_rate_mismatch[i] = 0.0; | 102 rc->layer_avg_rate_mismatch[i] = 0.0; |
| 94 } | 103 } |
| 104 rc->window_count = 0; |
| 105 rc->window_size = 15; |
| 106 rc->avg_st_encoding_bitrate = 0.0; |
| 107 rc->variance_st_encoding_bitrate = 0.0; |
| 95 } | 108 } |
| 96 | 109 |
| 97 static void printout_rate_control_summary(struct RateControlMetrics *rc, | 110 static void printout_rate_control_summary(struct RateControlMetrics *rc, |
| 98 vpx_codec_enc_cfg_t *cfg, | 111 vpx_codec_enc_cfg_t *cfg, |
| 99 int frame_cnt) { | 112 int frame_cnt) { |
| 100 unsigned int i = 0; | 113 unsigned int i = 0; |
| 101 int tot_num_frames = 0; | 114 int tot_num_frames = 0; |
| 115 double perc_fluctuation = 0.0; |
| 102 printf("Total number of processed frames: %d\n\n", frame_cnt -1); | 116 printf("Total number of processed frames: %d\n\n", frame_cnt -1); |
| 103 printf("Rate control layer stats for %d layer(s):\n\n", | 117 printf("Rate control layer stats for %d layer(s):\n\n", |
| 104 cfg->ts_number_layers); | 118 cfg->ts_number_layers); |
| 105 for (i = 0; i < cfg->ts_number_layers; ++i) { | 119 for (i = 0; i < cfg->ts_number_layers; ++i) { |
| 106 const int num_dropped = (i > 0) ? | 120 const int num_dropped = (i > 0) ? |
| 107 (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) : | 121 (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) : |
| 108 (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1); | 122 (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1); |
| 109 tot_num_frames += rc->layer_input_frames[i]; | 123 tot_num_frames += rc->layer_input_frames[i]; |
| 110 rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] * | 124 rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] * |
| 111 rc->layer_encoding_bitrate[i] / tot_num_frames; | 125 rc->layer_encoding_bitrate[i] / tot_num_frames; |
| 112 rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] / | 126 rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] / |
| 113 rc->layer_enc_frames[i]; | 127 rc->layer_enc_frames[i]; |
| 114 rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] / | 128 rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] / |
| 115 rc->layer_enc_frames[i]; | 129 rc->layer_enc_frames[i]; |
| 116 printf("For layer#: %d \n", i); | 130 printf("For layer#: %d \n", i); |
| 117 printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i], | 131 printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i], |
| 118 rc->layer_encoding_bitrate[i]); | 132 rc->layer_encoding_bitrate[i]); |
| 119 printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], | 133 printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], |
| 120 rc->layer_avg_frame_size[i]); | 134 rc->layer_avg_frame_size[i]); |
| 121 printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]); | 135 printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]); |
| 122 printf("Number of input frames, encoded (non-key) frames, " | 136 printf("Number of input frames, encoded (non-key) frames, " |
| 123 "and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i], | 137 "and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i], |
| 124 rc->layer_enc_frames[i], | 138 rc->layer_enc_frames[i], |
| 125 100.0 * num_dropped / rc->layer_input_frames[i]); | 139 100.0 * num_dropped / rc->layer_input_frames[i]); |
| 126 printf("\n"); | 140 printf("\n"); |
| 127 } | 141 } |
| 142 rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count; |
| 143 rc->variance_st_encoding_bitrate = |
| 144 rc->variance_st_encoding_bitrate / rc->window_count - |
| 145 (rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate); |
| 146 perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) / |
| 147 rc->avg_st_encoding_bitrate; |
| 148 printf("Short-time stats, for window of %d frames: \n",rc->window_size); |
| 149 printf("Average, rms-variance, and percent-fluct: %f %f %f \n", |
| 150 rc->avg_st_encoding_bitrate, |
| 151 sqrt(rc->variance_st_encoding_bitrate), |
| 152 perc_fluctuation); |
| 128 if ((frame_cnt - 1) != tot_num_frames) | 153 if ((frame_cnt - 1) != tot_num_frames) |
| 129 die("Error: Number of input frames not equal to output! \n"); | 154 die("Error: Number of input frames not equal to output! \n"); |
| 130 } | 155 } |
| 131 | 156 |
| 132 // Temporal scaling parameters: | 157 // Temporal scaling parameters: |
| 133 // NOTE: The 3 prediction frames cannot be used interchangeably due to | 158 // NOTE: The 3 prediction frames cannot be used interchangeably due to |
| 134 // differences in the way they are handled throughout the code. The | 159 // differences in the way they are handled throughout the code. The |
| 135 // frames should be allocated to layers in the order LAST, GF, ARF. | 160 // frames should be allocated to layers in the order LAST, GF, ARF. |
| 136 // Other combinations work, but may produce slightly inferior results. | 161 // Other combinations work, but may produce slightly inferior results. |
| 137 static void set_temporal_layer_pattern(int layering_mode, | 162 static void set_temporal_layer_pattern(int layering_mode, |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 struct RateControlMetrics rc; | 487 struct RateControlMetrics rc; |
| 463 int64_t cx_time = 0; | 488 int64_t cx_time = 0; |
| 464 const int min_args_base = 11; | 489 const int min_args_base = 11; |
| 465 #if CONFIG_VP9_HIGHBITDEPTH | 490 #if CONFIG_VP9_HIGHBITDEPTH |
| 466 vpx_bit_depth_t bit_depth = VPX_BITS_8; | 491 vpx_bit_depth_t bit_depth = VPX_BITS_8; |
| 467 int input_bit_depth = 8; | 492 int input_bit_depth = 8; |
| 468 const int min_args = min_args_base + 1; | 493 const int min_args = min_args_base + 1; |
| 469 #else | 494 #else |
| 470 const int min_args = min_args_base; | 495 const int min_args = min_args_base; |
| 471 #endif // CONFIG_VP9_HIGHBITDEPTH | 496 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 497 double sum_bitrate = 0.0; |
| 498 double sum_bitrate2 = 0.0; |
| 499 double framerate = 30.0; |
| 472 | 500 |
| 473 exec_name = argv[0]; | 501 exec_name = argv[0]; |
| 474 // Check usage and arguments. | 502 // Check usage and arguments. |
| 475 if (argc < min_args) { | 503 if (argc < min_args) { |
| 476 #if CONFIG_VP9_HIGHBITDEPTH | 504 #if CONFIG_VP9_HIGHBITDEPTH |
| 477 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> " | 505 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> " |
| 478 "<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> " | 506 "<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> " |
| 479 "<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]); | 507 "<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]); |
| 480 #else | 508 #else |
| 481 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> " | 509 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> " |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 | 625 |
| 598 // Target bandwidth for the whole stream. | 626 // Target bandwidth for the whole stream. |
| 599 // Set to ts_target_bitrate for highest layer (total bitrate). | 627 // Set to ts_target_bitrate for highest layer (total bitrate). |
| 600 cfg.rc_target_bitrate = cfg.ts_target_bitrate[cfg.ts_number_layers - 1]; | 628 cfg.rc_target_bitrate = cfg.ts_target_bitrate[cfg.ts_number_layers - 1]; |
| 601 | 629 |
| 602 // Open input file. | 630 // Open input file. |
| 603 if (!(infile = fopen(argv[1], "rb"))) { | 631 if (!(infile = fopen(argv[1], "rb"))) { |
| 604 die("Failed to open %s for reading", argv[1]); | 632 die("Failed to open %s for reading", argv[1]); |
| 605 } | 633 } |
| 606 | 634 |
| 635 framerate = cfg.g_timebase.den / cfg.g_timebase.num; |
| 607 // Open an output file for each stream. | 636 // Open an output file for each stream. |
| 608 for (i = 0; i < cfg.ts_number_layers; ++i) { | 637 for (i = 0; i < cfg.ts_number_layers; ++i) { |
| 609 char file_name[PATH_MAX]; | 638 char file_name[PATH_MAX]; |
| 610 VpxVideoInfo info; | 639 VpxVideoInfo info; |
| 611 info.codec_fourcc = encoder->fourcc; | 640 info.codec_fourcc = encoder->fourcc; |
| 612 info.frame_width = cfg.g_w; | 641 info.frame_width = cfg.g_w; |
| 613 info.frame_height = cfg.g_h; | 642 info.frame_height = cfg.g_h; |
| 614 info.time_base.numerator = cfg.g_timebase.num; | 643 info.time_base.numerator = cfg.g_timebase.num; |
| 615 info.time_base.denominator = cfg.g_timebase.den; | 644 info.time_base.denominator = cfg.g_timebase.den; |
| 616 | 645 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 645 if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) { | 674 if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) { |
| 646 die_codec(&codec, "Failed to set SVC"); | 675 die_codec(&codec, "Failed to set SVC"); |
| 647 } | 676 } |
| 648 } | 677 } |
| 649 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); | 678 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); |
| 650 vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); | 679 vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); |
| 651 // This controls the maximum target size of the key frame. | 680 // This controls the maximum target size of the key frame. |
| 652 // For generating smaller key frames, use a smaller max_intra_size_pct | 681 // For generating smaller key frames, use a smaller max_intra_size_pct |
| 653 // value, like 100 or 200. | 682 // value, like 100 or 200. |
| 654 { | 683 { |
| 655 const int max_intra_size_pct = 200; | 684 const int max_intra_size_pct = 900; |
| 656 vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, | 685 vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, |
| 657 max_intra_size_pct); | 686 max_intra_size_pct); |
| 658 } | 687 } |
| 659 | 688 |
| 660 frame_avail = 1; | 689 frame_avail = 1; |
| 661 while (frame_avail || got_data) { | 690 while (frame_avail || got_data) { |
| 662 struct vpx_usec_timer timer; | 691 struct vpx_usec_timer timer; |
| 663 vpx_codec_iter_t iter = NULL; | 692 vpx_codec_iter_t iter = NULL; |
| 664 const vpx_codec_cx_pkt_t *pkt; | 693 const vpx_codec_cx_pkt_t *pkt; |
| 665 // Update the temporal layer_id. No spatial layers in this test. | 694 // Update the temporal layer_id. No spatial layers in this test. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 // Keep count of rate control stats per layer (for non-key frames). | 727 // Keep count of rate control stats per layer (for non-key frames). |
| 699 if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] && | 728 if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] && |
| 700 !(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) { | 729 !(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) { |
| 701 rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz; | 730 rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz; |
| 702 rc.layer_avg_rate_mismatch[i] += | 731 rc.layer_avg_rate_mismatch[i] += |
| 703 fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) / | 732 fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) / |
| 704 rc.layer_pfb[i]; | 733 rc.layer_pfb[i]; |
| 705 ++rc.layer_enc_frames[i]; | 734 ++rc.layer_enc_frames[i]; |
| 706 } | 735 } |
| 707 } | 736 } |
| 737 // Update for short-time encoding bitrate states, for moving window |
| 738 // of size rc->window, shifted by rc->window / 2. |
| 739 // Ignore first window segment, due to key frame. |
| 740 if (frame_cnt > rc.window_size) { |
| 741 sum_bitrate += 0.001 * 8.0 * pkt->data.frame.sz * framerate; |
| 742 if (frame_cnt % rc.window_size == 0) { |
| 743 rc.window_count += 1; |
| 744 rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size; |
| 745 rc.variance_st_encoding_bitrate += |
| 746 (sum_bitrate / rc.window_size) * |
| 747 (sum_bitrate / rc.window_size); |
| 748 sum_bitrate = 0.0; |
| 749 } |
| 750 } |
| 751 // Second shifted window. |
| 752 if (frame_cnt > rc.window_size + rc.window_size / 2) { |
| 753 sum_bitrate2 += 0.001 * 8.0 * pkt->data.frame.sz * framerate; |
| 754 if (frame_cnt > 2 * rc.window_size && |
| 755 frame_cnt % rc.window_size == 0) { |
| 756 rc.window_count += 1; |
| 757 rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size; |
| 758 rc.variance_st_encoding_bitrate += |
| 759 (sum_bitrate2 / rc.window_size) * |
| 760 (sum_bitrate2 / rc.window_size); |
| 761 sum_bitrate2 = 0.0; |
| 762 } |
| 763 } |
| 708 break; | 764 break; |
| 709 default: | 765 default: |
| 710 break; | 766 break; |
| 711 } | 767 } |
| 712 } | 768 } |
| 713 ++frame_cnt; | 769 ++frame_cnt; |
| 714 pts += frame_duration; | 770 pts += frame_duration; |
| 715 } | 771 } |
| 716 fclose(infile); | 772 fclose(infile); |
| 717 printout_rate_control_summary(&rc, &cfg, frame_cnt); | 773 printout_rate_control_summary(&rc, &cfg, frame_cnt); |
| 718 printf("\n"); | 774 printf("\n"); |
| 719 printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n", | 775 printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n", |
| 720 frame_cnt, | 776 frame_cnt, |
| 721 1000 * (float)cx_time / (double)(frame_cnt * 1000000), | 777 1000 * (float)cx_time / (double)(frame_cnt * 1000000), |
| 722 1000000 * (double)frame_cnt / (double)cx_time); | 778 1000000 * (double)frame_cnt / (double)cx_time); |
| 723 | 779 |
| 724 if (vpx_codec_destroy(&codec)) | 780 if (vpx_codec_destroy(&codec)) |
| 725 die_codec(&codec, "Failed to destroy codec"); | 781 die_codec(&codec, "Failed to destroy codec"); |
| 726 | 782 |
| 727 // Try to rewrite the output file headers with the actual frame count. | 783 // Try to rewrite the output file headers with the actual frame count. |
| 728 for (i = 0; i < cfg.ts_number_layers; ++i) | 784 for (i = 0; i < cfg.ts_number_layers; ++i) |
| 729 vpx_video_writer_close(outfile[i]); | 785 vpx_video_writer_close(outfile[i]); |
| 730 | 786 |
| 731 vpx_img_free(&raw); | 787 vpx_img_free(&raw); |
| 732 return EXIT_SUCCESS; | 788 return EXIT_SUCCESS; |
| 733 } | 789 } |
| OLD | NEW |