Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Unified Diff: content/renderer/media/rtc_video_decoder_bridge_tv_unittest.cc

Issue 14247018: Implement WebRTC in Chrome for TV (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added tests and refined the code Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/rtc_video_decoder_bridge_tv_unittest.cc
diff --git a/content/renderer/media/rtc_video_decoder_bridge_tv_unittest.cc b/content/renderer/media/rtc_video_decoder_bridge_tv_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1a78a8c48d0fa03c6db619346b36f5345ca229e8
--- /dev/null
+++ b/content/renderer/media/rtc_video_decoder_bridge_tv_unittest.cc
@@ -0,0 +1,342 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/synchronization/waitable_event.h"
+#include "base/task_runner_util.h"
+#include "content/renderer/media/mock_media_stream_dependency_factory.h"
+#include "content/renderer/media/rtc_video_decoder_bridge_tv.h"
+#include "media/base/decoder_buffer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/webrtc/modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h"
+
+using ::testing::_;
+using ::testing::Return;
+
+namespace content {
+
+class RTCVideoDecoderBridgeTvTest : public ::testing::Test {
+ public:
+ RTCVideoDecoderBridgeTvTest()
+ : bridge_(RTCVideoDecoderBridgeTv::Get()),
+ demuxer_(NULL),
+ video_stream_(NULL),
+ size_(1280, 720),
+ input_image_(&data_, sizeof(data_), sizeof(data_)),
+ data_('a'),
+ read_event_(false, false),
+ decoder_thread_("Test decoeder thread"),
+ decoder_thread_event_(false, false) {}
+
+ void ReadCallback(media::DemuxerStream::Status status,
+ const scoped_refptr<media::DecoderBuffer>& decoder_buffer) {
+ last_decoder_buffer_ = decoder_buffer;
+ read_event_.Signal();
+ }
+
+ void ExpectEqualsAndSignal(int32_t expected_result, int32_t actual_result) {
+ EXPECT_EQ(expected_result, actual_result);
+ decoder_thread_event_.Signal();
+ }
+
+ void ExpectNotEqualsAndSignal(int32_t unexpected_result,
+ int32_t actual_result) {
+ EXPECT_NE(unexpected_result, actual_result);
+ decoder_thread_event_.Signal();
+ }
+
+ protected:
+ virtual void SetUp() OVERRIDE {
+ memset(&codec_, 0, sizeof(codec_));
+ message_loop_proxy_ = base::MessageLoopProxy::current();
+ input_image_._frameType = webrtc::kKeyFrame;
+ input_image_._encodedWidth = size_.width();
+ input_image_._encodedHeight = size_.height();
+ input_image_._completeFrame = true;
+ decoder_thread_.Start();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ if (demuxer_) {
+ bridge_->ReleaseOwnership(&owner_factory_);
+ bridge_->DestroyDemuxer(demuxer_);
+ }
+ decoder_thread_.Stop();
+ }
+
+ base::Callback<void(int32_t)> BindExpectEquals(
+ int32_t expected_result) {
+ return base::Bind(&RTCVideoDecoderBridgeTvTest::ExpectEqualsAndSignal,
+ base::Unretained(this),
+ expected_result);
+ }
+
+ base::Callback<void(int32_t)> BindExpectNotEquals(
+ int32_t unexpected_result) {
+ return base::Bind(&RTCVideoDecoderBridgeTvTest::ExpectNotEqualsAndSignal,
+ base::Unretained(this),
+ unexpected_result);
+ }
+
+ base::Callback<int32_t(void)> BindInitDecode(
+ const webrtc::VideoCodec* codec,
+ int32_t num_cores) {
+ return base::Bind(&RTCVideoDecoderBridgeTv::InitDecode,
+ base::Unretained(bridge_),
+ codec,
+ num_cores);
+ }
+
+ base::Callback<int32_t(void)> BindDecode(
+ const webrtc::EncodedImage& input_image,
+ bool missing_frames,
+ const webrtc::RTPFragmentationHeader* fragmentation,
+ const webrtc::CodecSpecificInfo* info = NULL,
+ int64_t render_time_ms = -1) {
+ return base::Bind(&RTCVideoDecoderBridgeTv::Decode,
+ base::Unretained(bridge_),
+ input_image,
+ missing_frames,
+ fragmentation,
+ info,
+ render_time_ms);
+ }
+
+ void AcquireOwnershipAndCreateDemuxer() {
+ bridge_->AcquireOwnership(&owner_factory_);
+ demuxer_ = bridge_->CreateDemuxer(&owner_factory_, message_loop_proxy_);
+ }
+
+ void InitDecode() {
+ codec_.codecType = webrtc::kVideoCodecVP8;
+ codec_.width = size_.width();
+ codec_.height = size_.height();
+ base::PostTaskAndReplyWithResult(
+ decoder_thread_.message_loop_proxy(),
+ FROM_HERE,
+ BindInitDecode(&codec_, 1),
+ BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
+ decoder_thread_event_.Wait();
+ base::PostTaskAndReplyWithResult(
+ decoder_thread_.message_loop_proxy(),
+ FROM_HERE,
+ base::Bind(&RTCVideoDecoderBridgeTv::RegisterDecodeCompleteCallback,
+ base::Unretained(bridge_),
+ &decode_complete_callback_),
+ BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
+ decoder_thread_event_.Wait();
+ }
+
+ void GetVideoStream() {
+ video_stream_ = demuxer_->GetStream(media::DemuxerStream::VIDEO);
+ EXPECT_NE(static_cast<media::DemuxerStream*>(NULL), video_stream_);
+ EXPECT_EQ(media::kCodecVP8, video_stream_->video_decoder_config().codec());
+ EXPECT_EQ(size_, video_stream_->video_decoder_config().coded_size());
+ EXPECT_EQ(gfx::Rect(size_),
+ video_stream_->video_decoder_config().visible_rect());
+ EXPECT_EQ(size_, video_stream_->video_decoder_config().natural_size());
+ }
+
+ void PostDecodeAndWait(int32_t expected_result,
+ const webrtc::EncodedImage& input_image,
+ bool missing_frames,
+ const webrtc::RTPFragmentationHeader* fragmentation,
+ const webrtc::CodecSpecificInfo* info = NULL,
+ int64_t render_time_ms = -1) {
+ base::PostTaskAndReplyWithResult(
+ decoder_thread_.message_loop_proxy(),
+ FROM_HERE,
+ BindDecode(
+ input_image, missing_frames, fragmentation, info, render_time_ms),
+ BindExpectEquals(expected_result));
+ decoder_thread_event_.Wait();
+ }
+
+ RTCVideoDecoderBridgeTv* bridge_;
+ MockMediaStreamDependencyFactory owner_factory_;
+ MockMediaStreamDependencyFactory non_owner_factory_;
+ base::MessageLoopProxy* message_loop_proxy_;
+ media::Demuxer* demuxer_;
+ media::DemuxerStream* video_stream_;
+ webrtc::VideoCodec codec_;
+ gfx::Size size_;
+ webrtc::EncodedImage input_image_;
+ unsigned char data_;
+ webrtc::MockDecodedImageCallback decode_complete_callback_;
+ base::WaitableEvent read_event_;
+ base::Thread decoder_thread_;
+ base::WaitableEvent decoder_thread_event_;
+ scoped_refptr<media::DecoderBuffer> last_decoder_buffer_;
+};
+
+TEST_F(RTCVideoDecoderBridgeTvTest, AcquireAndReleaseOwnership) {
+ EXPECT_TRUE(bridge_->AcquireOwnership(&owner_factory_));
+ EXPECT_FALSE(bridge_->AcquireOwnership(&non_owner_factory_));
+ bridge_->ReleaseOwnership(&owner_factory_);
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, CreateDemuxerAfterAcquireOwnership) {
+ EXPECT_TRUE(bridge_->AcquireOwnership(&owner_factory_));
+ EXPECT_EQ(static_cast<media::Demuxer*>(NULL),
+ bridge_->CreateDemuxer(&non_owner_factory_, message_loop_proxy_));
+ demuxer_ = bridge_->CreateDemuxer(&owner_factory_, message_loop_proxy_);
+ EXPECT_NE(static_cast<media::Demuxer*>(NULL), demuxer_);
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, CreateDemuxerBeforeAcquireOwnership) {
+ RTCVideoDecoderBridgeTv* bridge_ = RTCVideoDecoderBridgeTv::Get();
+ demuxer_ = bridge_->CreateDemuxer(&owner_factory_, message_loop_proxy_);
+ EXPECT_NE(static_cast<media::Demuxer*>(NULL), demuxer_);
+ EXPECT_EQ(static_cast<media::Demuxer*>(NULL),
+ bridge_->CreateDemuxer(&non_owner_factory_, message_loop_proxy_));
+ EXPECT_FALSE(bridge_->AcquireOwnership(&non_owner_factory_));
+ EXPECT_TRUE(bridge_->AcquireOwnership(&owner_factory_));
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, InitDecodeReturnsErrorOnNonVP8Codec) {
+ AcquireOwnershipAndCreateDemuxer();
+ codec_.codecType = webrtc::kVideoCodecI420;
+ base::PostTaskAndReplyWithResult(
+ decoder_thread_.message_loop_proxy(),
+ FROM_HERE,
+ BindInitDecode(&codec_, 1),
+ BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
+ decoder_thread_event_.Wait();
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, InitDecodeReturnsErrorOnFeedbackMode) {
+ AcquireOwnershipAndCreateDemuxer();
+ codec_.codecType = webrtc::kVideoCodecVP8;
+ codec_.codecSpecific.VP8.feedbackModeOn = true;
+ base::PostTaskAndReplyWithResult(
+ decoder_thread_.message_loop_proxy(),
+ FROM_HERE,
+ BindInitDecode(&codec_, 1),
+ BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
+ decoder_thread_event_.Wait();
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, DecodeReturnsErrorBeforeInitDecode) {
+ AcquireOwnershipAndCreateDemuxer();
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_UNINITIALIZED, input_image_, false, NULL, NULL, 0);
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, DecodeReturnsErrorOnDamagedBitstream) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ input_image_._completeFrame = false;
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, DecodeReturnsErrorOnMissingFrames) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_ERROR, input_image_, true, NULL, NULL, 0);
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, GetNonVideoStreamFails) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ EXPECT_EQ(static_cast<media::DemuxerStream*>(NULL),
+ demuxer_->GetStream(media::DemuxerStream::AUDIO));
+ EXPECT_EQ(static_cast<media::DemuxerStream*>(NULL),
+ demuxer_->GetStream(media::DemuxerStream::UNKNOWN));
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, GetVideoStreamSucceeds) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ GetVideoStream();
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, DecodeReturnsErrorOnNonKeyFrameAtFirst) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ GetVideoStream();
+ input_image_._frameType = webrtc::kDeltaFrame;
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, DecodeUpdatesVideoSizeOnKeyFrame) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ GetVideoStream();
+ gfx::Size new_size(320, 240);
+ input_image_._encodedWidth = new_size.width();
+ input_image_._encodedHeight = new_size.height();
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
+ EXPECT_EQ(new_size, video_stream_->video_decoder_config().coded_size());
+ EXPECT_EQ(gfx::Rect(new_size),
+ video_stream_->video_decoder_config().visible_rect());
+ EXPECT_EQ(new_size, video_stream_->video_decoder_config().natural_size());
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, DecodeAdjustsTimestampFromZero) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ GetVideoStream();
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10000);
+ video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
+ base::Unretained(this)));
+ read_event_.Wait();
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(0),
+ last_decoder_buffer_->GetTimestamp());
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10033);
+ video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
+ base::Unretained(this)));
+ read_event_.Wait();
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(33),
+ last_decoder_buffer_->GetTimestamp());
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, DecodePassesDataCorrectly) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ GetVideoStream();
+ video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
+ base::Unretained(this)));
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
+ read_event_.Wait();
+ EXPECT_EQ(static_cast<int>(sizeof(data_)),
+ last_decoder_buffer_->GetDataSize());
+ EXPECT_EQ(data_, last_decoder_buffer_->GetData()[0]);
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, NextReadTriggersDecodeCompleteCallback) {
+ EXPECT_CALL(decode_complete_callback_, Decoded(_))
+ .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
+
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ GetVideoStream();
+ video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
+ base::Unretained(this)));
+ PostDecodeAndWait(
+ WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
+ read_event_.Wait();
+ video_stream_->Read(base::Bind(&RTCVideoDecoderBridgeTvTest::ReadCallback,
+ base::Unretained(this)));
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, ResetReturnsOk) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->Reset());
+}
+
+TEST_F(RTCVideoDecoderBridgeTvTest, ReleaseReturnsOk) {
+ AcquireOwnershipAndCreateDemuxer();
+ InitDecode();
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->Release());
+}
+
+} // content

Powered by Google App Engine
This is Rietveld 408576698