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 |
11 /* | 11 /* |
12 * This is an example demonstrating how to implement a multi-layer | 12 * This is an example demonstrating how to implement a multi-layer |
13 * VP9 encoding scheme based on spatial scalability for video applications | 13 * VP9 encoding scheme based on spatial scalability for video applications |
14 * that benefit from a scalable bitstream. | 14 * that benefit from a scalable bitstream. |
15 */ | 15 */ |
16 | 16 |
17 #include <math.h> | 17 #include <math.h> |
18 #include <stdarg.h> | 18 #include <stdarg.h> |
19 #include <stdlib.h> | 19 #include <stdlib.h> |
20 #include <string.h> | 20 #include <string.h> |
21 #include <time.h> | 21 #include <time.h> |
22 | 22 |
23 | 23 |
24 #include "../args.h" | 24 #include "../args.h" |
25 #include "../tools_common.h" | 25 #include "../tools_common.h" |
26 #include "../video_writer.h" | 26 #include "../video_writer.h" |
27 | 27 |
| 28 #include "../vpx_ports/vpx_timer.h" |
28 #include "vpx/svc_context.h" | 29 #include "vpx/svc_context.h" |
29 #include "vpx/vp8cx.h" | 30 #include "vpx/vp8cx.h" |
30 #include "vpx/vpx_encoder.h" | 31 #include "vpx/vpx_encoder.h" |
31 #include "../vpxstats.h" | 32 #include "../vpxstats.h" |
32 #define OUTPUT_RC_STATS 1 | 33 #define OUTPUT_RC_STATS 1 |
33 | 34 |
34 static const arg_def_t skip_frames_arg = | 35 static const arg_def_t skip_frames_arg = |
35 ARG_DEF("s", "skip-frames", 1, "input frames to skip"); | 36 ARG_DEF("s", "skip-frames", 1, "input frames to skip"); |
36 static const arg_def_t frames_arg = | 37 static const arg_def_t frames_arg = |
37 ARG_DEF("f", "frames", 1, "number of frames to encode"); | 38 ARG_DEF("f", "frames", 1, "number of frames to encode"); |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 int frames_received = 0; | 558 int frames_received = 0; |
558 #if OUTPUT_RC_STATS | 559 #if OUTPUT_RC_STATS |
559 VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = {NULL}; | 560 VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = {NULL}; |
560 struct RateControlStats rc; | 561 struct RateControlStats rc; |
561 vpx_svc_layer_id_t layer_id; | 562 vpx_svc_layer_id_t layer_id; |
562 int sl, tl; | 563 int sl, tl; |
563 double sum_bitrate = 0.0; | 564 double sum_bitrate = 0.0; |
564 double sum_bitrate2 = 0.0; | 565 double sum_bitrate2 = 0.0; |
565 double framerate = 30.0; | 566 double framerate = 30.0; |
566 #endif | 567 #endif |
| 568 struct vpx_usec_timer timer; |
| 569 int64_t cx_time = 0; |
567 memset(&svc_ctx, 0, sizeof(svc_ctx)); | 570 memset(&svc_ctx, 0, sizeof(svc_ctx)); |
568 svc_ctx.log_print = 1; | 571 svc_ctx.log_print = 1; |
569 exec_name = argv[0]; | 572 exec_name = argv[0]; |
570 parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg); | 573 parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg); |
571 | 574 |
572 // Allocate image buffer | 575 // Allocate image buffer |
573 #if CONFIG_VP9_HIGHBITDEPTH | 576 #if CONFIG_VP9_HIGHBITDEPTH |
574 if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ? | 577 if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ? |
575 VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016, | 578 VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016, |
576 enc_cfg.g_w, enc_cfg.g_h, 32)) { | 579 enc_cfg.g_w, enc_cfg.g_h, 32)) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 #endif | 628 #endif |
626 | 629 |
627 // skip initial frames | 630 // skip initial frames |
628 for (i = 0; i < app_input.frames_to_skip; ++i) | 631 for (i = 0; i < app_input.frames_to_skip; ++i) |
629 vpx_img_read(&raw, infile); | 632 vpx_img_read(&raw, infile); |
630 | 633 |
631 if (svc_ctx.speed != -1) | 634 if (svc_ctx.speed != -1) |
632 vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed); | 635 vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed); |
633 if (svc_ctx.threads) | 636 if (svc_ctx.threads) |
634 vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1)); | 637 vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1)); |
| 638 if (svc_ctx.speed >= 5) |
| 639 vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); |
| 640 |
635 | 641 |
636 // Encode frames | 642 // Encode frames |
637 while (!end_of_stream) { | 643 while (!end_of_stream) { |
638 vpx_codec_iter_t iter = NULL; | 644 vpx_codec_iter_t iter = NULL; |
639 const vpx_codec_cx_pkt_t *cx_pkt; | 645 const vpx_codec_cx_pkt_t *cx_pkt; |
640 if (frame_cnt >= app_input.frames_to_code || !vpx_img_read(&raw, infile)) { | 646 if (frame_cnt >= app_input.frames_to_code || !vpx_img_read(&raw, infile)) { |
641 // We need one extra vpx_svc_encode call at end of stream to flush | 647 // We need one extra vpx_svc_encode call at end of stream to flush |
642 // encoder and get remaining data | 648 // encoder and get remaining data |
643 end_of_stream = 1; | 649 end_of_stream = 1; |
644 } | 650 } |
645 | 651 |
| 652 vpx_usec_timer_start(&timer); |
646 res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw), | 653 res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw), |
647 pts, frame_duration, svc_ctx.speed >= 5 ? | 654 pts, frame_duration, svc_ctx.speed >= 5 ? |
648 VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY); | 655 VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY); |
| 656 vpx_usec_timer_mark(&timer); |
| 657 cx_time += vpx_usec_timer_elapsed(&timer); |
649 | 658 |
650 printf("%s", vpx_svc_get_message(&svc_ctx)); | 659 printf("%s", vpx_svc_get_message(&svc_ctx)); |
651 if (res != VPX_CODEC_OK) { | 660 if (res != VPX_CODEC_OK) { |
652 die_codec(&codec, "Failed to encode frame"); | 661 die_codec(&codec, "Failed to encode frame"); |
653 } | 662 } |
654 | 663 |
655 while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) { | 664 while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) { |
656 switch (cx_pkt->kind) { | 665 switch (cx_pkt->kind) { |
657 case VPX_CODEC_CX_FRAME_PKT: { | 666 case VPX_CODEC_CX_FRAME_PKT: { |
658 if (cx_pkt->data.frame.sz > 0) { | 667 if (cx_pkt->data.frame.sz > 0) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 if (writer) { | 786 if (writer) { |
778 vpx_video_writer_close(writer); | 787 vpx_video_writer_close(writer); |
779 } | 788 } |
780 #if OUTPUT_RC_STATS | 789 #if OUTPUT_RC_STATS |
781 if (svc_ctx.output_rc_stat) { | 790 if (svc_ctx.output_rc_stat) { |
782 for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) { | 791 for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) { |
783 vpx_video_writer_close(outfile[tl]); | 792 vpx_video_writer_close(outfile[tl]); |
784 } | 793 } |
785 } | 794 } |
786 #endif | 795 #endif |
| 796 printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n", |
| 797 frame_cnt, |
| 798 1000 * (float)cx_time / (double)(frame_cnt * 1000000), |
| 799 1000000 * (double)frame_cnt / (double)cx_time); |
787 vpx_img_free(&raw); | 800 vpx_img_free(&raw); |
788 // display average size, psnr | 801 // display average size, psnr |
789 printf("%s", vpx_svc_dump_statistics(&svc_ctx)); | 802 printf("%s", vpx_svc_dump_statistics(&svc_ctx)); |
790 vpx_svc_release(&svc_ctx); | 803 vpx_svc_release(&svc_ctx); |
791 return EXIT_SUCCESS; | 804 return EXIT_SUCCESS; |
792 } | 805 } |
OLD | NEW |