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