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 |