]> granicus.if.org Git - libvpx/commitdiff
Add frame_type and show_idx to EncodeFrameResult
authorangiebird <angiebird@google.com>
Mon, 11 Nov 2019 20:32:10 +0000 (12:32 -0800)
committerangiebird <angiebird@google.com>
Mon, 18 Nov 2019 19:37:24 +0000 (11:37 -0800)
Let vp9_get_compressed_data update ENCODE_FRAME_RESULT, a C
version of EncodeFrameResult.
Let unit test to test frame_type and show_idx properly.

Change-Id: Id810c26c826254fd82249f19ab855ea3b440d99c

test/simple_encode_test.cc
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_encoder.h
vp9/simple_encode.cc
vp9/simple_encode.h
vp9/vp9_cx_iface.c

index f9643f612c4b2e344fb6dfc325c373a8cf0ce4be..30970514f3865dbe18c26bff18769581ce8a15b8 100644 (file)
@@ -62,13 +62,31 @@ TEST(SimpleEncode, EncodeFrame) {
                              target_bitrate, num_frames, file);
   simple_encode.ComputeFirstPassStats();
   int num_coding_frames = simple_encode.GetCodingFrameNum();
+  EXPECT_GE(num_coding_frames, num_frames);
+  // The coding frames include actual show frames and alternate reference
+  // frames, i.e. no show frame.
+  int ref_num_alternate_refereces = num_coding_frames - num_frames;
+  int num_alternate_refereces = 0;
   simple_encode.StartEncode();
   for (int i = 0; i < num_coding_frames; ++i) {
     EncodeFrameResult encode_frame_result;
+    if (i == 0) {
+      EXPECT_EQ(encode_frame_result.show_idx, 0);
+      EXPECT_EQ(encode_frame_result.frame_type, kKeyFrame)
+          << "The first coding frame should be key frame";
+    }
     simple_encode.EncodeFrame(&encode_frame_result);
-    // TODO(angiebird): For now, this test just check whether EncodeFrame can be
-    // run proprly. Add extra check later.
+    if (encode_frame_result.frame_type == kAlternateReference) {
+      ++num_alternate_refereces;
+    }
+    EXPECT_GE(encode_frame_result.show_idx, 0);
+    EXPECT_LT(encode_frame_result.show_idx, num_frames);
+    if (i == num_coding_frames - 1) {
+      EXPECT_EQ(encode_frame_result.show_idx, num_frames - 1)
+          << "The last coding frame should should be the last display order";
+    }
   }
+  EXPECT_EQ(num_alternate_refereces, ref_num_alternate_refereces);
   simple_encode.EndEncode();
 }
 
index c3dcb3ad7ba367ba083f66f013e45d4ce5014ee7..07f2d3444fde1f6b46354f9d5c5ad3b494596077 100644 (file)
@@ -7087,9 +7087,21 @@ static void setup_tpl_stats(VP9_COMP *cpi) {
 #endif  // CONFIG_NON_GREEDY_MV
 }
 
+static void init_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result) {
+  encode_frame_result->show_idx = -1;  // Actual encoding deosn't happen.
+}
+
+static void update_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result,
+                                       int show_idx,
+                                       FRAME_UPDATE_TYPE update_type) {
+  encode_frame_result->show_idx = show_idx;
+  encode_frame_result->update_type = update_type;
+}
+
 int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
                             size_t *size, uint8_t *dest, int64_t *time_stamp,
-                            int64_t *time_end, int flush) {
+                            int64_t *time_end, int flush,
+                            ENCODE_FRAME_RESULT *encode_frame_result) {
   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
   VP9_COMMON *const cm = &cpi->common;
   BufferPool *const pool = cm->buffer_pool;
@@ -7101,6 +7113,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
   int arf_src_index;
   const int gf_group_index = cpi->twopass.gf_group.index;
   int i;
+  init_encode_frame_result(encode_frame_result);
 
   if (is_one_pass_cbr_svc(cpi)) {
     vp9_one_pass_cbr_svc_start_layer(cpi);
@@ -7336,6 +7349,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
   bitstream_queue_set_frame_write(cm->current_video_frame * 2 + cm->show_frame);
 #endif
 
+  if (oxcf->pass != 1) {
+    update_encode_frame_result(
+        encode_frame_result, source->show_idx,
+        cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index]);
+  }
+
   cpi->td.mb.fp_src_pred = 0;
 #if CONFIG_REALTIME_ONLY
   if (cpi->use_svc) {
index e52ab65dd6c20fdafd82756a55603df9e897de3a..2304209531be85d48790f11f67e62920d4fd86fa 100644 (file)
@@ -822,6 +822,11 @@ typedef struct VP9_COMP {
   vpx_roi_map_t roi;
 } VP9_COMP;
 
+typedef struct ENCODE_FRAME_RESULT {
+  int show_idx;
+  FRAME_UPDATE_TYPE update_type;
+} ENCODE_FRAME_RESULT;
+
 void vp9_initialize_enc(void);
 
 void vp9_update_compressor_with_img_fmt(VP9_COMP *cpi, vpx_img_fmt_t img_fmt);
@@ -839,7 +844,8 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, vpx_enc_frame_flags_t frame_flags,
 
 int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
                             size_t *size, uint8_t *dest, int64_t *time_stamp,
-                            int64_t *time_end, int flush);
+                            int64_t *time_end, int flush,
+                            ENCODE_FRAME_RESULT *encode_frame_result);
 
 int vp9_get_preview_raw_frame(VP9_COMP *cpi, YV12_BUFFER_CONFIG *dest,
                               vp9_ppflags_t *flags);
