shithub: libvpx

Download patch

ref: dcbe6750e10f4281e5d50309dae98dbaf6169fea
parent: 6ee88546c09d777ca971f47a2f1216d6c5946929
parent: 2c2fea2c5bab1761de6ad36c93e030a395a3e77e
author: Jerome Jiang <jianj@google.com>
date: Tue Jan 23 20:12:44 EST 2018

Merge "Fix frame sizes in pkt to support spatial layers."

--- a/test/datarate_test.cc
+++ b/test/datarate_test.cc
@@ -1351,6 +1351,14 @@
               << "Buffer Underrun at frame " << pkt->data.frame.pts;
         }
       }
+
+      ASSERT_EQ(pkt->data.frame.width[sl],
+                top_sl_width_ * svc_params_.scaling_factor_num[sl] /
+                    svc_params_.scaling_factor_den[sl]);
+
+      ASSERT_EQ(pkt->data.frame.height[sl],
+                top_sl_height_ * svc_params_.scaling_factor_num[sl] /
+                    svc_params_.scaling_factor_den[sl]);
     }
   }
 
@@ -1393,6 +1401,8 @@
   int number_temporal_layers_;
   int layer_target_avg_bandwidth_[VPX_MAX_LAYERS];
   bool dynamic_drop_layer_;
+  unsigned int top_sl_width_;
+  unsigned int top_sl_height_;
 };
 static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
                                   const vpx_svc_extra_cfg_t *svc_params,
@@ -1486,6 +1496,8 @@
   number_spatial_layers_ = cfg_.ss_number_layers;
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
+  top_sl_width_ = 1280;
+  top_sl_height_ = 720;
   cfg_.rc_target_bitrate = 500;
   ResetModel();
   tune_content_ = 1;
@@ -1527,6 +1539,8 @@
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
                                        0, 400);
+  top_sl_width_ = 640;
+  top_sl_height_ = 480;
   // TODO(marpan): Check that effective_datarate for each layer hits the
   // layer target_bitrate.
   for (int i = 200; i <= 800; i += 200) {
@@ -1577,6 +1591,8 @@
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
                                        0, 400);
+  top_sl_width_ = 640;
+  top_sl_height_ = 480;
   // TODO(marpan): Check that effective_datarate for each layer hits the
   // layer target_bitrate.
   // For SVC, noise_sen = 1 means denoising only the top spatial layer
@@ -1633,6 +1649,8 @@
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
                                        0, 400);
+  top_sl_width_ = 640;
+  top_sl_height_ = 480;
   // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
   // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
   for (int j = 64; j <= 67; j++) {
@@ -1675,6 +1693,8 @@
   number_spatial_layers_ = cfg_.ss_number_layers;
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
+  top_sl_width_ = 1280;
+  top_sl_height_ = 720;
   cfg_.rc_target_bitrate = 800;
   ResetModel();
   assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
@@ -1722,6 +1742,8 @@
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
                                        0, 400);
+  top_sl_width_ = 640;
+  top_sl_height_ = 480;
   cfg_.rc_target_bitrate = 800;
   ResetModel();
   assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
@@ -1769,6 +1791,8 @@
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
                                        0, 400);
+  top_sl_width_ = 640;
+  top_sl_height_ = 480;
   cfg_.rc_target_bitrate = 800;
   ResetModel();
   dynamic_drop_layer_ = true;
@@ -1812,6 +1836,8 @@
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
                                        0, 400);
+  top_sl_width_ = 640;
+  top_sl_height_ = 480;
   // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
   // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
   for (int j = 32; j <= 35; j++) {
@@ -1856,6 +1882,8 @@
   number_spatial_layers_ = cfg_.ss_number_layers;
   number_temporal_layers_ = cfg_.ts_number_layers;
   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
+  top_sl_width_ = 1280;
+  top_sl_height_ = 720;
   cfg_.rc_target_bitrate = 800;
   ResetModel();
   assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
@@ -1911,6 +1939,8 @@
   bits_in_buffer_model_[1] =
       cfg_.layer_target_bitrate[1] * cfg_.rc_buf_initial_sz;
   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
+  top_sl_width_ = 1280;
+  top_sl_height_ = 720;
   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
   CheckLayerRateTargeting(&cfg_, number_spatial_layers_,
                           number_temporal_layers_, file_datarate_, 0.78, 1.15);
--- a/test/resize_test.cc
+++ b/test/resize_test.cc
@@ -278,10 +278,10 @@
   }
 
   virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
