chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h"

#include <sstream>
#include <string_view>

#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/time/time.h"
#include "media/base/limits.h"
#include "media/base/mock_filters.h"
#include "media/base/video_codecs.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/media_buildflags.h"
#include "media/video/fake_video_encode_accelerator.h"
#include "media/video/mock_gpu_video_accelerator_factories.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/modules/mediarecorder/fake_encoded_video_frame.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_component_impl.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/video_frame_utils.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "ui/gfx/gpu_memory_buffer.h"

kVEAEncoderMinResolutionHeight;
kVEAEncoderMinResolutionWidth;

_;
DoAll;
InSequence;
Mock;
Return;
SaveArg;
TestWithParam;
ValuesIn;

namespace blink {
namespace {

// Specifies frame type for test.
enum class TestFrameType {};

const TestFrameType kTestFrameTypes[] =;

const VideoTrackRecorder::CodecId kTrackRecorderTestCodec[] =;
const gfx::Size kTrackRecorderTestSize[] =;
static const int kTrackRecorderTestSizeDiff =;

constexpr media::VideoCodec MediaVideoCodecFromCodecId(
    VideoTrackRecorder::CodecId id) {}

media::VideoCodecProfile MediaVideoCodecProfileFromCodecId(
    VideoTrackRecorder::CodecId id) {}

}  // namespace

ACTION_P(RunClosure, closure) {}

class MockTestingPlatform : public IOTaskRunnerTestingPlatformSupport {};

class MockVideoTrackRecorderCallbackInterface
    : public GarbageCollected<MockVideoTrackRecorderCallbackInterface>,
      public VideoTrackRecorder::CallbackInterface {};

class VideoTrackRecorderTestBase {};

class VideoTrackRecorderTest : public VideoTrackRecorderTestBase {};

class VideoTrackRecorderTestWithAllCodecs : public ::testing::Test,
                                            public VideoTrackRecorderTest {};

TEST_F(VideoTrackRecorderTestWithAllCodecs, NoCrashInConfigureEncoder) {}

class VideoTrackRecorderTestWithCodec
    : public TestWithParam<testing::tuple<VideoTrackRecorder::CodecId, bool>>,
      public VideoTrackRecorderTest,
      public ScopedMediaRecorderUseMediaVideoEncoderForTest {};

// Construct and destruct all objects, in particular |video_track_recorder_| and
// its inner object(s). This is a non trivial sequence.
TEST_P(VideoTrackRecorderTestWithCodec, ConstructAndDestruct) {}

// Initializes an encoder with very large frame that causes an error on the
// initialization. Check if the error is reported via OnVideoEncodingError().
TEST_P(VideoTrackRecorderTestWithCodec,
       SoftwareEncoderInitializeErrorWithLargeFrame) {}

INSTANTIATE_TEST_SUITE_P();

// TODO(crbug/1177593): refactor the test parameter space to something more
// reasonable. Many tests below ignore parts of the space leading to too much
// being tested.
class VideoTrackRecorderTestParam
    : public TestWithParam<testing::tuple<VideoTrackRecorder::CodecId,
                                          gfx::Size,
                                          bool,
                                          TestFrameType,
                                          bool>>,
      public VideoTrackRecorderTest,
      public ScopedMediaRecorderUseMediaVideoEncoderForTest {};

// Creates the encoder and encodes 2 frames of the same size; the encoder
// should be initialised and produce a keyframe, then a non-keyframe. Finally
// a frame of larger size is sent and is expected to be encoded as a keyframe.
// If |encode_alpha_channel| is enabled, encoder is expected to return a
// second output with encoded alpha data.
TEST_P(VideoTrackRecorderTestParam, VideoEncoding) {}

// VideoEncoding with the screencast track.
TEST_P(VideoTrackRecorderTestParam, ConfigureEncoderWithScreenContent) {}

// Same as VideoEncoding but add the EXPECT_CALL for the
// VideoEncoderMetricsProvider.
TEST_P(VideoTrackRecorderTestParam, CheckMetricsProviderInVideoEncoding) {}

// Inserts a frame which has different coded size than the visible rect and
// expects encode to be completed without raising any sanitizer flags.
TEST_P(VideoTrackRecorderTestParam, EncodeFrameWithPaddedCodedSize) {}

TEST_P(VideoTrackRecorderTestParam, EncodeFrameRGB) {}

TEST_P(VideoTrackRecorderTestParam, EncoderHonorsKeyFrameRequests) {}

TEST_P(VideoTrackRecorderTestParam,
       NoSubsequenceKeyFramesWithDefaultKeyFrameConfig) {}

TEST_P(VideoTrackRecorderTestParam, KeyFramesGeneratedWithIntervalCount) {}

TEST_P(VideoTrackRecorderTestParam, KeyFramesGeneratedWithIntervalDuration) {}

TEST_P(VideoTrackRecorderTestParam, UsesFrameTimestampsIfProvided) {}

std::string PrintTestParams(
    const testing::TestParamInfo<testing::tuple<VideoTrackRecorder::CodecId,
                                                gfx::Size,
                                                bool,
                                                TestFrameType,
                                                bool>>& info) {}

INSTANTIATE_TEST_SUITE_P();

class VideoTrackRecorderTestMediaVideoEncoderParam
    : public ::testing::TestWithParam<bool>,
      public VideoTrackRecorderTest,
      public ScopedMediaRecorderUseMediaVideoEncoderForTest {};

TEST_P(VideoTrackRecorderTestMediaVideoEncoderParam, RelaysReadyStateEnded) {}

// Inserts an opaque frame followed by two transparent frames and expects the
// newly introduced transparent frame to force keyframe output.
TEST_P(VideoTrackRecorderTestMediaVideoEncoderParam,
       ForceKeyframeOnAlphaSwitch) {}

// Inserts an OnError() call between sent frames.
TEST_P(VideoTrackRecorderTestMediaVideoEncoderParam, HandlesOnError) {}

// Hardware encoder fails and fallbacks a software encoder.
TEST_P(VideoTrackRecorderTestMediaVideoEncoderParam,
       HandleSoftwareEncoderFallback) {}

// Inserts a frame for encode and makes sure that it is released.
TEST_P(VideoTrackRecorderTestMediaVideoEncoderParam, ReleasesFrame) {}

// Waits for HW encoder support to be enumerated before setting up and
// performing an encode.
TEST_P(VideoTrackRecorderTestMediaVideoEncoderParam, WaitForEncoderSupport) {}

TEST_P(VideoTrackRecorderTestMediaVideoEncoderParam, RequiredRefreshRate) {}

INSTANTIATE_TEST_SUITE_P();

class VideoTrackRecorderPassthroughTest
    : public TestWithParam<VideoTrackRecorder::CodecId>,
      public VideoTrackRecorderTestBase {};

scoped_refptr<FakeEncodedVideoFrame> CreateFrame(
    bool is_key_frame,
    VideoTrackRecorder::CodecId codec) {}

TEST_F(VideoTrackRecorderPassthroughTest, RequestsAndFinishesEncodedOutput) {}

void DoNothing() {}

// Matcher for checking codec type
MATCHER_P(IsSameCodec, codec, "") {}

TEST_P(VideoTrackRecorderPassthroughTest, HandlesFrames) {}

TEST_F(VideoTrackRecorderPassthroughTest, DoesntForwardDeltaFrameFirst) {}

TEST_F(VideoTrackRecorderPassthroughTest, PausesAndResumes) {}

INSTANTIATE_TEST_SUITE_P();

class CodecEnumeratorTest : public ::testing::Test {};

TEST_F(CodecEnumeratorTest, GetPreferredCodecIdDefault) {}

TEST_F(CodecEnumeratorTest, GetPreferredCodecIdVp8) {}

TEST_F(CodecEnumeratorTest, GetPreferredCodecIdVp9) {}

TEST_F(CodecEnumeratorTest, GetPreferredCodecIdVp8Vp9) {}

TEST_F(CodecEnumeratorTest, MakeSupportedProfilesVp9) {}

TEST_F(CodecEnumeratorTest, MakeSupportedProfilesNoVp8) {}

TEST_F(CodecEnumeratorTest, GetFirstSupportedVideoCodecProfileVp9) {}

TEST_F(CodecEnumeratorTest, GetFirstSupportedVideoCodecProfileNoVp8) {}

TEST_F(CodecEnumeratorTest, GetFirstSupportedVideoCodecProfileVp9VBR) {}

TEST_F(CodecEnumeratorTest, GetFirstSupportedVideoCodecProfileNoVp8VBR) {}

#if BUILDFLAG(ENABLE_OPENH264)
TEST_F(CodecEnumeratorTest, FindSupportedVideoCodecProfileH264) {
  const CodecEnumerator emulator(MakeH264Profiles());
  EXPECT_EQ(std::make_pair(media::H264PROFILE_HIGH, /*vbr_support=*/false),
            emulator.FindSupportedVideoCodecProfile(CodecId::kH264,
                                                    media::H264PROFILE_HIGH));
}

TEST_F(CodecEnumeratorTest, FindSupportedVideoCodecProfileH264VBR) {
  const CodecEnumerator emulator(MakeH264Profiles(/*vbr_support=*/true));
  EXPECT_EQ(std::make_pair(media::H264PROFILE_HIGH, /*vbr_support=*/true),
            emulator.FindSupportedVideoCodecProfile(CodecId::kH264,
                                                    media::H264PROFILE_HIGH));
}

TEST_F(CodecEnumeratorTest, FindSupportedVideoCodecProfileNoProfileH264) {
  const CodecEnumerator emulator(MakeH264Profiles());
  EXPECT_EQ(
      std::make_pair(media::VIDEO_CODEC_PROFILE_UNKNOWN, /*vbr_support=*/false),
      emulator.FindSupportedVideoCodecProfile(
          CodecId::kH264, media::H264PROFILE_HIGH422PROFILE));
}

TEST_F(CodecEnumeratorTest, FindSupportedVideoCodecProfileNoProfileH264VBR) {
  const CodecEnumerator emulator(MakeH264Profiles(/*vbr_support=*/true));
  EXPECT_EQ(
      std::make_pair(media::VIDEO_CODEC_PROFILE_UNKNOWN, /*vbr_support=*/false),
      emulator.FindSupportedVideoCodecProfile(
          CodecId::kH264, media::H264PROFILE_HIGH422PROFILE));
}

#endif

}  // namespace blink