Home | History | Annotate | Download | only in common_video
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      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
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include <math.h>
     12 #include <string.h>
     13 
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "webrtc/common_video/interface/i420_video_frame.h"
     16 #include "webrtc/system_wrappers/interface/ref_count.h"
     17 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     18 #include "webrtc/system_wrappers/interface/scoped_refptr.h"
     19 
     20 namespace webrtc {
     21 
     22 bool EqualFrames(const I420VideoFrame& frame1,
     23                  const I420VideoFrame& frame2);
     24 bool EqualFramesExceptSize(const I420VideoFrame& frame1,
     25                            const I420VideoFrame& frame2);
     26 int ExpectedSize(int plane_stride, int image_height, PlaneType type);
     27 
     28 TEST(TestI420VideoFrame, InitialValues) {
     29   I420VideoFrame frame;
     30   // Invalid arguments - one call for each variable.
     31   EXPECT_TRUE(frame.IsZeroSize());
     32   EXPECT_EQ(-1, frame.CreateEmptyFrame(0, 10, 10, 14, 14));
     33   EXPECT_EQ(-1, frame.CreateEmptyFrame(10, -1, 10, 90, 14));
     34   EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 0, 14, 18));
     35   EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 10, -2, 13));
     36   EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 10, 14, 0));
     37   EXPECT_EQ(0, frame.CreateEmptyFrame(10, 10, 10, 14, 90));
     38   EXPECT_FALSE(frame.IsZeroSize());
     39 }
     40 
     41 TEST(TestI420VideoFrame, WidthHeightValues) {
     42   I420VideoFrame frame;
     43   const int valid_value = 10;
     44   const int invalid_value = -1;
     45   EXPECT_EQ(0, frame.CreateEmptyFrame(10, 10, 10, 14, 90));
     46   EXPECT_EQ(valid_value, frame.width());
     47   EXPECT_EQ(invalid_value, frame.set_width(invalid_value));
     48   EXPECT_EQ(valid_value, frame.height());
     49   EXPECT_EQ(valid_value, frame.height());
     50   EXPECT_EQ(invalid_value, frame.set_height(0));
     51   EXPECT_EQ(valid_value, frame.height());
     52   frame.set_timestamp(123u);
     53   EXPECT_EQ(123u, frame.timestamp());
     54   frame.set_ntp_time_ms(456);
     55   EXPECT_EQ(456, frame.ntp_time_ms());
     56   frame.set_render_time_ms(789);
     57   EXPECT_EQ(789, frame.render_time_ms());
     58 }
     59 
     60 TEST(TestI420VideoFrame, SizeAllocation) {
     61   I420VideoFrame frame;
     62   EXPECT_EQ(0, frame. CreateEmptyFrame(10, 10, 12, 14, 220));
     63   int height = frame.height();
     64   int stride_y = frame.stride(kYPlane);
     65   int stride_u = frame.stride(kUPlane);
     66   int stride_v = frame.stride(kVPlane);
     67   // Verify that allocated size was computed correctly.
     68   EXPECT_EQ(ExpectedSize(stride_y, height, kYPlane),
     69             frame.allocated_size(kYPlane));
     70   EXPECT_EQ(ExpectedSize(stride_u, height, kUPlane),
     71             frame.allocated_size(kUPlane));
     72   EXPECT_EQ(ExpectedSize(stride_v, height, kVPlane),
     73             frame.allocated_size(kVPlane));
     74 }
     75 
     76 TEST(TestI420VideoFrame, ResetSize) {
     77   I420VideoFrame frame;
     78   EXPECT_EQ(0, frame. CreateEmptyFrame(10, 10, 12, 14, 220));
     79   EXPECT_FALSE(frame.IsZeroSize());
     80   frame.ResetSize();
     81   EXPECT_TRUE(frame.IsZeroSize());
     82 }
     83 
     84 TEST(TestI420VideoFrame, CopyFrame) {
     85   I420VideoFrame frame1, frame2;
     86   uint32_t timestamp = 1;
     87   int64_t ntp_time_ms = 2;
     88   int64_t render_time_ms = 3;
     89   int stride_y = 15;
     90   int stride_u = 10;
     91   int stride_v = 10;
     92   int width = 15;
     93   int height = 15;
     94   // Copy frame.
     95   EXPECT_EQ(0, frame1.CreateEmptyFrame(width, height,
     96                                        stride_y, stride_u, stride_v));
     97   frame1.set_timestamp(timestamp);
     98   frame1.set_ntp_time_ms(ntp_time_ms);
     99   frame1.set_render_time_ms(render_time_ms);
    100   const int kSizeY = 225;
    101   const int kSizeU = 80;
    102   const int kSizeV = 80;
    103   uint8_t buffer_y[kSizeY];
    104   uint8_t buffer_u[kSizeU];
    105   uint8_t buffer_v[kSizeV];
    106   memset(buffer_y, 16, kSizeY);
    107   memset(buffer_u, 8, kSizeU);
    108   memset(buffer_v, 4, kSizeV);
    109   frame2.CreateFrame(kSizeY, buffer_y,
    110                      kSizeU, buffer_u,
    111                      kSizeV, buffer_v,
    112                      width + 5, height + 5, stride_y + 5, stride_u, stride_v);
    113   // Frame of smaller dimensions - allocated sizes should not vary.
    114   EXPECT_EQ(0, frame1.CopyFrame(frame2));
    115   EXPECT_TRUE(EqualFramesExceptSize(frame1, frame2));
    116   EXPECT_EQ(kSizeY, frame1.allocated_size(kYPlane));
    117   EXPECT_EQ(kSizeU, frame1.allocated_size(kUPlane));
    118   EXPECT_EQ(kSizeV, frame1.allocated_size(kVPlane));
    119   // Verify copy of all parameters.
    120   // Frame of larger dimensions - update allocated sizes.
    121   EXPECT_EQ(0, frame2.CopyFrame(frame1));
    122   EXPECT_TRUE(EqualFrames(frame1, frame2));
    123 }
    124 
    125 TEST(TestI420VideoFrame, CloneFrame) {
    126   I420VideoFrame frame1;
    127   scoped_ptr<I420VideoFrame> frame2;
    128   const int kSizeY = 225;
    129   const int kSizeU = 80;
    130   const int kSizeV = 80;
    131   uint8_t buffer_y[kSizeY];
    132   uint8_t buffer_u[kSizeU];
    133   uint8_t buffer_v[kSizeV];
    134   memset(buffer_y, 16, kSizeY);
    135   memset(buffer_u, 8, kSizeU);
    136   memset(buffer_v, 4, kSizeV);
    137   frame1.CreateFrame(
    138       kSizeY, buffer_y, kSizeU, buffer_u, kSizeV, buffer_v, 20, 20, 20, 10, 10);
    139   frame1.set_timestamp(1);
    140   frame1.set_ntp_time_ms(2);
    141   frame1.set_render_time_ms(3);
    142 
    143   frame2.reset(frame1.CloneFrame());
    144   EXPECT_TRUE(frame2.get() != NULL);
    145   EXPECT_TRUE(EqualFrames(frame1, *frame2));
    146 }
    147 
    148 TEST(TestI420VideoFrame, CopyBuffer) {
    149   I420VideoFrame frame1, frame2;
    150   int width = 15;
    151   int height = 15;
    152   int stride_y = 15;
    153   int stride_uv = 10;
    154   const int kSizeY = 225;
    155   const int kSizeUv = 80;
    156   EXPECT_EQ(0, frame2.CreateEmptyFrame(width, height,
    157                                        stride_y, stride_uv, stride_uv));
    158   uint8_t buffer_y[kSizeY];
    159   uint8_t buffer_u[kSizeUv];
    160   uint8_t buffer_v[kSizeUv];
    161   memset(buffer_y, 16, kSizeY);
    162   memset(buffer_u, 8, kSizeUv);
    163   memset(buffer_v, 4, kSizeUv);
    164   frame2.CreateFrame(kSizeY, buffer_y,
    165                      kSizeUv, buffer_u,
    166                      kSizeUv, buffer_v,
    167                      width, height, stride_y, stride_uv, stride_uv);
    168   // Copy memory (at least allocated size).
    169   EXPECT_EQ(memcmp(buffer_y, frame2.buffer(kYPlane), kSizeY), 0);
    170   EXPECT_EQ(memcmp(buffer_u, frame2.buffer(kUPlane), kSizeUv), 0);
    171   EXPECT_EQ(memcmp(buffer_v, frame2.buffer(kVPlane), kSizeUv), 0);
    172   // Comapre size.
    173   EXPECT_LE(kSizeY, frame2.allocated_size(kYPlane));
    174   EXPECT_LE(kSizeUv, frame2.allocated_size(kUPlane));
    175   EXPECT_LE(kSizeUv, frame2.allocated_size(kVPlane));
    176 }
    177 
    178 TEST(TestI420VideoFrame, FrameSwap) {
    179   I420VideoFrame frame1, frame2;
    180   uint32_t timestamp1 = 1;
    181   int64_t ntp_time_ms1 = 2;
    182   int64_t render_time_ms1 = 3;
    183   int stride_y1 = 15;
    184   int stride_u1 = 10;
    185   int stride_v1 = 10;
    186   int width1 = 15;
    187   int height1 = 15;
    188   const int kSizeY1 = 225;
    189   const int kSizeU1 = 80;
    190   const int kSizeV1 = 80;
    191   uint32_t timestamp2 = 4;
    192   int64_t ntp_time_ms2 = 5;
    193   int64_t render_time_ms2 = 6;
    194   int stride_y2 = 30;
    195   int stride_u2 = 20;
    196   int stride_v2 = 20;
    197   int width2 = 30;
    198   int height2 = 30;
    199   const int kSizeY2 = 900;
    200   const int kSizeU2 = 300;
    201   const int kSizeV2 = 300;
    202   // Initialize frame1 values.
    203   EXPECT_EQ(0, frame1.CreateEmptyFrame(width1, height1,
    204                                        stride_y1, stride_u1, stride_v1));
    205   frame1.set_timestamp(timestamp1);
    206   frame1.set_ntp_time_ms(ntp_time_ms1);
    207   frame1.set_render_time_ms(render_time_ms1);
    208   // Set memory for frame1.
    209   uint8_t buffer_y1[kSizeY1];
    210   uint8_t buffer_u1[kSizeU1];
    211   uint8_t buffer_v1[kSizeV1];
    212   memset(buffer_y1, 2, kSizeY1);
    213   memset(buffer_u1, 4, kSizeU1);
    214   memset(buffer_v1, 8, kSizeV1);
    215   frame1.CreateFrame(kSizeY1, buffer_y1,
    216                      kSizeU1, buffer_u1,
    217                      kSizeV1, buffer_v1,
    218                      width1, height1, stride_y1, stride_u1, stride_v1);
    219   // Initialize frame2 values.
    220   EXPECT_EQ(0, frame2.CreateEmptyFrame(width2, height2,
    221                                        stride_y2, stride_u2, stride_v2));
    222   frame2.set_timestamp(timestamp2);
    223   frame1.set_ntp_time_ms(ntp_time_ms2);
    224   frame2.set_render_time_ms(render_time_ms2);
    225   // Set memory for frame2.
    226   uint8_t buffer_y2[kSizeY2];
    227   uint8_t buffer_u2[kSizeU2];
    228   uint8_t buffer_v2[kSizeV2];
    229   memset(buffer_y2, 0, kSizeY2);
    230   memset(buffer_u2, 1, kSizeU2);
    231   memset(buffer_v2, 2, kSizeV2);
    232   frame2.CreateFrame(kSizeY2, buffer_y2,
    233                      kSizeU2, buffer_u2,
    234                      kSizeV2, buffer_v2,
    235                      width2, height2, stride_y2, stride_u2, stride_v2);
    236   // Copy frames for subsequent comparison.
    237   I420VideoFrame frame1_copy, frame2_copy;
    238   frame1_copy.CopyFrame(frame1);
    239   frame2_copy.CopyFrame(frame2);
    240   // Swap frames.
    241   frame1.SwapFrame(&frame2);
    242   // Verify swap.
    243   EXPECT_TRUE(EqualFrames(frame1_copy, frame2));
    244   EXPECT_TRUE(EqualFrames(frame2_copy, frame1));
    245 }
    246 
    247 TEST(TestI420VideoFrame, RefCountedInstantiation) {
    248   // Refcounted instantiation - ref_count should correspond to the number of
    249   // instances.
    250   scoped_refptr<I420VideoFrame> ref_count_frame(
    251       new RefCountImpl<I420VideoFrame>());
    252   EXPECT_EQ(2, ref_count_frame->AddRef());
    253   EXPECT_EQ(3, ref_count_frame->AddRef());
    254   EXPECT_EQ(2, ref_count_frame->Release());
    255   EXPECT_EQ(1, ref_count_frame->Release());
    256 }
    257 
    258 bool EqualFrames(const I420VideoFrame& frame1,
    259                  const I420VideoFrame& frame2) {
    260   return (EqualFramesExceptSize(frame1, frame2) &&
    261           (frame1.allocated_size(kYPlane) == frame2.allocated_size(kYPlane)) &&
    262           (frame1.allocated_size(kUPlane) == frame2.allocated_size(kUPlane)) &&
    263           (frame1.allocated_size(kVPlane) == frame2.allocated_size(kVPlane)));
    264 }
    265 
    266 bool EqualFramesExceptSize(const I420VideoFrame& frame1,
    267                            const I420VideoFrame& frame2) {
    268   if ((frame1.width() != frame2.width()) ||
    269       (frame1.height() != frame2.height()) ||
    270       (frame1.stride(kYPlane) != frame2.stride(kYPlane)) ||
    271       (frame1.stride(kUPlane) != frame2.stride(kUPlane)) ||
    272       (frame1.stride(kVPlane) != frame2.stride(kVPlane)) ||
    273       (frame1.timestamp() != frame2.timestamp()) ||
    274       (frame1.ntp_time_ms() != frame2.ntp_time_ms()) ||
    275       (frame1.render_time_ms() != frame2.render_time_ms())) {
    276     return false;
    277   }
    278   // Memory should be the equal for the minimum of the two sizes.
    279   int size_y = std::min(frame1.allocated_size(kYPlane),
    280                         frame2.allocated_size(kYPlane));
    281   int size_u = std::min(frame1.allocated_size(kUPlane),
    282                         frame2.allocated_size(kUPlane));
    283   int size_v = std::min(frame1.allocated_size(kVPlane),
    284                         frame2.allocated_size(kVPlane));
    285   return (memcmp(frame1.buffer(kYPlane), frame2.buffer(kYPlane), size_y) == 0 &&
    286           memcmp(frame1.buffer(kUPlane), frame2.buffer(kUPlane), size_u) == 0 &&
    287           memcmp(frame1.buffer(kVPlane), frame2.buffer(kVPlane), size_v) == 0);
    288 }
    289 
    290 int ExpectedSize(int plane_stride, int image_height, PlaneType type) {
    291   if (type == kYPlane) {
    292     return (plane_stride * image_height);
    293   } else {
    294     int half_height = (image_height + 1) / 2;
    295     return (plane_stride * half_height);
    296   }
    297 }
    298 
    299 }  // namespace webrtc
    300