| 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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 int pts = 0; // PTS starts at 0. | 454 int pts = 0; // PTS starts at 0. |
| 455 int frame_duration = 1; // 1 timebase tick per frame. | 455 int frame_duration = 1; // 1 timebase tick per frame. |
| 456 int layering_mode = 0; | 456 int layering_mode = 0; |
| 457 int layer_flags[VPX_TS_MAX_PERIODICITY] = {0}; | 457 int layer_flags[VPX_TS_MAX_PERIODICITY] = {0}; |
| 458 int flag_periodicity = 1; | 458 int flag_periodicity = 1; |
| 459 vpx_svc_layer_id_t layer_id = {0, 0}; | 459 vpx_svc_layer_id_t layer_id = {0, 0}; |
| 460 const VpxInterface *encoder = NULL; | 460 const VpxInterface *encoder = NULL; |
| 461 FILE *infile = NULL; | 461 FILE *infile = NULL; |
| 462 struct RateControlMetrics rc; | 462 struct RateControlMetrics rc; |
| 463 int64_t cx_time = 0; | 463 int64_t cx_time = 0; |
| 464 const int min_args_base = 11; |
| 465 #if CONFIG_VP9_HIGHBITDEPTH |
| 466 vpx_bit_depth_t bit_depth = VPX_BITS_8; |
| 467 int input_bit_depth = 8; |
| 468 const int min_args = min_args_base + 1; |
| 469 #else |
| 470 const int min_args = min_args_base; |
| 471 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 464 | 472 |
| 465 exec_name = argv[0]; | 473 exec_name = argv[0]; |
| 466 // Check usage and arguments. | 474 // Check usage and arguments. |
| 467 if (argc < 11) { | 475 if (argc < min_args) { |
| 476 #if CONFIG_VP9_HIGHBITDEPTH |
| 477 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> " |
| 478 "<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> " |
| 479 "<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]); |
| 480 #else |
| 468 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> " | 481 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> " |
| 469 "<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> " | 482 "<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> " |
| 470 "<Rate_0> ... <Rate_nlayers-1> \n", argv[0]); | 483 "<Rate_0> ... <Rate_nlayers-1> \n", argv[0]); |
| 484 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 471 } | 485 } |
| 472 | 486 |
| 473 encoder = get_vpx_encoder_by_name(argv[3]); | 487 encoder = get_vpx_encoder_by_name(argv[3]); |
| 474 if (!encoder) | 488 if (!encoder) |
| 475 die("Unsupported codec."); | 489 die("Unsupported codec."); |
| 476 | 490 |
| 477 printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); | 491 printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); |
| 478 | 492 |
| 479 width = strtol(argv[4], NULL, 0); | 493 width = strtol(argv[4], NULL, 0); |
| 480 height = strtol(argv[5], NULL, 0); | 494 height = strtol(argv[5], NULL, 0); |
| 481 if (width < 16 || width % 2 || height < 16 || height % 2) { | 495 if (width < 16 || width % 2 || height < 16 || height % 2) { |
| 482 die("Invalid resolution: %d x %d", width, height); | 496 die("Invalid resolution: %d x %d", width, height); |
| 483 } | 497 } |
| 484 | 498 |
| 485 layering_mode = strtol(argv[10], NULL, 0); | 499 layering_mode = strtol(argv[10], NULL, 0); |
| 486 if (layering_mode < 0 || layering_mode > 12) { | 500 if (layering_mode < 0 || layering_mode > 12) { |
| 487 die("Invalid layering mode (0..12) %s", argv[10]); | 501 die("Invalid layering mode (0..12) %s", argv[10]); |
| 488 } | 502 } |
| 489 | 503 |
| 490 if (argc != 11 + mode_to_num_layers[layering_mode]) { | 504 if (argc != min_args + mode_to_num_layers[layering_mode]) { |
| 491 die("Invalid number of arguments"); | 505 die("Invalid number of arguments"); |
| 492 } | 506 } |
| 493 | 507 |
| 508 #if CONFIG_VP9_HIGHBITDEPTH |
| 509 switch (strtol(argv[argc-1], NULL, 0)) { |
| 510 case 8: |
| 511 bit_depth = VPX_BITS_8; |
| 512 input_bit_depth = 8; |
| 513 break; |
| 514 case 10: |
| 515 bit_depth = VPX_BITS_10; |
| 516 input_bit_depth = 10; |
| 517 break; |
| 518 case 12: |
| 519 bit_depth = VPX_BITS_12; |
| 520 input_bit_depth = 12; |
| 521 break; |
| 522 default: |
| 523 die("Invalid bit depth (8, 10, 12) %s", argv[argc-1]); |
| 524 } |
| 525 if (!vpx_img_alloc(&raw, |
| 526 bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : |
| 527 VPX_IMG_FMT_I42016, |
| 528 width, height, 32)) { |
| 529 die("Failed to allocate image", width, height); |
| 530 } |
| 531 #else |
| 494 if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) { | 532 if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) { |
| 495 die("Failed to allocate image", width, height); | 533 die("Failed to allocate image", width, height); |
| 496 } | 534 } |
| 535 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 497 | 536 |
| 498 // Populate encoder configuration. | 537 // Populate encoder configuration. |
| 499 res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); | 538 res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); |
| 500 if (res) { | 539 if (res) { |
| 501 printf("Failed to get config: %s\n", vpx_codec_err_to_string(res)); | 540 printf("Failed to get config: %s\n", vpx_codec_err_to_string(res)); |
| 502 return EXIT_FAILURE; | 541 return EXIT_FAILURE; |
| 503 } | 542 } |
| 504 | 543 |
| 505 // Update the default configuration with our settings. | 544 // Update the default configuration with our settings. |
| 506 cfg.g_w = width; | 545 cfg.g_w = width; |
| 507 cfg.g_h = height; | 546 cfg.g_h = height; |
| 508 | 547 |
| 548 #if CONFIG_VP9_HIGHBITDEPTH |
| 549 if (bit_depth != VPX_BITS_8) { |
| 550 cfg.g_bit_depth = bit_depth; |
| 551 cfg.g_input_bit_depth = input_bit_depth; |
| 552 cfg.g_profile = 2; |
| 553 } |
| 554 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 555 |
| 509 // Timebase format e.g. 30fps: numerator=1, demoninator = 30. | 556 // Timebase format e.g. 30fps: numerator=1, demoninator = 30. |
| 510 cfg.g_timebase.num = strtol(argv[6], NULL, 0); | 557 cfg.g_timebase.num = strtol(argv[6], NULL, 0); |
| 511 cfg.g_timebase.den = strtol(argv[7], NULL, 0); | 558 cfg.g_timebase.den = strtol(argv[7], NULL, 0); |
| 512 | 559 |
| 513 speed = strtol(argv[8], NULL, 0); | 560 speed = strtol(argv[8], NULL, 0); |
| 514 if (speed < 0) { | 561 if (speed < 0) { |
| 515 die("Invalid speed setting: must be positive"); | 562 die("Invalid speed setting: must be positive"); |
| 516 } | 563 } |
| 517 | 564 |
| 518 for (i = 11; (int)i < 11 + mode_to_num_layers[layering_mode]; ++i) { | 565 for (i = min_args_base; |
| 566 (int)i < min_args_base + mode_to_num_layers[layering_mode]; |
| 567 ++i) { |
| 519 cfg.ts_target_bitrate[i - 11] = strtol(argv[i], NULL, 0); | 568 cfg.ts_target_bitrate[i - 11] = strtol(argv[i], NULL, 0); |
| 520 } | 569 } |
| 521 | 570 |
| 522 // Real time parameters. | 571 // Real time parameters. |
| 523 cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0); | 572 cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0); |
| 524 cfg.rc_end_usage = VPX_CBR; | 573 cfg.rc_end_usage = VPX_CBR; |
| 525 cfg.rc_resize_allowed = 0; | 574 cfg.rc_resize_allowed = 0; |
| 526 cfg.rc_min_quantizer = 2; | 575 cfg.rc_min_quantizer = 2; |
| 527 cfg.rc_max_quantizer = 56; | 576 cfg.rc_max_quantizer = 56; |
| 528 cfg.rc_undershoot_pct = 50; | 577 cfg.rc_undershoot_pct = 50; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info); | 618 outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info); |
| 570 if (!outfile[i]) | 619 if (!outfile[i]) |
| 571 die("Failed to open %s for writing", file_name); | 620 die("Failed to open %s for writing", file_name); |
| 572 | 621 |
| 573 assert(outfile[i] != NULL); | 622 assert(outfile[i] != NULL); |
| 574 } | 623 } |
| 575 // No spatial layers in this encoder. | 624 // No spatial layers in this encoder. |
| 576 cfg.ss_number_layers = 1; | 625 cfg.ss_number_layers = 1; |
| 577 | 626 |
| 578 // Initialize codec. | 627 // Initialize codec. |
| 628 #if CONFIG_VP9_HIGHBITDEPTH |
| 629 if (vpx_codec_enc_init( |
| 630 &codec, encoder->codec_interface(), &cfg, |
| 631 bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH)) |
| 632 #else |
| 579 if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) | 633 if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) |
| 634 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 580 die_codec(&codec, "Failed to initialize encoder"); | 635 die_codec(&codec, "Failed to initialize encoder"); |
| 581 | 636 |
| 582 if (strncmp(encoder->name, "vp8", 3) == 0) { | 637 if (strncmp(encoder->name, "vp8", 3) == 0) { |
| 583 vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed); | 638 vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed); |
| 584 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOnYOnly); | 639 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOnYOnly); |
| 585 } else if (strncmp(encoder->name, "vp9", 3) == 0) { | 640 } else if (strncmp(encoder->name, "vp9", 3) == 0) { |
| 586 vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); | 641 vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); |
| 587 vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); | 642 vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); |
| 588 vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0); | 643 vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0); |
| 589 vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0); | 644 vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 if (vpx_codec_destroy(&codec)) | 724 if (vpx_codec_destroy(&codec)) |
| 670 die_codec(&codec, "Failed to destroy codec"); | 725 die_codec(&codec, "Failed to destroy codec"); |
| 671 | 726 |
| 672 // Try to rewrite the output file headers with the actual frame count. | 727 // Try to rewrite the output file headers with the actual frame count. |
| 673 for (i = 0; i < cfg.ts_number_layers; ++i) | 728 for (i = 0; i < cfg.ts_number_layers; ++i) |
| 674 vpx_video_writer_close(outfile[i]); | 729 vpx_video_writer_close(outfile[i]); |
| 675 | 730 |
| 676 vpx_img_free(&raw); | 731 vpx_img_free(&raw); |
| 677 return EXIT_SUCCESS; | 732 return EXIT_SUCCESS; |
| 678 } | 733 } |
| OLD | NEW |