| 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 23 matching lines...) Expand all Loading... |
| 34 | 34 |
| 35 // For rate control encoding stats. | 35 // For rate control encoding stats. |
| 36 struct RateControlMetrics { | 36 struct RateControlMetrics { |
| 37 // Number of input frames per layer. | 37 // Number of input frames per layer. |
| 38 int layer_input_frames[VPX_TS_MAX_LAYERS]; | 38 int layer_input_frames[VPX_TS_MAX_LAYERS]; |
| 39 // Total (cumulative) number of encoded frames per layer. | 39 // Total (cumulative) number of encoded frames per layer. |
| 40 int layer_tot_enc_frames[VPX_TS_MAX_LAYERS]; | 40 int layer_tot_enc_frames[VPX_TS_MAX_LAYERS]; |
| 41 // Number of encoded non-key frames per layer. | 41 // Number of encoded non-key frames per layer. |
| 42 int layer_enc_frames[VPX_TS_MAX_LAYERS]; | 42 int layer_enc_frames[VPX_TS_MAX_LAYERS]; |
| 43 // Framerate per layer layer (cumulative). | 43 // Framerate per layer layer (cumulative). |
| 44 float layer_framerate[VPX_TS_MAX_LAYERS]; | 44 double layer_framerate[VPX_TS_MAX_LAYERS]; |
| 45 // Target average frame size per layer (per-frame-bandwidth per layer). | 45 // Target average frame size per layer (per-frame-bandwidth per layer). |
| 46 float layer_pfb[VPX_TS_MAX_LAYERS]; | 46 double layer_pfb[VPX_TS_MAX_LAYERS]; |
| 47 // Actual average frame size per layer. | 47 // Actual average frame size per layer. |
| 48 float layer_avg_frame_size[VPX_TS_MAX_LAYERS]; | 48 double layer_avg_frame_size[VPX_TS_MAX_LAYERS]; |
| 49 // Average rate mismatch per layer (|target - actual| / target). | 49 // Average rate mismatch per layer (|target - actual| / target). |
| 50 float layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS]; | 50 double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS]; |
| 51 // Actual encoding bitrate per layer (cumulative). | 51 // Actual encoding bitrate per layer (cumulative). |
| 52 float layer_encoding_bitrate[VPX_TS_MAX_LAYERS]; | 52 double layer_encoding_bitrate[VPX_TS_MAX_LAYERS]; |
| 53 }; | 53 }; |
| 54 | 54 |
| 55 // Note: these rate control metrics assume only 1 key frame in the |
| 56 // sequence (i.e., first frame only). So for temporal pattern# 7 |
| 57 // (which has key frame for every frame on base layer), the metrics |
| 58 // computation will be off/wrong. |
| 59 // TODO(marpan): Update these metrics to account for multiple key frames |
| 60 // in the stream. |
| 55 static void set_rate_control_metrics(struct RateControlMetrics *rc, | 61 static void set_rate_control_metrics(struct RateControlMetrics *rc, |
| 56 vpx_codec_enc_cfg_t *cfg) { | 62 vpx_codec_enc_cfg_t *cfg) { |
| 57 int i = 0; | 63 unsigned int i = 0; |
| 58 // Set the layer (cumulative) framerate and the target layer (non-cumulative) | 64 // Set the layer (cumulative) framerate and the target layer (non-cumulative) |
| 59 // per-frame-bandwidth, for the rate control encoding stats below. | 65 // per-frame-bandwidth, for the rate control encoding stats below. |
| 60 float framerate = cfg->g_timebase.den / cfg->g_timebase.num; | 66 const double framerate = cfg->g_timebase.den / cfg->g_timebase.num; |
| 61 rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0]; | 67 rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0]; |
| 62 rc->layer_pfb[0] = 1000.0 * cfg->ts_target_bitrate[0] / | 68 rc->layer_pfb[0] = 1000.0 * cfg->ts_target_bitrate[0] / |
| 63 rc->layer_framerate[0]; | 69 rc->layer_framerate[0]; |
| 64 for (i = 0; i < cfg->ts_number_layers; ++i) { | 70 for (i = 0; i < cfg->ts_number_layers; ++i) { |
| 65 if (i > 0) { | 71 if (i > 0) { |
| 66 rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i]; | 72 rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i]; |
| 67 rc->layer_pfb[i] = 1000.0 * | 73 rc->layer_pfb[i] = 1000.0 * |
| 68 (cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) / | 74 (cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) / |
| 69 (rc->layer_framerate[i] - rc->layer_framerate[i - 1]); | 75 (rc->layer_framerate[i] - rc->layer_framerate[i - 1]); |
| 70 } | 76 } |
| 71 rc->layer_input_frames[i] = 0; | 77 rc->layer_input_frames[i] = 0; |
| 72 rc->layer_enc_frames[i] = 0; | 78 rc->layer_enc_frames[i] = 0; |
| 73 rc->layer_tot_enc_frames[i] = 0; | 79 rc->layer_tot_enc_frames[i] = 0; |
| 74 rc->layer_encoding_bitrate[i] = 0.0; | 80 rc->layer_encoding_bitrate[i] = 0.0; |
| 75 rc->layer_avg_frame_size[i] = 0.0; | 81 rc->layer_avg_frame_size[i] = 0.0; |
| 76 rc->layer_avg_rate_mismatch[i] = 0.0; | 82 rc->layer_avg_rate_mismatch[i] = 0.0; |
| 77 } | 83 } |
| 78 } | 84 } |
| 79 | 85 |
| 80 static void printout_rate_control_summary(struct RateControlMetrics *rc, | 86 static void printout_rate_control_summary(struct RateControlMetrics *rc, |
| 81 vpx_codec_enc_cfg_t *cfg, | 87 vpx_codec_enc_cfg_t *cfg, |
| 82 int frame_cnt) { | 88 int frame_cnt) { |
| 83 int i = 0; | 89 unsigned int i = 0; |
| 84 int check_num_frames = 0; | 90 int tot_num_frames = 0; |
| 85 printf("Total number of processed frames: %d\n\n", frame_cnt -1); | 91 printf("Total number of processed frames: %d\n\n", frame_cnt -1); |
| 86 printf("Rate control layer stats for %d layer(s):\n\n", | 92 printf("Rate control layer stats for %d layer(s):\n\n", |
| 87 cfg->ts_number_layers); | 93 cfg->ts_number_layers); |
| 88 for (i = 0; i < cfg->ts_number_layers; ++i) { | 94 for (i = 0; i < cfg->ts_number_layers; ++i) { |
| 89 const int num_dropped = (i > 0) ? | 95 const int num_dropped = (i > 0) ? |
| 90 (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) : | 96 (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) : |
| 91 (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1); | 97 (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1); |
| 98 tot_num_frames += rc->layer_input_frames[i]; |
| 92 rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] * | 99 rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] * |
| 93 rc->layer_encoding_bitrate[i] / rc->layer_tot_enc_frames[i]; | 100 rc->layer_encoding_bitrate[i] / tot_num_frames; |
| 94 rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] / | 101 rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] / |
| 95 rc->layer_enc_frames[i]; | 102 rc->layer_enc_frames[i]; |
| 96 rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] / | 103 rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] / |
| 97 rc->layer_enc_frames[i]; | 104 rc->layer_enc_frames[i]; |
| 98 printf("For layer#: %d \n", i); | 105 printf("For layer#: %d \n", i); |
| 99 printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i], | 106 printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i], |
| 100 rc->layer_encoding_bitrate[i]); | 107 rc->layer_encoding_bitrate[i]); |
| 101 printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], | 108 printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], |
| 102 rc->layer_avg_frame_size[i]); | 109 rc->layer_avg_frame_size[i]); |
| 103 printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]); | 110 printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]); |
| 104 printf("Number of input frames, encoded (non-key) frames, " | 111 printf("Number of input frames, encoded (non-key) frames, " |
| 105 "and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i], | 112 "and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i], |
| 106 rc->layer_enc_frames[i], | 113 rc->layer_enc_frames[i], |
| 107 100.0 * num_dropped / rc->layer_input_frames[i]); | 114 100.0 * num_dropped / rc->layer_input_frames[i]); |
| 108 check_num_frames += rc->layer_input_frames[i]; | |
| 109 printf("\n"); | 115 printf("\n"); |
| 110 } | 116 } |
| 111 if ((frame_cnt - 1) != check_num_frames) | 117 if ((frame_cnt - 1) != tot_num_frames) |
| 112 die("Error: Number of input frames not equal to output! \n"); | 118 die("Error: Number of input frames not equal to output! \n"); |
| 113 } | 119 } |
| 114 | 120 |
| 115 // Temporal scaling parameters: | 121 // Temporal scaling parameters: |
| 116 // NOTE: The 3 prediction frames cannot be used interchangeably due to | 122 // NOTE: The 3 prediction frames cannot be used interchangeably due to |
| 117 // differences in the way they are handled throughout the code. The | 123 // differences in the way they are handled throughout the code. The |
| 118 // frames should be allocated to layers in the order LAST, GF, ARF. | 124 // frames should be allocated to layers in the order LAST, GF, ARF. |
| 119 // Other combinations work, but may produce slightly inferior results. | 125 // Other combinations work, but may produce slightly inferior results. |
| 120 static void set_temporal_layer_pattern(int layering_mode, | 126 static void set_temporal_layer_pattern(int layering_mode, |
| 121 vpx_codec_enc_cfg_t *cfg, | 127 vpx_codec_enc_cfg_t *cfg, |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 vpx_codec_ctx_t codec; | 431 vpx_codec_ctx_t codec; |
| 426 vpx_codec_enc_cfg_t cfg; | 432 vpx_codec_enc_cfg_t cfg; |
| 427 int frame_cnt = 0; | 433 int frame_cnt = 0; |
| 428 vpx_image_t raw; | 434 vpx_image_t raw; |
| 429 vpx_codec_err_t res; | 435 vpx_codec_err_t res; |
| 430 unsigned int width; | 436 unsigned int width; |
| 431 unsigned int height; | 437 unsigned int height; |
| 432 int frame_avail; | 438 int frame_avail; |
| 433 int got_data; | 439 int got_data; |
| 434 int flags = 0; | 440 int flags = 0; |
| 435 int i; | 441 unsigned int i; |
| 436 int pts = 0; // PTS starts at 0. | 442 int pts = 0; // PTS starts at 0. |
| 437 int frame_duration = 1; // 1 timebase tick per frame. | 443 int frame_duration = 1; // 1 timebase tick per frame. |
| 438 int layering_mode = 0; | 444 int layering_mode = 0; |
| 439 int layer_flags[VPX_TS_MAX_PERIODICITY] = {0}; | 445 int layer_flags[VPX_TS_MAX_PERIODICITY] = {0}; |
| 440 int flag_periodicity = 1; | 446 int flag_periodicity = 1; |
| 441 int max_intra_size_pct; | 447 int max_intra_size_pct; |
| 442 vpx_svc_layer_id_t layer_id = {0, 0}; | 448 vpx_svc_layer_id_t layer_id = {0, 0}; |
| 443 const VpxInterface *encoder = NULL; | 449 const VpxInterface *encoder = NULL; |
| 444 FILE *infile = NULL; | 450 FILE *infile = NULL; |
| 445 struct RateControlMetrics rc; | 451 struct RateControlMetrics rc; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 } | 491 } |
| 486 | 492 |
| 487 // Update the default configuration with our settings. | 493 // Update the default configuration with our settings. |
| 488 cfg.g_w = width; | 494 cfg.g_w = width; |
| 489 cfg.g_h = height; | 495 cfg.g_h = height; |
| 490 | 496 |
| 491 // Timebase format e.g. 30fps: numerator=1, demoninator = 30. | 497 // Timebase format e.g. 30fps: numerator=1, demoninator = 30. |
| 492 cfg.g_timebase.num = strtol(argv[6], NULL, 0); | 498 cfg.g_timebase.num = strtol(argv[6], NULL, 0); |
| 493 cfg.g_timebase.den = strtol(argv[7], NULL, 0); | 499 cfg.g_timebase.den = strtol(argv[7], NULL, 0); |
| 494 | 500 |
| 495 for (i = 10; i < 10 + mode_to_num_layers[layering_mode]; ++i) { | 501 for (i = 10; (int)i < 10 + mode_to_num_layers[layering_mode]; ++i) { |
| 496 cfg.ts_target_bitrate[i - 10] = strtol(argv[i], NULL, 0); | 502 cfg.ts_target_bitrate[i - 10] = strtol(argv[i], NULL, 0); |
| 497 } | 503 } |
| 498 | 504 |
| 499 // Real time parameters. | 505 // Real time parameters. |
| 500 cfg.rc_dropframe_thresh = strtol(argv[8], NULL, 0); | 506 cfg.rc_dropframe_thresh = strtol(argv[8], NULL, 0); |
| 501 cfg.rc_end_usage = VPX_CBR; | 507 cfg.rc_end_usage = VPX_CBR; |
| 502 cfg.rc_resize_allowed = 0; | 508 cfg.rc_resize_allowed = 0; |
| 503 cfg.rc_min_quantizer = 2; | 509 cfg.rc_min_quantizer = 2; |
| 504 cfg.rc_max_quantizer = 56; | 510 cfg.rc_max_quantizer = 56; |
| 505 cfg.rc_undershoot_pct = 50; | 511 cfg.rc_undershoot_pct = 50; |
| 506 cfg.rc_overshoot_pct = 50; | 512 cfg.rc_overshoot_pct = 50; |
| 507 cfg.rc_buf_initial_sz = 500; | 513 cfg.rc_buf_initial_sz = 500; |
| 508 cfg.rc_buf_optimal_sz = 600; | 514 cfg.rc_buf_optimal_sz = 600; |
| 509 cfg.rc_buf_sz = 1000; | 515 cfg.rc_buf_sz = 1000; |
| 510 | 516 |
| 511 // Enable error resilient mode. | 517 // Enable error resilient mode. |
| 512 cfg.g_error_resilient = 1; | 518 cfg.g_error_resilient = 1; |
| 513 cfg.g_lag_in_frames = 0; | 519 cfg.g_lag_in_frames = 0; |
| 514 cfg.kf_mode = VPX_KF_DISABLED; | 520 cfg.kf_mode = VPX_KF_DISABLED; |
| 515 | 521 |
| 516 // Disable automatic keyframe placement. | 522 // Disable automatic keyframe placement. |
| 517 cfg.kf_min_dist = cfg.kf_max_dist = 3000; | 523 cfg.kf_min_dist = cfg.kf_max_dist = 3000; |
| 518 | 524 |
| 519 // Default setting for bitrate: used in special case of 1 layer (case 0). | |
| 520 cfg.rc_target_bitrate = cfg.ts_target_bitrate[0]; | |
| 521 | |
| 522 set_temporal_layer_pattern(layering_mode, | 525 set_temporal_layer_pattern(layering_mode, |
| 523 &cfg, | 526 &cfg, |
| 524 layer_flags, | 527 layer_flags, |
| 525 &flag_periodicity); | 528 &flag_periodicity); |
| 526 | 529 |
| 527 set_rate_control_metrics(&rc, &cfg); | 530 set_rate_control_metrics(&rc, &cfg); |
| 528 | 531 |
| 532 // Target bandwidth for the whole stream. |
| 533 // Set to ts_target_bitrate for highest layer (total bitrate). |
| 534 cfg.rc_target_bitrate = cfg.ts_target_bitrate[cfg.ts_number_layers - 1]; |
| 535 |
| 529 // Open input file. | 536 // Open input file. |
| 530 if (!(infile = fopen(argv[1], "rb"))) { | 537 if (!(infile = fopen(argv[1], "rb"))) { |
| 531 die("Failed to open %s for reading", argv[1]); | 538 die("Failed to open %s for reading", argv[1]); |
| 532 } | 539 } |
| 533 | 540 |
| 534 // Open an output file for each stream. | 541 // Open an output file for each stream. |
| 535 for (i = 0; i < cfg.ts_number_layers; ++i) { | 542 for (i = 0; i < cfg.ts_number_layers; ++i) { |
| 536 char file_name[PATH_MAX]; | 543 char file_name[PATH_MAX]; |
| 537 VpxVideoInfo info; | 544 VpxVideoInfo info; |
| 538 info.codec_fourcc = encoder->fourcc; | 545 info.codec_fourcc = encoder->fourcc; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 557 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 1); | 564 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 1); |
| 558 if (strncmp(encoder->name, "vp9", 3) == 0) { | 565 if (strncmp(encoder->name, "vp9", 3) == 0) { |
| 559 vpx_codec_control(&codec, VP8E_SET_CPUUSED, 3); | 566 vpx_codec_control(&codec, VP8E_SET_CPUUSED, 3); |
| 560 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 0); | 567 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 0); |
| 561 if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) { | 568 if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) { |
| 562 die_codec(&codec, "Failed to set SVC"); | 569 die_codec(&codec, "Failed to set SVC"); |
| 563 } | 570 } |
| 564 } | 571 } |
| 565 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); | 572 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); |
| 566 vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); | 573 vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); |
| 574 // This controls the maximum target size of the key frame. |
| 575 // For generating smaller key frames, use a smaller max_intra_size_pct |
| 576 // value, like 100 or 200. |
| 567 max_intra_size_pct = (int) (((double)cfg.rc_buf_optimal_sz * 0.5) | 577 max_intra_size_pct = (int) (((double)cfg.rc_buf_optimal_sz * 0.5) |
| 568 * ((double) cfg.g_timebase.den / cfg.g_timebase.num) / 10.0); | 578 * ((double) cfg.g_timebase.den / cfg.g_timebase.num) / 10.0); |
| 569 vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, max_intra_size_pct); | 579 vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, max_intra_size_pct); |
| 570 | 580 |
| 571 frame_avail = 1; | 581 frame_avail = 1; |
| 572 while (frame_avail || got_data) { | 582 while (frame_avail || got_data) { |
| 573 vpx_codec_iter_t iter = NULL; | 583 vpx_codec_iter_t iter = NULL; |
| 574 const vpx_codec_cx_pkt_t *pkt; | 584 const vpx_codec_cx_pkt_t *pkt; |
| 575 // Update the temporal layer_id. No spatial layers in this test. | 585 // Update the temporal layer_id. No spatial layers in this test. |
| 576 layer_id.spatial_layer_id = 0; | 586 layer_id.spatial_layer_id = 0; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 | 635 |
| 626 if (vpx_codec_destroy(&codec)) | 636 if (vpx_codec_destroy(&codec)) |
| 627 die_codec(&codec, "Failed to destroy codec"); | 637 die_codec(&codec, "Failed to destroy codec"); |
| 628 | 638 |
| 629 // Try to rewrite the output file headers with the actual frame count. | 639 // Try to rewrite the output file headers with the actual frame count. |
| 630 for (i = 0; i < cfg.ts_number_layers; ++i) | 640 for (i = 0; i < cfg.ts_number_layers; ++i) |
| 631 vpx_video_writer_close(outfile[i]); | 641 vpx_video_writer_close(outfile[i]); |
| 632 | 642 |
| 633 return EXIT_SUCCESS; | 643 return EXIT_SUCCESS; |
| 634 } | 644 } |
| OLD | NEW |