-    ASSERT_NE(static_cast<int>(pkt->data.frame.width), 0);
-    ASSERT_NE(static_cast<int>(pkt->data.frame.height), 0);
-    encode_frame_width_.push_back(pkt->data.frame.width);
-    encode_frame_height_.push_back(pkt->data.frame.height);
+    ASSERT_NE(static_cast<int>(pkt->data.frame.width[0]), 0);
+    ASSERT_NE(static_cast<int>(pkt->data.frame.height[0]), 0);
+    encode_frame_width_.push_back(pkt->data.frame.width[0]);
+    encode_frame_height_.push_back(pkt->data.frame.height[0]);
   }
 
   unsigned int GetFrameWidth(size_t idx) const {
@@ -485,10 +485,10 @@
   }
 
   virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
-    ASSERT_NE(static_cast<int>(pkt->data.frame.width), 0);
-    ASSERT_NE(static_cast<int>(pkt->data.frame.height), 0);
-    encode_frame_width_.push_back(pkt->data.frame.width);
-    encode_frame_height_.push_back(pkt->data.frame.height);
+    ASSERT_NE(static_cast<int>(pkt->data.frame.width[0]), 0);
+    ASSERT_NE(static_cast<int>(pkt->data.frame.height[0]), 0);
+    encode_frame_width_.push_back(pkt->data.frame.width[0]);
+    encode_frame_height_.push_back(pkt->data.frame.height[0]);
   }
 
   unsigned int GetMismatchFrames() { return mismatch_nframes_; }
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -911,8 +911,8 @@
             (unsigned long)((delta * ctx->cfg.g_timebase.den + round) /
                             ctx->cfg.g_timebase.num / 10000000);
         pkt.data.frame.flags = lib_flags << 16;
-        pkt.data.frame.width = cpi->common.Width;
-        pkt.data.frame.height = cpi->common.Height;
+        pkt.data.frame.width[0] = cpi->common.Width;
+        pkt.data.frame.height[0] = cpi->common.Height;
 
         if (lib_flags & FRAMEFLAGS_KEY) {
           pkt.data.frame.flags |= VPX_FRAME_IS_KEY;
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -1233,6 +1233,8 @@
           ctx->pending_frame_magnitude |= size;
           cx_data += size;
           cx_data_sz -= size;
+          pkt.data.frame.width[cpi->svc.spatial_layer_id] = cpi->common.width;
+          pkt.data.frame.height[cpi->svc.spatial_layer_id] = cpi->common.height;
 
           if (ctx->output_cx_pkt_cb.output_cx_pkt) {
             pkt.kind = VPX_CODEC_CX_FRAME_PKT;
@@ -1259,8 +1261,8 @@
         pkt.data.frame.duration = (unsigned long)ticks_to_timebase_units(
             timebase, dst_end_time_stamp - dst_time_stamp);
         pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags);
-        pkt.data.frame.width = cpi->common.width;
-        pkt.data.frame.height = cpi->common.height;
+        pkt.data.frame.width[cpi->svc.spatial_layer_id] = cpi->common.width;
+        pkt.data.frame.height[cpi->svc.spatial_layer_id] = cpi->common.height;
 
         if (ctx->pending_cx_data) {
           if (size) ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
--- a/vpx/vpx_encoder.h
+++ b/vpx/vpx_encoder.h
@@ -182,8 +182,10 @@
        * Only applicable when "output partition" mode is enabled. First
        * partition has id 0.*/
       int partition_id;
-      unsigned int width;               /**< frame width */
-      unsigned int height;              /**< frame height */
+      /*!\brief Width and height of frames in this packet. VP8 will only use the
+       * first one.*/
+      unsigned int width[VPX_SS_MAX_LAYERS];  /**< frame width */
+      unsigned int height[VPX_SS_MAX_LAYERS]; /**< frame height */
     } frame;                            /**< data for compressed frame packet */
     vpx_fixed_buf_t twopass_stats;      /**< data for two-pass packet */
     vpx_fixed_buf_t firstpass_mb_stats; /**< first pass mb packet */