History

Merge changes I32ab6829,If47867d4,I4442de01

* changes: Add coding_data_bit_size to EncodeFrameResult Pass in infile_path to SimpleEncode() Add SimpleEncode::EncodeFrameWithQuantizeIndex()

Angie Chiang committed 6 years ago

Commit 9fbcfd12 parents 831536c 6a950fe5 files · +115 −37Browse files

Unified · Split

5 files
  1. test/simple_encode_test.cc +39 −27
  2. vp9/encoder/vp9_encoder.c +19 −0
  3. vp9/encoder/vp9_encoder.h +28 −0
  4. vp9/simple_encode.cc +21 −8
  5. vp9/simple_encode.h +8 −2
test/simple_encode_test.cc+39−27
@@ -1,21 +1,28 @@
1#include <math.h>
1#include <memory>2#include <memory>
2#include <vector>3#include <vector>
3#include "third_party/googletest/src/include/gtest/gtest.h"4#include "third_party/googletest/src/include/gtest/gtest.h"
4#include "vp9/simple_encode.h"5#include "vp9/simple_encode.h"
5 6
6namespace {7namespace {
8const int w = 352;
9const int h = 288;
10const int frame_rate_num = 30;
11const int frame_rate_den = 1;
12const int target_bitrate = 1000;
13const int num_frames = 17;
14// TODO(angiebird): Figure out how to upload test video to our codebase
15const char infile_path[] = "bus_352x288_420_f20_b8.yuv";
16
17static double get_bit_rate_in_kpbs(size_t bit_size, int num_frames,
18 int frame_rate_num, int frame_rate_den) {
19 return static_cast<double>(bit_size) / num_frames * frame_rate_num /
20 frame_rate_den / 1000.;
21}
7 22
8TEST(SimpleEncode, ComputeFirstPassStats) {23TEST(SimpleEncode, ComputeFirstPassStats) {
9 int w = 352;
10 int h = 288;
11 int frame_rate_num = 30;
12 int frame_rate_den = 1;
13 int target_bitrate = 200;
14 int num_frames = 17;
15 // TODO(angiebird): Figure out how to upload test video to our codebase
16 FILE *file = fopen("bus_352x288_420_f20_b8.yuv", "r");
17 SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,24 SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
18 target_bitrate, num_frames, file);25 target_bitrate, num_frames, infile_path);
19 simple_encode.ComputeFirstPassStats();26 simple_encode.ComputeFirstPassStats();
20 std::vector<std::vector<double>> frame_stats =27 std::vector<std::vector<double>> frame_stats =
21 simple_encode.ObserveFirstPassStats();28 simple_encode.ObserveFirstPassStats();
@@ -34,32 +41,16 @@ TEST(SimpleEncode, ComputeFirstPassStats) { · 12 unmodified lines
34}41}
35 42
36TEST(SimpleEncode, GetCodingFrameNum) {43TEST(SimpleEncode, GetCodingFrameNum) {
37 int w = 352;
38 int h = 288;
39 int frame_rate_num = 30;
40 int frame_rate_den = 1;
41 int target_bitrate = 200;
42 int num_frames = 17;
43 // TODO(angiebird): Figure out how to upload test video to our codebase
44 FILE *file = fopen("bus_352x288_420_f20_b8.yuv", "r");
45 SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,44 SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
46 target_bitrate, num_frames, file);45 target_bitrate, num_frames, infile_path);
47 simple_encode.ComputeFirstPassStats();46 simple_encode.ComputeFirstPassStats();
48 int num_coding_frames = simple_encode.GetCodingFrameNum();47 int num_coding_frames = simple_encode.GetCodingFrameNum();
49 EXPECT_EQ(num_coding_frames, 19);48 EXPECT_EQ(num_coding_frames, 19);
50}49}
51 50
52TEST(SimpleEncode, EncodeFrame) {51TEST(SimpleEncode, EncodeFrame) {
53 int w = 352;
54 int h = 288;
55 int frame_rate_num = 30;
56 int frame_rate_den = 1;
57 int target_bitrate = 1000;
58 int num_frames = 17;
59 // TODO(angiebird): Figure out how to upload test video to our codebase
60 FILE *file = fopen("bus_352x288_420_f20_b8.yuv", "r");
61 SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,52 SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
62 target_bitrate, num_frames, file);53 target_bitrate, num_frames, infile_path);
63 simple_encode.ComputeFirstPassStats();54 simple_encode.ComputeFirstPassStats();
64 int num_coding_frames = simple_encode.GetCodingFrameNum();55 int num_coding_frames = simple_encode.GetCodingFrameNum();
65 EXPECT_GE(num_coding_frames, num_frames);56 EXPECT_GE(num_coding_frames, num_frames);
@@ -68,6 +59,7 @@ TEST(SimpleEncode, EncodeFrame) { · 2 unmodified lines
68 int ref_num_alternate_refereces = num_coding_frames - num_frames;59 int ref_num_alternate_refereces = num_coding_frames - num_frames;
69 int num_alternate_refereces = 0;60 int num_alternate_refereces = 0;
70 simple_encode.StartEncode();61 simple_encode.StartEncode();
62 size_t total_data_bit_size = 0;
71 for (int i = 0; i < num_coding_frames; ++i) {63 for (int i = 0; i < num_coding_frames; ++i) {
72 EncodeFrameResult encode_frame_result;64 EncodeFrameResult encode_frame_result;
73 if (i == 0) {65 if (i == 0) {
@@ -88,8 +80,28 @@ TEST(SimpleEncode, EncodeFrame) { · 14 unmodified lines
88 EXPECT_GE(encode_frame_result.psnr, 34)80 EXPECT_GE(encode_frame_result.psnr, 34)
89 << "The psnr is supposed to be greater than 34 given the "81 << "The psnr is supposed to be greater than 34 given the "
90 "target_bitrate 1000 kbps";82 "target_bitrate 1000 kbps";
83 total_data_bit_size += encode_frame_result.coding_data_bit_size;
91 }84 }
92 EXPECT_EQ(num_alternate_refereces, ref_num_alternate_refereces);85 EXPECT_EQ(num_alternate_refereces, ref_num_alternate_refereces);
86 double bitrate = get_bit_rate_in_kpbs(total_data_bit_size, num_frames,
87 frame_rate_num, frame_rate_den);
88 EXPECT_LE(fabs(target_bitrate - bitrate), 150);
89 simple_encode.EndEncode();
90}
91
92TEST(SimpleEncode, EncodeFrameWithQuantizeIndex) {
93 SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
94 target_bitrate, num_frames, infile_path);
95 simple_encode.ComputeFirstPassStats();
96 int num_coding_frames = simple_encode.GetCodingFrameNum();
97 simple_encode.StartEncode();
98 for (int i = 0; i < num_coding_frames; ++i) {
99 int assigned_quantize_index = 100 + i;
100 EncodeFrameResult encode_frame_result;
101 simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result,
102 assigned_quantize_index);
103 EXPECT_EQ(encode_frame_result.quantize_index, assigned_quantize_index);
104 }
93 simple_encode.EndEncode();105 simple_encode.EndEncode();
94}106}
95 107
vp9/encoder/vp9_encoder.c+19−0
@@ -2647,6 +2647,10 @@ VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, · 2646 unmodified lines
2647 2647
2648 cm->error.setjmp = 0;2648 cm->error.setjmp = 0;
2649 2649
2650#if CONFIG_RATE_CTRL
2651 encode_command_init(&cpi->encode_command);
2652#endif
2653
2650 return cpi;2654 return cpi;
2651}2655}
2652 2656
@@ -4282,6 +4286,14 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, · 1629 unmodified lines
4282 vp9_scale_references(cpi);4286 vp9_scale_references(cpi);
4283 }4287 }
4284 4288
4289#if CONFIG_RATE_CTRL
4290 // TODO(angiebird): This is a hack for making sure the encoder use the
4291 // external_quantize_index exactly. Avoid this kind of hack later.
4292 if (cpi->encode_command.use_external_quantize_index) {
4293 q = cpi->encode_command.external_quantize_index;
4294 }
4295#endif
4296
4285 vp9_set_quantizer(cm, q);4297 vp9_set_quantizer(cm, q);
4286 4298
4287 if (loop_count == 0) setup_frame(cpi);4299 if (loop_count == 0) setup_frame(cpi);
@@ -4307,6 +4319,13 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, · 19 unmodified lines
4307 // update_base_skip_probs(cpi);4319 // update_base_skip_probs(cpi);
4308 4320
4309 vpx_clear_system_state();4321 vpx_clear_system_state();
4322#if CONFIG_RATE_CTRL
4323 // TODO(angiebird): This is a hack for making sure the encoder use the
4324 // external_quantize_index exactly. Avoid this kind of hack later.
4325 if (cpi->encode_command.use_external_quantize_index) {
4326 break;
4327 }
4328#endif
4310 4329
4311 // Dummy pack of the bitstream using up to date stats to get an4330 // Dummy pack of the bitstream using up to date stats to get an
4312 // accurate estimate of output frame size to determine if we need4331 // accurate estimate of output frame size to determine if we need
vp9/encoder/vp9_encoder.h+28−0
@@ -516,6 +516,31 @@ typedef struct KMEANS_DATA { · 515 unmodified lines
516 int group_idx;516 int group_idx;
517} KMEANS_DATA;517} KMEANS_DATA;
518 518
519#if CONFIG_RATE_CTRL
520typedef struct ENCODE_COMMAND {
521 int use_external_quantize_index;
522 int external_quantize_index;
523} ENCODE_COMMAND;
524
525static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) {
526 vp9_zero(*encode_command);
527 encode_command->use_external_quantize_index = 0;
528 encode_command->external_quantize_index = -1;
529}
530
531static INLINE void encode_command_set_external_quantize_index(
532 ENCODE_COMMAND *encode_command, int quantize_index) {
533 encode_command->use_external_quantize_index = 1;
534 encode_command->external_quantize_index = quantize_index;
535}
536
537static INLINE void encode_command_reset_external_quantize_index(
538 ENCODE_COMMAND *encode_command) {
539 encode_command->use_external_quantize_index = 0;
540 encode_command->external_quantize_index = -1;
541}
542#endif
543
519typedef struct VP9_COMP {544typedef struct VP9_COMP {
520 FRAME_INFO frame_info;545 FRAME_INFO frame_info;
521 QUANTS quants;546 QUANTS quants;
@@ -820,6 +845,9 @@ typedef struct VP9_COMP { · 298 unmodified lines
820 845
821 int multi_layer_arf;846 int multi_layer_arf;
822 vpx_roi_map_t roi;847 vpx_roi_map_t roi;
848#if CONFIG_RATE_CTRL
849 ENCODE_COMMAND encode_command;
850#endif
823} VP9_COMP;851} VP9_COMP;
824 852
825typedef struct ENCODE_FRAME_RESULT {853typedef struct ENCODE_FRAME_RESULT {
vp9/simple_encode.cc+21−8
@@ -87,6 +87,8 @@ get_frame_type_from_update_type(FRAME_UPDATE_TYPE update_type) { · 86 unmodified lines
87static void update_encode_frame_result(87static void update_encode_frame_result(
88 EncodeFrameResult *encode_frame_result,88 EncodeFrameResult *encode_frame_result,
89 const ENCODE_FRAME_RESULT *encode_frame_info) {89 const ENCODE_FRAME_RESULT *encode_frame_info) {
90 encode_frame_result->coding_data_bit_size =
91 encode_frame_result->coding_data_byte_size * 8;
90 encode_frame_result->show_idx = encode_frame_info->show_idx;92 encode_frame_result->show_idx = encode_frame_info->show_idx;
91 encode_frame_result->frame_type =93 encode_frame_result->frame_type =
92 get_frame_type_from_update_type(encode_frame_info->update_type);94 get_frame_type_from_update_type(encode_frame_info->update_type);
@@ -97,7 +99,8 @@ static void update_encode_frame_result( · 4 unmodified lines
97 99
98SimpleEncode::SimpleEncode(int frame_width, int frame_height,100SimpleEncode::SimpleEncode(int frame_width, int frame_height,
99 int frame_rate_num, int frame_rate_den,101 int frame_rate_num, int frame_rate_den,
100 int target_bitrate, int num_frames, FILE *file)102 int target_bitrate, int num_frames,
103 const char *infile_path)
101 : pimpl{ std::unique_ptr<impl>(new impl()) } {104 : pimpl{ std::unique_ptr<impl>(new impl()) } {
102 this->frame_width = frame_width;105 this->frame_width = frame_width;
103 this->frame_height = frame_height;106 this->frame_height = frame_height;
@@ -105,7 +108,8 @@ SimpleEncode::SimpleEncode(int frame_width, int frame_height, · 1 unmodified line
105 this->frame_rate_den = frame_rate_den;108 this->frame_rate_den = frame_rate_den;
106 this->target_bitrate = target_bitrate;109 this->target_bitrate = target_bitrate;
107 this->num_frames = num_frames;110 this->num_frames = num_frames;
108 this->file = file;111 // TODO(angirbid): Should we keep a file pointer here or keep the file_path?
112 this->file = fopen(infile_path, "r");
109 pimpl->cpi = NULL;113 pimpl->cpi = NULL;
110 pimpl->img_fmt = VPX_IMG_FMT_I420;114 pimpl->img_fmt = VPX_IMG_FMT_I420;
111}115}
@@ -234,26 +238,35 @@ void SimpleEncode::EncodeFrame(EncodeFrameResult *encode_frame_result) { · 122 unmodified lines
234 }238 }
235 }239 }
236 assert(encode_frame_result->coding_data.get() == nullptr);240 assert(encode_frame_result->coding_data.get() == nullptr);
237 const size_t max_coding_data_size = frame_width * frame_height * 3;241 const size_t max_coding_data_byte_size = frame_width * frame_height * 3;
238 encode_frame_result->coding_data =242 encode_frame_result->coding_data = std::move(
239 std::move(std::unique_ptr<uint8_t[]>(new uint8_t[max_coding_data_size]));243 std::unique_ptr<uint8_t[]>(new uint8_t[max_coding_data_byte_size]));
240 int64_t time_stamp;244 int64_t time_stamp;
241 int64_t time_end;245 int64_t time_end;
242 int flush = 1; // Make vp9_get_compressed_data encode a frame246 int flush = 1; // Make vp9_get_compressed_data encode a frame
243 unsigned int frame_flags = 0;247 unsigned int frame_flags = 0;
244 ENCODE_FRAME_RESULT encode_frame_info;248 ENCODE_FRAME_RESULT encode_frame_info;
245 vp9_get_compressed_data(cpi, &frame_flags,249 vp9_get_compressed_data(cpi, &frame_flags,
246 &encode_frame_result->coding_data_size,250 &encode_frame_result->coding_data_byte_size,
247 encode_frame_result->coding_data.get(), &time_stamp,251 encode_frame_result->coding_data.get(), &time_stamp,
248 &time_end, flush, &encode_frame_info);252 &time_end, flush, &encode_frame_info);
249 // vp9_get_compressed_data is expected to encode a frame every time, so the253 // vp9_get_compressed_data is expected to encode a frame every time, so the
250 // data size should be greater than zero.254 // data size should be greater than zero.
251 assert(encode_frame_result->coding_data_size > 0);255 assert(encode_frame_result->coding_data_byte_size > 0);
252 assert(encode_frame_result->coding_data_size < max_coding_data_size);256 assert(encode_frame_result->coding_data_byte_size <
257 max_coding_data_byte_size);
253 258
254 update_encode_frame_result(encode_frame_result, &encode_frame_info);259 update_encode_frame_result(encode_frame_result, &encode_frame_info);
255}260}
256 261
262void SimpleEncode::EncodeFrameWithQuantizeIndex(
263 EncodeFrameResult *encode_frame_result, int quantize_index) {
264 encode_command_set_external_quantize_index(&pimpl->cpi->encode_command,
265 quantize_index);
266 EncodeFrame(encode_frame_result);
267 encode_command_reset_external_quantize_index(&pimpl->cpi->encode_command);
268}
269
257int SimpleEncode::GetCodingFrameNum() {270int SimpleEncode::GetCodingFrameNum() {
258 assert(pimpl->first_pass_stats.size() - 1 > 0);271 assert(pimpl->first_pass_stats.size() - 1 > 0);
259 // These are the default settings for now.272 // These are the default settings for now.
vp9/simple_encode.h+8−2
@@ -10,7 +10,8 @@ enum FrameType { · 9 unmodified lines
10struct EncodeFrameResult {10struct EncodeFrameResult {
11 int show_idx;11 int show_idx;
12 FrameType frame_type;12 FrameType frame_type;
13 size_t coding_data_size;13 size_t coding_data_bit_size;
14 size_t coding_data_byte_size;
14 // The EncodeFrame will allocate a buffer, write the coding data into the15 // The EncodeFrame will allocate a buffer, write the coding data into the
15 // buffer and give the ownership of the buffer to coding_data16 // buffer and give the ownership of the buffer to coding_data
16 std::unique_ptr<unsigned char[]> coding_data;17 std::unique_ptr<unsigned char[]> coding_data;
@@ -23,7 +24,7 @@ class SimpleEncode { · 6 unmodified lines
23 public:24 public:
24 SimpleEncode(int frame_width, int frame_height, int frame_rate_num,25 SimpleEncode(int frame_width, int frame_height, int frame_rate_num,
25 int frame_rate_den, int target_bitrate, int num_frames,26 int frame_rate_den, int target_bitrate, int num_frames,
26 FILE *file);27 const char *infile_path);
27 ~SimpleEncode();28 ~SimpleEncode();
28 SimpleEncode(SimpleEncode &&) = delete;29 SimpleEncode(SimpleEncode &&) = delete;
29 SimpleEncode &operator=(SimpleEncode &&) = delete;30 SimpleEncode &operator=(SimpleEncode &&) = delete;
@@ -47,6 +48,11 @@ class SimpleEncode { · 17 unmodified lines
47 // This funtion should be called after StartEncode() before EndEncode()48 // This funtion should be called after StartEncode() before EndEncode()
48 void EncodeFrame(EncodeFrameResult *encode_frame_result);49 void EncodeFrame(EncodeFrameResult *encode_frame_result);
49 50
51 // Encode a frame with a specific quantize index
52 // This funtion should be called after StartEncode() before EndEncode()
53 void EncodeFrameWithQuantizeIndex(EncodeFrameResult *encode_frame_result,
54 int quantize_index);
55
50 // Get the number of coding frames for the video. The coding frames include56 // Get the number of coding frames for the video. The coding frames include
51 // show frame and no show frame.57 // show frame and no show frame.
52 // This funtion should be called after ComputeFirstPassStats()58 // This funtion should be called after ComputeFirstPassStats()

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t