index 020ea9fe84eb6250f98ae67bdc621a22938a948b..9319a7f9fb00920de3fd299a180907c7f7b2f9df 100644 (file)
@@ -73,6 +73,25 @@ static INLINE vpx_rational_t make_vpx_rational(int num, int den) {
   return v;
 }
 
+static INLINE FrameType
+get_frame_type_from_update_type(FRAME_UPDATE_TYPE update_type) {
+  // TODO(angiebird): Figure out if we need frame type other than key frame,
+  // alternate reference and inter frame
+  switch (update_type) {
+    case KF_UPDATE: return kKeyFrame; break;
+    case ARF_UPDATE: return kAlternateReference; break;
+    default: return kInterFrame; break;
+  }
+}
+
+static void update_encode_frame_result(
+    EncodeFrameResult *encode_frame_result,
+    const ENCODE_FRAME_RESULT *encode_frame_info) {
+  encode_frame_result->show_idx = encode_frame_info->show_idx;
+  encode_frame_result->frame_type =
+      get_frame_type_from_update_type(encode_frame_info->update_type);
+}
+
 SimpleEncode::SimpleEncode(int frame_width, int frame_height,
                            int frame_rate_num, int frame_rate_den,
                            int target_bitrate, int num_frames, FILE *file)
@@ -120,9 +139,10 @@ void SimpleEncode::ComputeFirstPassStats() {
         int flush = 1;  // Make vp9_get_compressed_data process a frame
         size_t size;
         unsigned int frame_flags = 0;
+        ENCODE_FRAME_RESULT encode_frame_info;
         // TODO(angiebird): Call vp9_first_pass directly
         vp9_get_compressed_data(cpi, &frame_flags, &size, NULL, &time_stamp,
-                                &time_end, flush);
+                                &time_end, flush, &encode_frame_info);
         // vp9_get_compressed_data only generates first pass stats not
         // compresses data
         assert(size == 0);
@@ -218,13 +238,17 @@ void SimpleEncode::EncodeFrame(EncodeFrameResult *encode_frame_result) {
   int64_t time_end;
   int flush = 1;  // Make vp9_get_compressed_data encode a frame
   unsigned int frame_flags = 0;
-  vp9_get_compressed_data(
-      cpi, &frame_flags, &encode_frame_result->coding_data_size,
-      encode_frame_result->coding_data.get(), &time_stamp, &time_end, flush);
+  ENCODE_FRAME_RESULT encode_frame_info;
+  vp9_get_compressed_data(cpi, &frame_flags,
+                          &encode_frame_result->coding_data_size,
+                          encode_frame_result->coding_data.get(), &time_stamp,
+                          &time_end, flush, &encode_frame_info);
   // vp9_get_compressed_data is expected to encode a frame every time, so the
   // data size should be greater than zero.
   assert(encode_frame_result->coding_data_size > 0);
   assert(encode_frame_result->coding_data_size < max_coding_data_size);
+
+  update_encode_frame_result(encode_frame_result, &encode_frame_info);
 }
 
 int SimpleEncode::GetCodingFrameNum() {
index b06339f430634b28fd7f91038ba4b46ece502939..26415a3c2d99edf4cfdca5c896fd65289c540796 100644 (file)
@@ -8,8 +8,8 @@ enum FrameType {
 };
 
 struct EncodeFrameResult {
-  // TODO(angiebird): int show_index;
-  // TODO(angiebird): FrameType frame_type;
+  int show_idx;
+  FrameType frame_type;
   size_t coding_data_size;
   // The EncodeFrame will allocate a buffer, write the coding data into the
   // buffer and give the ownership of the buffer to coding_data
index a019b976c31dbe0914f02ac0a9068362d4684a9e..3f5170859a71191f05453c60ad2fd784154772ac 100644 (file)
@@ -1249,11 +1249,12 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx,
       // compute first pass stats
       if (img) {
         int ret;
+        ENCODE_FRAME_RESULT encode_frame_result;
         vpx_codec_cx_pkt_t fps_pkt;
         // TODO(angiebird): Call vp9_first_pass directly
-        ret =
-            vp9_get_compressed_data(cpi, &lib_flags, &size, cx_data,
-                                    &dst_time_stamp, &dst_end_time_stamp, !img);
+        ret = vp9_get_compressed_data(cpi, &lib_flags, &size, cx_data,
+                                      &dst_time_stamp, &dst_end_time_stamp,
+                                      !img, &encode_frame_result);
         assert(size == 0);  // There is no compressed data in the first pass
         (void)ret;
         assert(ret == 0);
@@ -1271,10 +1272,11 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx,
       assert(0);
 #endif  // !CONFIG_REALTIME_ONLY
     } else {
+      ENCODE_FRAME_RESULT encode_frame_result;
       while (cx_data_sz >= ctx->cx_data_sz / 2 &&
              -1 != vp9_get_compressed_data(cpi, &lib_flags, &size, cx_data,
                                            &dst_time_stamp, &dst_end_time_stamp,
-                                           !img)) {
+                                           !img, &encode_frame_result)) {
         // Pack psnr pkt
         if (size > 0 && !cpi->use_svc) {
           // TODO(angiebird): Figure out while we don't need psnr pkt when