11bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org/*
21bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
31bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org *
41bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org *  Use of this source code is governed by a BSD-style license
51bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org *  that can be found in the LICENSE file in the root of the source
61bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org *  tree. An additional intellectual property rights grant can be found
71bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org *  in the file PATENTS.  All contributing project authors may
81bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org *  be found in the AUTHORS file in the root of the source tree.
91bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org */
101bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
111bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org// This file includes unit tests for ViECapturer.
121bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
131bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/video_engine/vie_capturer.h"
141bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
151bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include <vector>
161bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
171bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "testing/gmock/include/gmock/gmock.h"
181bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "testing/gtest/include/gtest/gtest.h"
191bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/common.h"
201bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/common_video/interface/native_handle.h"
211bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/common_video/interface/texture_video_frame.h"
221bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/modules/utility/interface/mock/mock_process_thread.h"
231bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/modules/video_capture/include/mock/mock_video_capture.h"
241bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
251bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/system_wrappers/interface/event_wrapper.h"
261bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/system_wrappers/interface/ref_count.h"
271bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
281bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/system_wrappers/interface/scoped_vector.h"
291bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include "webrtc/video_engine/mock/mock_vie_frame_provider_base.h"
301bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
311bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgusing ::testing::_;
321bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgusing ::testing::Invoke;
331bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgusing ::testing::NiceMock;
341bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgusing ::testing::Return;
351bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgusing ::testing::WithArg;
361bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
371bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org// If an output frame does not arrive in 500ms, the test will fail.
381bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#define FRAME_TIMEOUT_MS 500
391bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
401bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgnamespace webrtc {
411bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
421bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgbool EqualFrames(const I420VideoFrame& frame1,
431bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                 const I420VideoFrame& frame2);
441bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgbool EqualTextureFrames(const I420VideoFrame& frame1,
451bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                        const I420VideoFrame& frame2);
461bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgbool EqualBufferFrames(const I420VideoFrame& frame1,
471bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                       const I420VideoFrame& frame2);
481bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgbool EqualFramesVector(const ScopedVector<I420VideoFrame>& frames1,
491bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                       const ScopedVector<I420VideoFrame>& frames2);
501bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgI420VideoFrame* CreateI420VideoFrame(uint8_t length);
511bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
521bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgclass FakeNativeHandle : public NativeHandle {
531bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org public:
541bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  FakeNativeHandle() {}
551bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  virtual ~FakeNativeHandle() {}
561bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  virtual void* GetHandle() { return NULL; }
571bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org};
581bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
591bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgclass ViECapturerTest : public ::testing::Test {
601bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org protected:
611bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  ViECapturerTest()
621bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org      : mock_capture_module_(new NiceMock<MockVideoCaptureModule>()),
631bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org        mock_process_thread_(new NiceMock<MockProcessThread>),
641bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org        mock_frame_callback_(new NiceMock<MockViEFrameCallback>),
651bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org        data_callback_(NULL),
661bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org        output_frame_event_(EventWrapper::Create()) {
671bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
681bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
691bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  virtual void SetUp() {
701bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    EXPECT_CALL(*mock_capture_module_, RegisterCaptureDataCallback(_))
711bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org        .WillRepeatedly(Invoke(this, &ViECapturerTest::SetCaptureDataCallback));
721bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    EXPECT_CALL(*mock_frame_callback_, DeliverFrame(_, _, _, _))
731bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org        .WillRepeatedly(
741bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org            WithArg<1>(Invoke(this, &ViECapturerTest::AddOutputFrame)));
751bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
761bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    Config config;
771bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    vie_capturer_.reset(
781bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org        ViECapturer::CreateViECapture(
791bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org            0, 0, config, mock_capture_module_.get(), *mock_process_thread_));
801bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    vie_capturer_->RegisterFrameCallback(0, mock_frame_callback_.get());
811bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
821bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
831bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  virtual void TearDown() {
841bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    // ViECapturer accesses |mock_process_thread_| in destructor and should
851bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    // be deleted first.
861bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    vie_capturer_.reset();
871bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
881bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
891bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  void SetCaptureDataCallback(VideoCaptureDataCallback& data_callback) {
901bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    data_callback_ = &data_callback;
911bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
921bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
931bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  void AddInputFrame(I420VideoFrame* frame) {
941bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    data_callback_->OnIncomingCapturedFrame(0, *frame);
951bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
961bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
971bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  void AddOutputFrame(I420VideoFrame* frame) {
981bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    if (frame->native_handle() == NULL)
991bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org      output_frame_ybuffers_.push_back(frame->buffer(kYPlane));
1001bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    // Clone the frames because ViECapturer owns the frames.
1011bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    output_frames_.push_back(frame->CloneFrame());
1021bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    output_frame_event_->Set();
1031bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
1041bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1051bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  void WaitOutputFrame() {
1061bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    EXPECT_EQ(kEventSignaled, output_frame_event_->Wait(FRAME_TIMEOUT_MS));
1071bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
1081bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1091bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  scoped_ptr<MockVideoCaptureModule> mock_capture_module_;
1101bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  scoped_ptr<MockProcessThread> mock_process_thread_;
1111bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  scoped_ptr<MockViEFrameCallback> mock_frame_callback_;
1121bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1131bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // Used to send input capture frames to ViECapturer.
1141bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  VideoCaptureDataCallback* data_callback_;
1151bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1161bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  scoped_ptr<ViECapturer> vie_capturer_;
1171bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1181bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // Input capture frames of ViECapturer.
1191bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  ScopedVector<I420VideoFrame> input_frames_;
1201bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1211bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // Indicate an output frame has arrived.
1221bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  scoped_ptr<EventWrapper> output_frame_event_;
1231bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1241bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // Output delivered frames of ViECaptuer.
1251bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  ScopedVector<I420VideoFrame> output_frames_;
1261bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1271bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // The pointers of Y plane buffers of output frames. This is used to verify
1281bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // the frame are swapped and not copied.
1291bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  std::vector<uint8_t*> output_frame_ybuffers_;
1301bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org};
1311bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1321bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgTEST_F(ViECapturerTest, TestTextureFrames) {
1331bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  const int kNumFrame = 3;
1341bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  for (int i = 0 ; i < kNumFrame; ++i) {
1351bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    webrtc::RefCountImpl<FakeNativeHandle>* handle =
1361bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org              new webrtc::RefCountImpl<FakeNativeHandle>();
1371bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    input_frames_.push_back(new TextureVideoFrame(handle, i, i, i, i));
1381bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    AddInputFrame(input_frames_[i]);
1391bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    WaitOutputFrame();
1401bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
1411bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1421bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  EXPECT_TRUE(EqualFramesVector(input_frames_, output_frames_));
1431bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
1441bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1451bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgTEST_F(ViECapturerTest, TestI420Frames) {
1461bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  const int kNumFrame = 4;
1471bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  ScopedVector<I420VideoFrame> copied_input_frames;
1481bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  std::vector<uint8_t*> ybuffer_pointers;
1491bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  for (int i = 0; i < kNumFrame; ++i) {
1501bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    input_frames_.push_back(CreateI420VideoFrame(static_cast<uint8_t>(i + 1)));
1511bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    ybuffer_pointers.push_back(input_frames_[i]->buffer(kYPlane));
1521bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    // Copy input frames because the buffer data will be swapped.
1531bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    copied_input_frames.push_back(input_frames_[i]->CloneFrame());
1541bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    AddInputFrame(input_frames_[i]);
1551bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    WaitOutputFrame();
1561bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
1571bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1581bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  EXPECT_TRUE(EqualFramesVector(copied_input_frames, output_frames_));
1591bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // Make sure the buffer is swapped and not copied.
1601bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  for (int i = 0; i < kNumFrame; ++i)
1611bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    EXPECT_EQ(ybuffer_pointers[i], output_frame_ybuffers_[i]);
1621bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // The pipeline should be filled with frames with allocated buffers. Check
1631bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  // the last input frame has the same allocated size after swapping.
1641bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  EXPECT_EQ(input_frames_.back()->allocated_size(kYPlane),
1651bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org            copied_input_frames.back()->allocated_size(kYPlane));
1661bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
1671bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1681bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgTEST_F(ViECapturerTest, TestI420FrameAfterTextureFrame) {
1691bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  webrtc::RefCountImpl<FakeNativeHandle>* handle =
1701bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org      new webrtc::RefCountImpl<FakeNativeHandle>();
1711bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  input_frames_.push_back(new TextureVideoFrame(handle, 1, 1, 1, 1));
1721bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  AddInputFrame(input_frames_[0]);
1731bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  WaitOutputFrame();
1741bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1751bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  input_frames_.push_back(CreateI420VideoFrame(1));
1761bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  scoped_ptr<I420VideoFrame> copied_input_frame(input_frames_[1]->CloneFrame());
1771bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  AddInputFrame(copied_input_frame.get());
1781bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  WaitOutputFrame();
1791bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1801bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  EXPECT_TRUE(EqualFramesVector(input_frames_, output_frames_));
1811bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
1821bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1831bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgTEST_F(ViECapturerTest, TestTextureFrameAfterI420Frame) {
1841bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  input_frames_.push_back(CreateI420VideoFrame(1));
1851bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  scoped_ptr<I420VideoFrame> copied_input_frame(input_frames_[0]->CloneFrame());
1861bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  AddInputFrame(copied_input_frame.get());
1871bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  WaitOutputFrame();
1881bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1891bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  webrtc::RefCountImpl<FakeNativeHandle>* handle =
1901bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org      new webrtc::RefCountImpl<FakeNativeHandle>();
1911bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  input_frames_.push_back(new TextureVideoFrame(handle, 1, 1, 1, 1));
1921bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  AddInputFrame(input_frames_[1]);
1931bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  WaitOutputFrame();
1941bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1951bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  EXPECT_TRUE(EqualFramesVector(input_frames_, output_frames_));
1961bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
1971bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
1981bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgbool EqualFrames(const I420VideoFrame& frame1,
1991bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                 const I420VideoFrame& frame2) {
2001bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  if (frame1.native_handle() != NULL || frame2.native_handle() != NULL)
2011bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    return EqualTextureFrames(frame1, frame2);
2021bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  return EqualBufferFrames(frame1, frame2);
2031bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
2041bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
2051bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgbool EqualTextureFrames(const I420VideoFrame& frame1,
2061bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                        const I420VideoFrame& frame2) {
2071bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  return ((frame1.native_handle() == frame2.native_handle()) &&
2081bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.width() == frame2.width()) &&
2091bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.height() == frame2.height()) &&
2101bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.timestamp() == frame2.timestamp()) &&
2111bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.render_time_ms() == frame2.render_time_ms()));
2121bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
2131bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
2141bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgbool EqualBufferFrames(const I420VideoFrame& frame1,
2151bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                       const I420VideoFrame& frame2) {
2161bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  return ((frame1.width() == frame2.width()) &&
2171bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.height() == frame2.height()) &&
2181bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.stride(kYPlane) == frame2.stride(kYPlane)) &&
2191bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.stride(kUPlane) == frame2.stride(kUPlane)) &&
2201bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.stride(kVPlane) == frame2.stride(kVPlane)) &&
2211bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.timestamp() == frame2.timestamp()) &&
2221bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.ntp_time_ms() == frame2.ntp_time_ms()) &&
2231bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.render_time_ms() == frame2.render_time_ms()) &&
2241bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.allocated_size(kYPlane) == frame2.allocated_size(kYPlane)) &&
2251bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.allocated_size(kUPlane) == frame2.allocated_size(kUPlane)) &&
2261bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (frame1.allocated_size(kVPlane) == frame2.allocated_size(kVPlane)) &&
2271bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (memcmp(frame1.buffer(kYPlane), frame2.buffer(kYPlane),
2281bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                  frame1.allocated_size(kYPlane)) == 0) &&
2291bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (memcmp(frame1.buffer(kUPlane), frame2.buffer(kUPlane),
2301bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                  frame1.allocated_size(kUPlane)) == 0) &&
2311bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org          (memcmp(frame1.buffer(kVPlane), frame2.buffer(kVPlane),
2321bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                  frame1.allocated_size(kVPlane)) == 0));
2331bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
2341bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
2351bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgbool EqualFramesVector(const ScopedVector<I420VideoFrame>& frames1,
2361bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org                       const ScopedVector<I420VideoFrame>& frames2) {
2371bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  if (frames1.size() != frames2.size())
2381bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    return false;
2391bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  for (size_t i = 0; i < frames1.size(); ++i) {
2401bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org    if (!EqualFrames(*frames1[i], *frames2[i]))
2411bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org      return false;
2421bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  }
2431bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  return true;
2441bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
2451bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
2461bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgI420VideoFrame* CreateI420VideoFrame(uint8_t data) {
2471bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  I420VideoFrame* frame = new I420VideoFrame();
2481bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  const int width = 36;
2491bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  const int height = 24;
2501bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  const int kSizeY = width * height * 2;
2511bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  const int kSizeUV = width * height;
2521bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  uint8_t buffer[kSizeY];
2531bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  memset(buffer, data, kSizeY);
2541bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  frame->CreateFrame(
2551bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org      kSizeY, buffer, kSizeUV, buffer, kSizeUV, buffer, width, height, width,
2561bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org      width / 2, width / 2);
2571bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  frame->set_timestamp(data);
2581bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  frame->set_ntp_time_ms(data);
2591bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  frame->set_render_time_ms(data);
2601bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org  return frame;
2611bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}
2621bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org
2631bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org}  // namespace webrtc
264