// Copyright 2018 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 #include #include "base/bind.h" #include "base/callback_helpers.h" #include "base/memory/raw_ptr.h" #include "base/run_loop.h" #include "base/test/gmock_callback_support.h" #include "base/test/task_environment.h" #include "media/base/media_util.h" #include "media/base/mock_filters.h" #include "media/base/video_decoder_config.h" #include "media/base/video_frame.h" #include "media/base/video_thumbnail_decoder.h" #include "media/base/video_types.h" #include "testing/gtest/include/gtest/gtest.h" using ::base::test::RunCallback; using ::base::test::RunOnceCallback; using ::testing::_; using ::testing::DoAll; namespace media { namespace { class VideoThumbnailDecoderTest : public testing::Test { public: VideoThumbnailDecoderTest() = default; VideoThumbnailDecoderTest(const VideoThumbnailDecoderTest&) = delete; VideoThumbnailDecoderTest& operator=(const VideoThumbnailDecoderTest&) = delete; ~VideoThumbnailDecoderTest() override = default; protected: void SetUp() override { auto mock_video_decoder = std::make_unique(); mock_video_decoder_ = mock_video_decoder.get(); VideoDecoderConfig valid_config( VideoCodec::kVP8, VP8PROFILE_ANY, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(), kNoTransformation, gfx::Size(1, 1), gfx::Rect(1, 1), gfx::Size(1, 1), EmptyExtraData(), EncryptionScheme::kUnencrypted); thumbnail_decoder_ = std::make_unique( std::move(mock_video_decoder), valid_config, std::vector{0u}); } void TearDown() override {} void Start() { thumbnail_decoder_->Start(base::BindOnce( &VideoThumbnailDecoderTest::OnFrameDecoded, base::Unretained(this))); base::RunLoop().RunUntilIdle(); } scoped_refptr CreateFrame() { return VideoFrame::CreateZeroInitializedFrame( VideoPixelFormat::PIXEL_FORMAT_I420, gfx::Size(1, 1), gfx::Rect(1, 1), gfx::Size(1, 1), base::TimeDelta()); } VideoThumbnailDecoder* thumbnail_decoder() { return thumbnail_decoder_.get(); } MockVideoDecoder* mock_video_decoder() { return mock_video_decoder_; } scoped_refptr frame() { return frame_; } private: void OnFrameDecoded(scoped_refptr frame) { frame_ = std::move(frame); } base::test::TaskEnvironment task_environment_; raw_ptr mock_video_decoder_; std::unique_ptr thumbnail_decoder_; // The video frame returned from the thumbnail decoder. scoped_refptr frame_; }; // Verifies a video frame can be delivered when decoder successfully created // the video frame. TEST_F(VideoThumbnailDecoderTest, Success) { auto expected_frame = CreateFrame(); EXPECT_CALL(*mock_video_decoder(), Initialize_(_, _, _, _, _, _)) .WillOnce(DoAll(RunOnceCallback<3>(DecoderStatus::Codes::kOk), RunCallback<4>(expected_frame))); EXPECT_CALL(*mock_video_decoder(), Decode_(_, _)) .Times(2) .WillRepeatedly(RunOnceCallback<1>(DecoderStatus::Codes::kOk)); Start(); EXPECT_TRUE(frame()); } // No output video frame when decoder failed to initialize. TEST_F(VideoThumbnailDecoderTest, InitializationFailed) { auto expected_frame = CreateFrame(); EXPECT_CALL(*mock_video_decoder(), Initialize_(_, _, _, _, _, _)) .WillOnce(RunOnceCallback<3>(DecoderStatus::Codes::kFailed)); Start(); EXPECT_FALSE(frame()); } // No output video frame when decoder failed to decode. TEST_F(VideoThumbnailDecoderTest, DecodingFailed) { auto expected_frame = CreateFrame(); EXPECT_CALL(*mock_video_decoder(), Initialize_(_, _, _, _, _, _)) .WillOnce(RunOnceCallback<3>(DecoderStatus::Codes::kOk)); EXPECT_CALL(*mock_video_decoder(), Decode_(_, _)) .WillOnce(RunOnceCallback<1>(DecoderStatus::Codes::kFailed)); Start(); EXPECT_FALSE(frame()); } } // namespace } // namespace media