Home | History | Annotate | Download | only in frame_editing
      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 <stdio.h>
     12 #include <stdlib.h>
     13 
     14 #include <fstream>
     15 
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 #include "webrtc/base/scoped_ptr.h"
     18 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
     19 #include "webrtc/test/testsupport/fileutils.h"
     20 #include "webrtc/tools/frame_editing/frame_editing_lib.h"
     21 
     22 namespace webrtc {
     23 namespace test {
     24 
     25 const int kWidth = 352;
     26 const int kHeight = 288;
     27 const size_t kFrameSize = CalcBufferSize(kI420, kWidth, kHeight);
     28 
     29 class FrameEditingTest : public ::testing::Test {
     30  protected:
     31   virtual void SetUp() {
     32     reference_video_ = ResourcePath("foreman_cif", "yuv");
     33     test_video_ = webrtc::test::TempFilename(webrtc::test::OutputPath(),
     34                                              "frame_editing_unittest.yuv");
     35 
     36     original_fid_ = fopen(reference_video_.c_str(), "rb");
     37     ASSERT_TRUE(original_fid_ != NULL);
     38 
     39     // Ensure the output file exists on disk.
     40     std::ofstream(test_video_.c_str(), std::ios::out);
     41     // Open the output file for reading.
     42     // TODO(holmer): Figure out why this file has to be opened here (test fails
     43     // if it's opened after the write operation performed in EditFrames).
     44     edited_fid_ = fopen(test_video_.c_str(), "rb");
     45     ASSERT_TRUE(edited_fid_ != NULL);
     46 
     47     original_buffer_.reset(new int[kFrameSize]);
     48     edited_buffer_.reset(new int[kFrameSize]);
     49     num_frames_read_ = 0;
     50   }
     51   virtual void TearDown() {
     52     fclose(original_fid_);
     53     fclose(edited_fid_);
     54     remove(test_video_.c_str());
     55   }
     56   // Compares the frames in both streams to the end of one of the streams.
     57   void CompareToTheEnd(FILE* test_video_fid,
     58                        FILE* ref_video_fid,
     59                        rtc::scoped_ptr<int[]>* ref_buffer,
     60                        rtc::scoped_ptr<int[]>* test_buffer) {
     61     while (!feof(test_video_fid) && !feof(ref_video_fid)) {
     62       num_bytes_read_ = fread(ref_buffer->get(), 1, kFrameSize, ref_video_fid);
     63       if (!feof(ref_video_fid)) {
     64         EXPECT_EQ(kFrameSize, num_bytes_read_);
     65       }
     66       num_bytes_read_ = fread(test_buffer->get(), 1, kFrameSize,
     67                               test_video_fid);
     68       if (!feof(test_video_fid)) {
     69         EXPECT_EQ(kFrameSize, num_bytes_read_);
     70       }
     71       if (!feof(test_video_fid) && !feof(test_video_fid)) {
     72         EXPECT_EQ(0, memcmp(ref_buffer->get(), test_buffer->get(),
     73                             kFrameSize));
     74       }
     75     }
     76     // There should not be anything left in either stream.
     77     EXPECT_EQ(!feof(test_video_fid), !feof(ref_video_fid));
     78   }
     79   std::string reference_video_;
     80   std::string test_video_;
     81   FILE* original_fid_;
     82   FILE* edited_fid_;
     83   size_t num_bytes_read_;
     84   rtc::scoped_ptr<int[]> original_buffer_;
     85   rtc::scoped_ptr<int[]> edited_buffer_;
     86   int num_frames_read_;
     87 };
     88 
     89 TEST_F(FrameEditingTest, ValidInPath) {
     90   const int kFirstFrameToProcess = 160;
     91   const int kInterval = -1;
     92   const int kLastFrameToProcess = 240;
     93 
     94   int result = EditFrames(reference_video_, kWidth, kHeight,
     95                           kFirstFrameToProcess, kInterval, kLastFrameToProcess,
     96                           test_video_);
     97   EXPECT_EQ(0, result);
     98 
     99   for (int i = 1; i < kFirstFrameToProcess; ++i) {
    100     num_bytes_read_ = fread(original_buffer_.get(), 1, kFrameSize,
    101                             original_fid_);
    102     EXPECT_EQ(kFrameSize, num_bytes_read_);
    103 
    104     num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, edited_fid_);
    105     EXPECT_EQ(kFrameSize, num_bytes_read_);
    106 
    107     EXPECT_EQ(0, memcmp(original_buffer_.get(), edited_buffer_.get(),
    108                         kFrameSize));
    109   }
    110   // Do not compare the frames that have been cut.
    111   for (int i = kFirstFrameToProcess; i <= kLastFrameToProcess; ++i) {
    112     num_bytes_read_ = fread(original_buffer_.get(), 1, kFrameSize,
    113                             original_fid_);
    114     EXPECT_EQ(kFrameSize, num_bytes_read_);
    115   }
    116   CompareToTheEnd(edited_fid_, original_fid_, &original_buffer_,
    117                   &edited_buffer_);
    118 }
    119 
    120 TEST_F(FrameEditingTest, EmptySetToCut) {
    121   const int kFirstFrameToProcess = 2;
    122   const int kInterval = -1;
    123   const int kLastFrameToProcess = 1;
    124 
    125   int result = EditFrames(reference_video_, kWidth, kHeight,
    126                           kFirstFrameToProcess, kInterval, kLastFrameToProcess,
    127                           test_video_);
    128   EXPECT_EQ(-10, result);
    129 }
    130 
    131 TEST_F(FrameEditingTest, InValidInPath) {
    132   const std::string kRefVideo_ = "PATH/THAT/DOES/NOT/EXIST";
    133 
    134   const int kFirstFrameToProcess = 30;
    135   const int kInterval = 1;
    136   const int kLastFrameToProcess = 120;
    137 
    138   int result = EditFrames(kRefVideo_, kWidth, kHeight, kFirstFrameToProcess,
    139                           kInterval, kLastFrameToProcess, test_video_);
    140   EXPECT_EQ(-11, result);
    141 }
    142 
    143 TEST_F(FrameEditingTest, DeletingEverySecondFrame) {
    144   const int kFirstFrameToProcess = 1;
    145   const int kInterval = -2;
    146   const int kLastFrameToProcess = 10000;
    147   // Set kLastFrameToProcess to a large value so that all frame are processed.
    148   int result = EditFrames(reference_video_, kWidth, kHeight,
    149                           kFirstFrameToProcess, kInterval, kLastFrameToProcess,
    150                           test_video_);
    151   EXPECT_EQ(0, result);
    152 
    153   while (!feof(original_fid_) && !feof(edited_fid_)) {
    154     num_bytes_read_ =
    155         fread(original_buffer_.get(), 1, kFrameSize, original_fid_);
    156     if (!feof(original_fid_)) {
    157       EXPECT_EQ(kFrameSize, num_bytes_read_);
    158       num_frames_read_++;
    159     }
    160     // We want to compare every second frame of the original to the edited.
    161     // kInterval=-2 and (num_frames_read_ - 1) % kInterval  will be -1 for
    162     // every second frame.
    163     // num_frames_read_ - 1 because we have deleted frame number 2, 4 , 6 etc.
    164     if ((num_frames_read_ - 1) % kInterval == -1) {
    165       num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize,
    166                               edited_fid_);
    167       if (!feof(edited_fid_)) {
    168         EXPECT_EQ(kFrameSize, num_bytes_read_);
    169       }
    170       if (!feof(original_fid_) && !feof(edited_fid_)) {
    171         EXPECT_EQ(0, memcmp(original_buffer_.get(),
    172                             edited_buffer_.get(), kFrameSize));
    173       }
    174     }
    175   }
    176 }
    177 
    178 TEST_F(FrameEditingTest, RepeatFrames) {
    179   const int kFirstFrameToProcess = 160;
    180   const int kInterval = 2;
    181   const int kLastFrameToProcess = 240;
    182 
    183   int result = EditFrames(reference_video_, kWidth, kHeight,
    184                           kFirstFrameToProcess, kInterval, kLastFrameToProcess,
    185                           test_video_);
    186   EXPECT_EQ(0, result);
    187 
    188   for (int i = 1; i < kFirstFrameToProcess; ++i) {
    189     num_bytes_read_ = fread(original_buffer_.get(), 1, kFrameSize,
    190                             original_fid_);
    191     EXPECT_EQ(kFrameSize, num_bytes_read_);
    192 
    193     num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, edited_fid_);
    194     EXPECT_EQ(kFrameSize, num_bytes_read_);
    195 
    196     EXPECT_EQ(0, memcmp(original_buffer_.get(), edited_buffer_.get(),
    197                         kFrameSize));
    198   }
    199   // Do not compare the frames that have been repeated.
    200   for (int i = kFirstFrameToProcess; i <= kLastFrameToProcess; ++i) {
    201     num_bytes_read_ = fread(original_buffer_.get(), 1, kFrameSize,
    202                             original_fid_);
    203     EXPECT_EQ(kFrameSize, num_bytes_read_);
    204     for (int i = 1; i <= kInterval; ++i) {
    205       num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize,
    206                               edited_fid_);
    207       EXPECT_EQ(kFrameSize, num_bytes_read_);
    208       EXPECT_EQ(0, memcmp(original_buffer_.get(), edited_buffer_.get(),
    209                           kFrameSize));
    210     }
    211   }
    212   CompareToTheEnd(edited_fid_, original_fid_, &original_buffer_,
    213                   &edited_buffer_);
    214 }
    215 }  // namespace test
    216 }  // namespace webrtc
    217