diff options
Diffstat (limited to 'chromium/media/renderers')
38 files changed, 458 insertions, 299 deletions
diff --git a/chromium/media/renderers/BUILD.gn b/chromium/media/renderers/BUILD.gn index a37d1891aec..00083feb2db 100644 --- a/chromium/media/renderers/BUILD.gn +++ b/chromium/media/renderers/BUILD.gn @@ -53,9 +53,9 @@ source_set("renderers") { "//media/filters", "//media/video", "//third_party/libyuv", - "//ui/gfx:geometry_skia", "//ui/gfx:memory_buffer", "//ui/gfx/geometry", + "//ui/gfx/geometry:geometry_skia", "//ui/gl", ] @@ -89,9 +89,7 @@ source_set("renderers") { ] } - configs += [ - "//media:subcomponent_config", - ] + configs += [ "//media:subcomponent_config" ] } # Note: This is a roll-up only target; do not expand the visibility. DEPS should diff --git a/chromium/media/renderers/audio_renderer_impl.cc b/chromium/media/renderers/audio_renderer_impl.cc index 305369256b7..74117712664 100644 --- a/chromium/media/renderers/audio_renderer_impl.cc +++ b/chromium/media/renderers/audio_renderer_impl.cc @@ -476,9 +476,9 @@ void AudioRendererImpl::OnDeviceInfoReceived( if (is_passthrough_) { AudioParameters::Format format = AudioParameters::AUDIO_FAKE; - if (codec == kCodecAC3) { + if (codec == AudioCodec::kAC3) { format = AudioParameters::AUDIO_BITSTREAM_AC3; - } else if (codec == kCodecEAC3) { + } else if (codec == AudioCodec::kEAC3) { format = AudioParameters::AUDIO_BITSTREAM_EAC3; } else { NOTREACHED(); @@ -538,11 +538,10 @@ void AudioRendererImpl::OnDeviceInfoReceived( // mixer will attempt to up-mix stereo source streams to just the left/right // speaker of the 5.1 setup, nulling out the other channels // (http://crbug.com/177872). - ChannelLayout hw_channel_layout = - hw_params.channel_layout() == CHANNEL_LAYOUT_DISCRETE || - try_supported_channel_layouts - ? CHANNEL_LAYOUT_STEREO - : hw_params.channel_layout(); + hw_channel_layout = hw_params.channel_layout() == CHANNEL_LAYOUT_DISCRETE || + try_supported_channel_layouts + ? CHANNEL_LAYOUT_STEREO + : hw_params.channel_layout(); int hw_channel_count = ChannelLayoutToChannelCount(hw_channel_layout); // The layout we pass to |audio_parameters_| will be used for the lifetime diff --git a/chromium/media/renderers/audio_renderer_impl.h b/chromium/media/renderers/audio_renderer_impl.h index b201648b67d..53dc93630d2 100644 --- a/chromium/media/renderers/audio_renderer_impl.h +++ b/chromium/media/renderers/audio_renderer_impl.h @@ -78,6 +78,10 @@ class MEDIA_EXPORT AudioRendererImpl const CreateAudioDecodersCB& create_audio_decoders_cb, MediaLog* media_log, SpeechRecognitionClient* speech_recognition_client = nullptr); + + AudioRendererImpl(const AudioRendererImpl&) = delete; + AudioRendererImpl& operator=(const AudioRendererImpl&) = delete; + ~AudioRendererImpl() override; // TimeSource implementation. @@ -383,8 +387,6 @@ class MEDIA_EXPORT AudioRendererImpl // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<AudioRendererImpl> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl); }; } // namespace media diff --git a/chromium/media/renderers/audio_renderer_impl_unittest.cc b/chromium/media/renderers/audio_renderer_impl_unittest.cc index 6a76173d67c..628c9502660 100644 --- a/chromium/media/renderers/audio_renderer_impl_unittest.cc +++ b/chromium/media/renderers/audio_renderer_impl_unittest.cc @@ -58,7 +58,7 @@ struct OutputFrames { } // namespace // Constants to specify the type of audio data used. -constexpr AudioCodec kCodec = kCodecVorbis; +constexpr AudioCodec kCodec = AudioCodec::kVorbis; constexpr SampleFormat kSampleFormat = kSampleFormatPlanarF32; constexpr ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; constexpr int kChannels = 2; @@ -136,9 +136,12 @@ class AudioRendererImplTest : public ::testing::Test, public RendererClient { base::Unretained(this)), &media_log_, nullptr); renderer_->tick_clock_ = &tick_clock_; - tick_clock_.Advance(base::TimeDelta::FromSeconds(1)); + tick_clock_.Advance(base::Seconds(1)); } + AudioRendererImplTest(const AudioRendererImplTest&) = delete; + AudioRendererImplTest& operator=(const AudioRendererImplTest&) = delete; + ~AudioRendererImplTest() override { SCOPED_TRACE("~AudioRendererImplTest()"); } @@ -251,9 +254,10 @@ class AudioRendererImplTest : public ::testing::Test, public RendererClient { hardware_params_.Reset(AudioParameters::AUDIO_BITSTREAM_EAC3, kChannelLayout, kOutputSamplesPerSecond, 512); sink_ = base::MakeRefCounted<FakeAudioRendererSink>(hardware_params_); - AudioDecoderConfig audio_config( - kCodecAC3, kSampleFormatEac3, kChannelLayout, kInputSamplesPerSecond, - EmptyExtraData(), EncryptionScheme::kUnencrypted); + AudioDecoderConfig audio_config(AudioCodec::kAC3, kSampleFormatEac3, + kChannelLayout, kInputSamplesPerSecond, + EmptyExtraData(), + EncryptionScheme::kUnencrypted); demuxer_stream_.set_audio_decoder_config(audio_config); ConfigureDemuxerStream(true); @@ -594,8 +598,6 @@ class AudioRendererImplTest : public ::testing::Test, public RendererClient { bool expected_init_result_; bool enter_pending_decoder_init_; bool ended_; - - DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest); }; TEST_F(AudioRendererImplTest, Initialize_Successful) { @@ -649,7 +651,7 @@ TEST_F(AudioRendererImplTest, SignalConfigChange) { // Force config change to simulate detected change from decoder stream. Expect // that RendererClient to be signaled with the new config. const AudioDecoderConfig kValidAudioConfig( - kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, + AudioCodec::kVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, EmptyExtraData(), EncryptionScheme::kUnencrypted); EXPECT_TRUE(kValidAudioConfig.IsValidConfig()); EXPECT_CALL(*this, OnAudioConfigChange(DecoderConfigEq(kValidAudioConfig))); @@ -923,7 +925,7 @@ TEST_F(AudioRendererImplTest, ChannelMask_DownmixDiscreteLayout) { int audio_channels = 9; AudioDecoderConfig audio_config( - kCodecOpus, kSampleFormat, CHANNEL_LAYOUT_DISCRETE, + AudioCodec::kOpus, kSampleFormat, CHANNEL_LAYOUT_DISCRETE, kInputSamplesPerSecond, EmptyExtraData(), EncryptionScheme::kUnencrypted); audio_config.SetChannelsForDiscrete(audio_channels); demuxer_stream_.set_audio_decoder_config(audio_config); @@ -976,8 +978,7 @@ TEST_F(AudioRendererImplTest, PendingRead_Flush) { FlushDuringPendingRead(); // Preroll again to a different timestamp and verify it completed normally. - const base::TimeDelta seek_timestamp = - base::TimeDelta::FromMilliseconds(1000); + const base::TimeDelta seek_timestamp = base::Milliseconds(1000); Preroll(seek_timestamp, seek_timestamp, PIPELINE_OK); } @@ -1095,8 +1096,8 @@ TEST_F(AudioRendererImplTest, RenderingDelayedForEarlyStartTime) { // through the desired output buffer; this allows for maximum test coverage. const double kBuffers = 4.5; const base::TimeDelta first_timestamp = - base::TimeDelta::FromSecondsD(hardware_params_.frames_per_buffer() * - kBuffers / hardware_params_.sample_rate()); + base::Seconds(hardware_params_.frames_per_buffer() * kBuffers / + hardware_params_.sample_rate()); Preroll(base::TimeDelta(), first_timestamp, PIPELINE_OK); StartTicking(); @@ -1278,8 +1279,7 @@ TEST_F(AudioRendererImplTest, TimeSourceBehavior) { // Consume some more audio data. frames_to_consume = frames_buffered(); - tick_clock_.Advance( - base::TimeDelta::FromSecondsD(1.0 / kOutputSamplesPerSecond)); + tick_clock_.Advance(base::Seconds(1.0 / kOutputSamplesPerSecond)); EXPECT_TRUE(ConsumeBufferedData(frames_to_consume)); // Time should change now that the audio hardware has called back. @@ -1314,7 +1314,7 @@ TEST_F(AudioRendererImplTest, TimeSourceBehavior) { // Advancing once more will exceed the amount of played out frames finally. const base::TimeDelta kOneSample = - base::TimeDelta::FromSecondsD(1.0 / kOutputSamplesPerSecond); + base::Seconds(1.0 / kOutputSamplesPerSecond); base::TimeTicks current_time = tick_clock_.NowTicks(); tick_clock_.Advance(kOneSample); EXPECT_EQ(current_time, CurrentMediaWallClockTime(&is_time_moving)); @@ -1324,7 +1324,7 @@ TEST_F(AudioRendererImplTest, TimeSourceBehavior) { DeliverRemainingAudio(); // Elapse a lot of time between StopTicking() and the next Render() call. - const base::TimeDelta kOneSecond = base::TimeDelta::FromSeconds(1); + const base::TimeDelta kOneSecond = base::Seconds(1); tick_clock_.Advance(kOneSecond); StartTicking(); @@ -1334,8 +1334,8 @@ TEST_F(AudioRendererImplTest, TimeSourceBehavior) { // Consume some buffered data with a small delay. uint32_t delay_frames = 500; - base::TimeDelta delay_time = base::TimeDelta::FromMicroseconds( - std::round(delay_frames * kOutputMicrosPerFrame)); + base::TimeDelta delay_time = + base::Microseconds(std::round(delay_frames * kOutputMicrosPerFrame)); frames_to_consume.value = frames_buffered().value / 16; EXPECT_TRUE(ConsumeBufferedData(frames_to_consume, delay_time)); diff --git a/chromium/media/renderers/decrypting_renderer.h b/chromium/media/renderers/decrypting_renderer.h index d803b7504ff..b1b9a25e6c7 100644 --- a/chromium/media/renderers/decrypting_renderer.h +++ b/chromium/media/renderers/decrypting_renderer.h @@ -38,6 +38,10 @@ class MEDIA_EXPORT DecryptingRenderer : public Renderer { std::unique_ptr<Renderer> renderer, MediaLog* media_log, const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner); + + DecryptingRenderer(const DecryptingRenderer&) = delete; + DecryptingRenderer& operator=(const DecryptingRenderer&) = delete; + ~DecryptingRenderer() override; // Renderer implementation: @@ -88,8 +92,6 @@ class MEDIA_EXPORT DecryptingRenderer : public Renderer { std::unique_ptr<DecryptingMediaResource> decrypting_media_resource_; base::WeakPtrFactory<DecryptingRenderer> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(DecryptingRenderer); }; } // namespace media diff --git a/chromium/media/renderers/decrypting_renderer_factory.h b/chromium/media/renderers/decrypting_renderer_factory.h index 6b0e12cd578..cc8cd013b16 100644 --- a/chromium/media/renderers/decrypting_renderer_factory.h +++ b/chromium/media/renderers/decrypting_renderer_factory.h @@ -26,6 +26,11 @@ class MEDIA_EXPORT DecryptingRendererFactory final : public RendererFactory { DecryptingRendererFactory( MediaLog* media_log, std::unique_ptr<media::RendererFactory> renderer_factory); + + DecryptingRendererFactory(const DecryptingRendererFactory&) = delete; + DecryptingRendererFactory& operator=(const DecryptingRendererFactory&) = + delete; + ~DecryptingRendererFactory() final; // RendererFactory implementation. @@ -41,8 +46,6 @@ class MEDIA_EXPORT DecryptingRendererFactory final : public RendererFactory { MediaLog* media_log_; std::unique_ptr<media::RendererFactory> renderer_factory_; - - DISALLOW_COPY_AND_ASSIGN(DecryptingRendererFactory); }; } // namespace media diff --git a/chromium/media/renderers/default_decoder_factory.h b/chromium/media/renderers/default_decoder_factory.h index 9283bd9cccc..d38d06a71a8 100644 --- a/chromium/media/renderers/default_decoder_factory.h +++ b/chromium/media/renderers/default_decoder_factory.h @@ -19,6 +19,10 @@ class MEDIA_EXPORT DefaultDecoderFactory final : public DecoderFactory { // additional decoders. explicit DefaultDecoderFactory( std::unique_ptr<DecoderFactory> external_decoder_factory); + + DefaultDecoderFactory(const DefaultDecoderFactory&) = delete; + DefaultDecoderFactory& operator=(const DefaultDecoderFactory&) = delete; + ~DefaultDecoderFactory() final; void CreateAudioDecoders( @@ -46,8 +50,6 @@ class MEDIA_EXPORT DefaultDecoderFactory final : public DecoderFactory { std::unique_ptr<DecoderFactory> external_decoder_factory_ GUARDED_BY(shutdown_lock_); - - DISALLOW_COPY_AND_ASSIGN(DefaultDecoderFactory); }; } // namespace media diff --git a/chromium/media/renderers/default_renderer_factory.h b/chromium/media/renderers/default_renderer_factory.h index b6486df45d3..4446df21bcb 100644 --- a/chromium/media/renderers/default_renderer_factory.h +++ b/chromium/media/renderers/default_renderer_factory.h @@ -51,6 +51,10 @@ class MEDIA_EXPORT DefaultRendererFactory final : public RendererFactory { const GetGpuFactoriesCB& get_gpu_factories_cb, std::unique_ptr<SpeechRecognitionClient> speech_recognition_client); #endif + + DefaultRendererFactory(const DefaultRendererFactory&) = delete; + DefaultRendererFactory& operator=(const DefaultRendererFactory&) = delete; + ~DefaultRendererFactory() final; std::unique_ptr<Renderer> CreateRenderer( @@ -82,8 +86,6 @@ class MEDIA_EXPORT DefaultRendererFactory final : public RendererFactory { #if !defined(OS_ANDROID) std::unique_ptr<SpeechRecognitionClient> speech_recognition_client_; #endif - - DISALLOW_COPY_AND_ASSIGN(DefaultRendererFactory); }; } // namespace media diff --git a/chromium/media/renderers/paint_canvas_video_renderer.cc b/chromium/media/renderers/paint_canvas_video_renderer.cc index 8b6339f26a9..9a84134c8ee 100644 --- a/chromium/media/renderers/paint_canvas_video_renderer.cc +++ b/chromium/media/renderers/paint_canvas_video_renderer.cc @@ -43,7 +43,7 @@ #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" #include "ui/gfx/geometry/rect_f.h" -#include "ui/gfx/skia_util.h" +#include "ui/gfx/geometry/skia_conversions.h" // Skia internal format depends on a platform. On Android it is ABGR, on others // it's ARGB. YUV_MATRIX(), YUV_ORDER() conditionally remap YUV to YVU for ABGR. @@ -568,7 +568,8 @@ class VideoImageGenerator : public cc::PaintImageGenerator { VideoImageGenerator(scoped_refptr<VideoFrame> frame) : cc::PaintImageGenerator( SkImageInfo::MakeN32Premul(frame->visible_rect().width(), - frame->visible_rect().height())), + frame->visible_rect().height(), + frame->ColorSpace().ToSkColorSpace())), frame_(std::move(frame)) { DCHECK(!frame_->HasTextures()); } @@ -587,6 +588,13 @@ class VideoImageGenerator : public cc::PaintImageGenerator { // If skia couldn't do the YUV conversion on GPU, we will on CPU. PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(frame_.get(), pixels, row_bytes); + + if (!SkColorSpace::Equals(GetSkImageInfo().colorSpace(), + info.colorSpace())) { + SkPixmap src(GetSkImageInfo(), pixels, row_bytes); + if (!src.readPixels(info, pixels, row_bytes)) + return false; + } return true; } @@ -775,11 +783,10 @@ class VideoTextureBacking : public cc::TextureBacking { }; PaintCanvasVideoRenderer::PaintCanvasVideoRenderer() - : cache_deleting_timer_( - FROM_HERE, - base::TimeDelta::FromSeconds(kTemporaryResourceDeletionDelay), - this, - &PaintCanvasVideoRenderer::ResetCache), + : cache_deleting_timer_(FROM_HERE, + base::Seconds(kTemporaryResourceDeletionDelay), + this, + &PaintCanvasVideoRenderer::ResetCache), renderer_stable_id_(cc::PaintImage::GetNextId()) {} PaintCanvasVideoRenderer::~PaintCanvasVideoRenderer() = default; @@ -1405,13 +1412,16 @@ bool PaintCanvasVideoRenderer::UploadVideoFrameToGLTexture( return true; } +// static bool PaintCanvasVideoRenderer::PrepareVideoFrameForWebGL( viz::RasterContextProvider* raster_context_provider, gpu::gles2::GLES2Interface* destination_gl, scoped_refptr<VideoFrame> video_frame, unsigned int target, unsigned int texture) { - DCHECK(thread_checker_.CalledOnValidThread()); + // TODO(776222): This static function uses no common functionality in + // PaintCanvasVideoRenderer, and should be removed from this class. + DCHECK(video_frame); DCHECK(video_frame->HasTextures()); if (video_frame->NumTextures() == 1) { @@ -1449,9 +1459,15 @@ bool PaintCanvasVideoRenderer::PrepareVideoFrameForWebGL( destination_gl->GenUnverifiedSyncTokenCHROMIUM( mailbox_holder.sync_token.GetData()); - if (!PrepareVideoFrame(video_frame, raster_context_provider, - mailbox_holder)) { - return false; + // Generate a new image. + if (video_frame->HasTextures()) { + if (video_frame->NumTextures() > 1) { + VideoFrameYUVConverter::ConvertYUVVideoFrameNoCaching( + video_frame.get(), raster_context_provider, mailbox_holder); + } else { + // We don't support Android now. + return false; + } } // Wait for mailbox creation on canvas context before consuming it and @@ -1465,7 +1481,6 @@ bool PaintCanvasVideoRenderer::PrepareVideoFrameForWebGL( WaitAndReplaceSyncTokenClient client(source_ri); video_frame->UpdateReleaseSyncToken(&client); - DCHECK(!CacheBackingWrapsTexture()); return true; } @@ -1833,27 +1848,6 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( return true; } -bool PaintCanvasVideoRenderer::PrepareVideoFrame( - scoped_refptr<VideoFrame> video_frame, - viz::RasterContextProvider* raster_context_provider, - const gpu::MailboxHolder& dest_holder) { - // Generate a new image. - // Note: Skia will hold onto |video_frame| via |video_generator| only when - // |video_frame| is software. - // Holding |video_frame| longer than this call when using GPUVideoDecoder - // could cause problems since the pool of VideoFrames has a fixed size. - if (video_frame->HasTextures()) { - if (video_frame->NumTextures() > 1) { - VideoFrameYUVConverter::ConvertYUVVideoFrameNoCaching( - video_frame.get(), raster_context_provider, dest_holder); - } else { - // We don't support Android now. - return false; - } - } - return true; -} - PaintCanvasVideoRenderer::YUVTextureCache::YUVTextureCache() = default; PaintCanvasVideoRenderer::YUVTextureCache::~YUVTextureCache() { Reset(); diff --git a/chromium/media/renderers/paint_canvas_video_renderer.h b/chromium/media/renderers/paint_canvas_video_renderer.h index 81a43500daf..f8e668e9cec 100644 --- a/chromium/media/renderers/paint_canvas_video_renderer.h +++ b/chromium/media/renderers/paint_canvas_video_renderer.h @@ -46,6 +46,10 @@ class VideoTextureBacking; class MEDIA_EXPORT PaintCanvasVideoRenderer { public: PaintCanvasVideoRenderer(); + + PaintCanvasVideoRenderer(const PaintCanvasVideoRenderer&) = delete; + PaintCanvasVideoRenderer& operator=(const PaintCanvasVideoRenderer&) = delete; + ~PaintCanvasVideoRenderer(); // Paints |video_frame| translated and scaled to |dest_rect| on |canvas|. @@ -103,7 +107,8 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer { bool premultiply_alpha, bool flip_y); - bool PrepareVideoFrameForWebGL( + // TODO(776222): Remove this function from PaintCanvasVideoRenderer. + static bool PrepareVideoFrameForWebGL( viz::RasterContextProvider* raster_context_provider, gpu::gles2::GLES2Interface* gl, scoped_refptr<VideoFrame> video_frame, @@ -277,8 +282,6 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer { gpu::SyncToken sync_token; }; YUVTextureCache yuv_cache_; - - DISALLOW_COPY_AND_ASSIGN(PaintCanvasVideoRenderer); }; } // namespace media diff --git a/chromium/media/renderers/paint_canvas_video_renderer_unittest.cc b/chromium/media/renderers/paint_canvas_video_renderer_unittest.cc index 727fad0ffdd..ebd8b5cb7aa 100644 --- a/chromium/media/renderers/paint_canvas_video_renderer_unittest.cc +++ b/chromium/media/renderers/paint_canvas_video_renderer_unittest.cc @@ -110,6 +110,11 @@ class PaintCanvasVideoRendererTest : public testing::Test { }; PaintCanvasVideoRendererTest(); + + PaintCanvasVideoRendererTest(const PaintCanvasVideoRendererTest&) = delete; + PaintCanvasVideoRendererTest& operator=(const PaintCanvasVideoRendererTest&) = + delete; + ~PaintCanvasVideoRendererTest() override; // Paints to |canvas| using |renderer_| without any frame data. @@ -150,8 +155,6 @@ class PaintCanvasVideoRendererTest : public testing::Test { SkBitmap bitmap_; cc::SkiaPaintCanvas target_canvas_; base::test::TaskEnvironment task_environment_; - - DISALLOW_COPY_AND_ASSIGN(PaintCanvasVideoRendererTest); }; static SkBitmap AllocBitmap(int width, int height) { @@ -164,7 +167,7 @@ static SkBitmap AllocBitmap(int width, int height) { static scoped_refptr<VideoFrame> CreateCroppedFrame() { scoped_refptr<VideoFrame> cropped_frame = VideoFrame::CreateFrame( PIXEL_FORMAT_I420, gfx::Size(16, 16), gfx::Rect(6, 6, 8, 6), - gfx::Size(8, 6), base::TimeDelta::FromMilliseconds(4)); + gfx::Size(8, 6), base::Milliseconds(4)); // Make sure the cropped video frame's aspect ratio matches the output device. // Update cropped_frame_'s crop dimensions if this is not the case. EXPECT_EQ(cropped_frame->visible_rect().width() * kHeight, @@ -256,9 +259,9 @@ PaintCanvasVideoRendererTest::PaintCanvasVideoRendererTest() bitmap_(AllocBitmap(kWidth, kHeight)), target_canvas_(bitmap_) { // Give each frame a unique timestamp. - natural_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(1)); - larger_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(2)); - smaller_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(3)); + natural_frame_->set_timestamp(base::Milliseconds(1)); + larger_frame_->set_timestamp(base::Milliseconds(2)); + smaller_frame_->set_timestamp(base::Milliseconds(3)); } PaintCanvasVideoRendererTest::~PaintCanvasVideoRendererTest() = default; @@ -682,20 +685,20 @@ TEST_F(PaintCanvasVideoRendererTest, Y16) { TEST_F(PaintCanvasVideoRendererTest, Yuv420P12OddWidth) { // Allocate the Y, U, V planes for a 3x3 12-bit YUV 4:2:0 image. Note that // there are no padding bytes after each row. - constexpr int kWidth = 3; - constexpr int kHeight = 3; - constexpr int kUvWidth = (kWidth + 1) / 2; - constexpr int kUvHeight = (kHeight + 1) / 2; + constexpr int kImgWidth = 3; + constexpr int kImgHeight = 3; + constexpr int kUvWidth = (kImgWidth + 1) / 2; + constexpr int kUvHeight = (kImgHeight + 1) / 2; std::unique_ptr<uint16_t[]> y_plane = - std::make_unique<uint16_t[]>(kWidth * kHeight); + std::make_unique<uint16_t[]>(kImgWidth * kImgHeight); std::unique_ptr<uint16_t[]> u_plane = std::make_unique<uint16_t[]>(kUvWidth * kUvHeight); std::unique_ptr<uint16_t[]> v_plane = std::make_unique<uint16_t[]>(kUvWidth * kUvHeight); // Set all pixels to white. - for (int i = 0; i < kHeight; ++i) { - for (int j = 0; j < kWidth; ++j) { - y_plane[i * kWidth + j] = 4095; + for (int i = 0; i < kImgHeight; ++i) { + for (int j = 0; j < kImgWidth; ++j) { + y_plane[i * kImgWidth + j] = 4095; } } for (int i = 0; i < kUvHeight; ++i) { @@ -704,25 +707,25 @@ TEST_F(PaintCanvasVideoRendererTest, Yuv420P12OddWidth) { v_plane[i * kUvWidth + j] = 2048; } } - const int32_t y_stride = sizeof(uint16_t) * kWidth; + const int32_t y_stride = sizeof(uint16_t) * kImgWidth; const int32_t uv_stride = sizeof(uint16_t) * kUvWidth; uint8_t* const y_data = reinterpret_cast<uint8_t*>(y_plane.get()); uint8_t* const u_data = reinterpret_cast<uint8_t*>(u_plane.get()); uint8_t* const v_data = reinterpret_cast<uint8_t*>(v_plane.get()); - auto size = gfx::Size(kWidth, kHeight); + auto size = gfx::Size(kImgWidth, kImgHeight); scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalYuvData( PIXEL_FORMAT_YUV420P12, size, gfx::Rect(size), size, y_stride, uv_stride, uv_stride, y_data, u_data, v_data, base::TimeDelta()); std::unique_ptr<uint32_t[]> rgba = - std::make_unique<uint32_t[]>(kWidth * kHeight); + std::make_unique<uint32_t[]>(kImgWidth * kImgHeight); PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( frame.get(), rgba.get(), frame->visible_rect().width() * 4, /*premultiply_alpha=*/true); - for (int i = 0; i < kHeight; ++i) { - for (int j = 0; j < kWidth; ++j) { - EXPECT_EQ(rgba[i * kWidth + j], 0xffffffff); + for (int i = 0; i < kImgHeight; ++i) { + for (int j = 0; j < kImgWidth; ++j) { + EXPECT_EQ(rgba[i * kImgWidth + j], 0xffffffff); } } } @@ -829,8 +832,7 @@ TEST_F(PaintCanvasVideoRendererTest, CorrectFrameSizeToVisibleRect) { auto video_frame = media::VideoFrame::WrapExternalData( media::PIXEL_FORMAT_Y16, coded_size, gfx::Rect(visible_size), - visible_size, &memory[0], fWidth * fHeight * 2, - base::TimeDelta::FromMilliseconds(4)); + visible_size, &memory[0], fWidth * fHeight * 2, base::Milliseconds(4)); gfx::RectF visible_rect(visible_size.width(), visible_size.height()); cc::PaintFlags flags; @@ -944,21 +946,23 @@ class PaintCanvasVideoRendererWithGLTest : public testing::TestWithParam<bool> { gl::GLSurfaceTestSupport::InitializeOneOff(); enable_pixels_.emplace(); media_context_ = base::MakeRefCounted<viz::TestInProcessContextProvider>( - /*enable_gpu_rasterization=*/false, - /*enable_oop_rasterization=*/GetParam(), /*support_locking=*/false); + /*enable_gles2_interface=*/false, + /*support_locking=*/false, + GetParam() ? viz::RasterInterfaceType::OOPR + : viz::RasterInterfaceType::GPU); gpu::ContextResult result = media_context_->BindToCurrentThread(); ASSERT_EQ(result, gpu::ContextResult::kSuccess); gles2_context_ = base::MakeRefCounted<viz::TestInProcessContextProvider>( - /*enable_gpu_rasterization=*/false, - /*enable_oop_rasterization=*/false, /*support_locking=*/false); + /*enable_gles2_interface=*/true, /*support_locking=*/false, + viz::RasterInterfaceType::None); result = gles2_context_->BindToCurrentThread(); ASSERT_EQ(result, gpu::ContextResult::kSuccess); destination_context_ = base::MakeRefCounted<viz::TestInProcessContextProvider>( - /*enable_gpu_rasterization=*/false, - /*enable_oop_rasterization=*/false, /*support_locking=*/false); + /*enable_gles2_interface=*/true, /*support_locking=*/false, + viz::RasterInterfaceType::None); result = destination_context_->BindToCurrentThread(); ASSERT_EQ(result, gpu::ContextResult::kSuccess); cropped_frame_ = CreateCroppedFrame(); diff --git a/chromium/media/renderers/renderer_impl.h b/chromium/media/renderers/renderer_impl.h index 69abeb247da..e48a4b3f066 100644 --- a/chromium/media/renderers/renderer_impl.h +++ b/chromium/media/renderers/renderer_impl.h @@ -51,6 +51,9 @@ class MEDIA_EXPORT RendererImpl final : public Renderer { std::unique_ptr<AudioRenderer> audio_renderer, std::unique_ptr<VideoRenderer> video_renderer); + RendererImpl(const RendererImpl&) = delete; + RendererImpl& operator=(const RendererImpl&) = delete; + ~RendererImpl() final; // Renderer implementation. @@ -256,9 +259,8 @@ class MEDIA_EXPORT RendererImpl final : public Renderer { // The amount of time to wait before declaring underflow if the video renderer // runs out of data but the audio renderer still has enough. Tuneable<base::TimeDelta> video_underflow_threshold_ = { - "MediaVideoUnderflowThreshold", base::TimeDelta::FromMilliseconds(1000), - base::TimeDelta::FromMilliseconds(3000), - base::TimeDelta::FromMilliseconds(8000)}; + "MediaVideoUnderflowThreshold", base::Milliseconds(1000), + base::Milliseconds(3000), base::Milliseconds(8000)}; // Lock used to protect access to the |restarting_audio_| flag and // |restarting_audio_time_|. @@ -272,8 +274,6 @@ class MEDIA_EXPORT RendererImpl final : public Renderer { base::WeakPtr<RendererImpl> weak_this_; base::WeakPtrFactory<RendererImpl> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(RendererImpl); }; } // namespace media diff --git a/chromium/media/renderers/renderer_impl_unittest.cc b/chromium/media/renderers/renderer_impl_unittest.cc index a7e80c0ca91..7d16cc84b1c 100644 --- a/chromium/media/renderers/renderer_impl_unittest.cc +++ b/chromium/media/renderers/renderer_impl_unittest.cc @@ -66,6 +66,10 @@ class RendererImplTest : public ::testing::Test { class CallbackHelper : public MockRendererClient { public: CallbackHelper() = default; + + CallbackHelper(const CallbackHelper&) = delete; + CallbackHelper& operator=(const CallbackHelper&) = delete; + virtual ~CallbackHelper() = default; // Completion callbacks. @@ -75,9 +79,6 @@ class RendererImplTest : public ::testing::Test { MOCK_METHOD1(OnDurationChange, void(base::TimeDelta duration)); MOCK_METHOD0(OnVideoTrackChangeComplete, void()); MOCK_METHOD0(OnAudioTrackChangeComplete, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(CallbackHelper); }; RendererImplTest() @@ -97,6 +98,9 @@ class RendererImplTest : public ::testing::Test { EXPECT_CALL(*demuxer_, GetAllStreams()).WillRepeatedly(Return(streams_)); } + RendererImplTest(const RendererImplTest&) = delete; + RendererImplTest& operator=(const RendererImplTest&) = delete; + ~RendererImplTest() override { Destroy(); } protected: @@ -244,8 +248,7 @@ class RendererImplTest : public ::testing::Test { OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, BUFFERING_CHANGE_REASON_UNKNOWN)); - base::TimeDelta start_time( - base::TimeDelta::FromMilliseconds(kStartPlayingTimeInMs)); + base::TimeDelta start_time(base::Milliseconds(kStartPlayingTimeInMs)); EXPECT_CALL(time_source_, SetMediaTime(start_time)); EXPECT_CALL(time_source_, StartTicking()); @@ -295,8 +298,7 @@ class RendererImplTest : public ::testing::Test { int64_t start_time_ms = GetMediaTimeMs(); const int64_t time_to_advance_ms = 100; - test_tick_clock_.Advance( - base::TimeDelta::FromMilliseconds(time_to_advance_ms)); + test_tick_clock_.Advance(base::Milliseconds(time_to_advance_ms)); if (GetMediaTimeMs() == start_time_ms + time_to_advance_ms * playback_rate) return true; @@ -374,9 +376,6 @@ class RendererImplTest : public ::testing::Test { PipelineStatus initialization_status_; bool is_encrypted_ = false; bool is_cdm_set_ = false; - - private: - DISALLOW_COPY_AND_ASSIGN(RendererImplTest); }; TEST_F(RendererImplTest, Destroy_BeforeInitialize) { @@ -815,8 +814,7 @@ TEST_F(RendererImplTest, VideoUnderflowWithAudioFlush) { Play(); // Set a massive threshold such that it shouldn't fire within this test. - renderer_impl_->set_video_underflow_threshold_for_testing( - base::TimeDelta::FromSeconds(100)); + renderer_impl_->set_video_underflow_threshold_for_testing(base::Seconds(100)); // Simulate the cases where audio underflows and then video underflows. EXPECT_CALL(time_source_, StopTicking()); diff --git a/chromium/media/renderers/shared_image_video_frame_test_utils.cc b/chromium/media/renderers/shared_image_video_frame_test_utils.cc index 9b36170d6c1..9431cae4e27 100644 --- a/chromium/media/renderers/shared_image_video_frame_test_utils.cc +++ b/chromium/media/renderers/shared_image_video_frame_test_utils.cc @@ -122,8 +122,7 @@ scoped_refptr<VideoFrame> CreateSharedImageRGBAFrame( return CreateSharedImageFrame( std::move(context_provider), VideoPixelFormat::PIXEL_FORMAT_ABGR, {mailbox}, sync_token, GL_TEXTURE_2D, coded_size, visible_rect, - visible_rect.size(), base::TimeDelta::FromSeconds(1), - std::move(destroyed_callback)); + visible_rect.size(), base::Seconds(1), std::move(destroyed_callback)); } scoped_refptr<VideoFrame> CreateSharedImageI420Frame( @@ -186,7 +185,7 @@ scoped_refptr<VideoFrame> CreateSharedImageI420Frame( return CreateSharedImageFrame( std::move(context_provider), VideoPixelFormat::PIXEL_FORMAT_I420, {y_mailbox, u_mailbox, v_mailbox}, sync_token, GL_TEXTURE_2D, coded_size, - visible_rect, visible_rect.size(), base::TimeDelta::FromSeconds(1), + visible_rect, visible_rect.size(), base::Seconds(1), std::move(destroyed_callback)); } @@ -247,7 +246,7 @@ scoped_refptr<VideoFrame> CreateSharedImageNV12Frame( return CreateSharedImageFrame( std::move(context_provider), VideoPixelFormat::PIXEL_FORMAT_NV12, {y_mailbox, uv_mailbox}, sync_token, GL_TEXTURE_2D, coded_size, - visible_rect, visible_rect.size(), base::TimeDelta::FromSeconds(1), + visible_rect, visible_rect.size(), base::Seconds(1), std::move(destroyed_callback)); } diff --git a/chromium/media/renderers/video_frame_rgba_to_yuva_converter.cc b/chromium/media/renderers/video_frame_rgba_to_yuva_converter.cc index 0d94aa8500e..58e588933f4 100644 --- a/chromium/media/renderers/video_frame_rgba_to_yuva_converter.cc +++ b/chromium/media/renderers/video_frame_rgba_to_yuva_converter.cc @@ -5,9 +5,11 @@ #include "media/renderers/video_frame_rgba_to_yuva_converter.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "components/viz/common/gpu/raster_context_provider.h" #include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/client/raster_interface.h" +#include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "media/base/simple_sync_token_client.h" #include "media/base/wait_and_replace_sync_token_client.h" @@ -16,6 +18,7 @@ #include "skia/ext/rgba_to_yuva.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace { @@ -71,7 +74,7 @@ class ScopedAcceleratedSkImage { return nullptr; } - return absl::WrapUnique<ScopedAcceleratedSkImage>( + return base::WrapUnique<ScopedAcceleratedSkImage>( new ScopedAcceleratedSkImage(provider, texture_id, std::move(sk_image))); } @@ -119,50 +122,86 @@ bool CopyRGBATextureToVideoFrame(viz::RasterContextProvider* provider, auto* ri = provider->RasterInterface(); DCHECK(ri); - // Create an accelerated SkImage for the source. - auto scoped_sk_image = ScopedAcceleratedSkImage::Create( - provider, src_format, src_size, src_color_space, src_surface_origin, - src_mailbox_holder); - if (!scoped_sk_image) { - DLOG(ERROR) - << "Failed to create accelerated SkImage for RGBA to YUVA conversion."; - return false; - } + if (!provider->GrContext()) { + SkYUVAInfo yuva_info = + VideoFrameYUVMailboxesHolder::VideoFrameGetSkYUVAInfo(dst_video_frame); + gpu::Mailbox yuva_mailboxes[SkYUVAInfo::kMaxPlanes]; + ri->WaitSyncTokenCHROMIUM(src_mailbox_holder.sync_token.GetConstData()); + for (int plane = 0; plane < yuva_info.numPlanes(); ++plane) { + gpu::MailboxHolder dst_mailbox_holder = + dst_video_frame->mailbox_holder(plane); + ri->WaitSyncTokenCHROMIUM(dst_mailbox_holder.sync_token.GetConstData()); + yuva_mailboxes[plane] = dst_mailbox_holder.mailbox; + } + ri->ConvertRGBAToYUVAMailboxes( + yuva_info.yuvColorSpace(), yuva_info.planeConfig(), + yuva_info.subsampling(), yuva_mailboxes, src_mailbox_holder.mailbox); + } else { + // Create an accelerated SkImage for the source. + auto scoped_sk_image = ScopedAcceleratedSkImage::Create( + provider, src_format, src_size, src_color_space, src_surface_origin, + src_mailbox_holder); + if (!scoped_sk_image) { + DLOG(ERROR) << "Failed to create accelerated SkImage for RGBA to YUVA " + "conversion."; + return false; + } - // Create SkSurfaces for the destination planes. - sk_sp<SkSurface> sk_surfaces[SkYUVAInfo::kMaxPlanes]; - VideoFrameYUVMailboxesHolder holder; - if (!holder.VideoFrameToPlaneSkSurfaces(dst_video_frame, provider, - sk_surfaces)) { - DLOG(ERROR) << "Failed to create SkSurfaces for VideoFrame."; - return false; - } + // Create SkSurfaces for the destination planes. + sk_sp<SkSurface> sk_surfaces[SkYUVAInfo::kMaxPlanes]; + SkSurface* sk_surface_ptrs[SkYUVAInfo::kMaxPlanes] = {nullptr}; + VideoFrameYUVMailboxesHolder holder; + if (!holder.VideoFrameToPlaneSkSurfaces(dst_video_frame, provider, + sk_surfaces)) { + DLOG(ERROR) << "Failed to create SkSurfaces for VideoFrame."; + return false; + } - // Make GrContext wait for `dst_video_frame`. Waiting on the mailbox tokens - // here ensures that all writes are completed in cases where the underlying - // GpuMemoryBuffer and SharedImage resources have been reused. - ri->Flush(); - WaitAndReplaceSyncTokenClient client(ri); - for (size_t plane = 0; plane < 2; ++plane) - dst_video_frame->UpdateMailboxHolderSyncToken(plane, &client); - - // Do the blit. - skia::BlitRGBAToYUVA( - scoped_sk_image->sk_image(), - SkRect::MakeWH(src_size.width(), src_size.height()), sk_surfaces, - holder.yuva_info(), - SkRect::MakeWH(holder.yuva_info().width(), holder.yuva_info().height())); - provider->GrContext()->flushAndSubmit(false); + // Make GrContext wait for `dst_video_frame`. Waiting on the mailbox tokens + // here ensures that all writes are completed in cases where the underlying + // GpuMemoryBuffer and SharedImage resources have been reused. + ri->Flush(); + WaitAndReplaceSyncTokenClient client(ri); + for (int plane = 0; plane < holder.yuva_info().numPlanes(); ++plane) { + sk_surface_ptrs[plane] = sk_surfaces[plane].get(); + dst_video_frame->UpdateMailboxHolderSyncToken(plane, &client); + } + + // Do the blit. + skia::BlitRGBAToYUVA(scoped_sk_image->sk_image().get(), sk_surface_ptrs, + holder.yuva_info()); + provider->GrContext()->flushAndSubmit(false); + } ri->Flush(); - // Set `completion_sync_token` to mark the completion of the copy. - ri->GenSyncTokenCHROMIUM(completion_sync_token.GetData()); + const size_t num_planes = dst_video_frame->layout().num_planes(); + + // For shared memory GMBs on Windows we needed to explicitly request a copy + // from the shared image GPU texture to the GMB. Set `completion_sync_token` + // to mark the completion of the copy. + if (dst_video_frame->HasGpuMemoryBuffer() && + dst_video_frame->GetGpuMemoryBuffer()->GetType() == + gfx::SHARED_MEMORY_BUFFER) { + auto* sii = provider->SharedImageInterface(); + + gpu::SyncToken blit_done_sync_token; + ri->GenUnverifiedSyncTokenCHROMIUM(blit_done_sync_token.GetData()); + + for (size_t plane = 0; plane < num_planes; ++plane) { + const auto& mailbox = dst_video_frame->mailbox_holder(plane).mailbox; + sii->CopyToGpuMemoryBuffer(blit_done_sync_token, mailbox); + } + + completion_sync_token = sii->GenVerifiedSyncToken(); + } else { + ri->GenSyncTokenCHROMIUM(completion_sync_token.GetData()); + } // Make access to the `dst_video_frame` wait on copy completion. We also // update the ReleaseSyncToken here since it's used when the underlying // GpuMemoryBuffer and SharedImage resources are returned to the pool. SimpleSyncTokenClient simple_client(completion_sync_token); - for (size_t plane = 0; plane < 2; ++plane) + for (size_t plane = 0; plane < num_planes; ++plane) dst_video_frame->UpdateMailboxHolderSyncToken(plane, &simple_client); dst_video_frame->UpdateReleaseSyncToken(&simple_client); return true; diff --git a/chromium/media/renderers/video_overlay_factory.h b/chromium/media/renderers/video_overlay_factory.h index e11ee06557a..14eaf7e7e2b 100644 --- a/chromium/media/renderers/video_overlay_factory.h +++ b/chromium/media/renderers/video_overlay_factory.h @@ -23,6 +23,10 @@ class VideoFrame; class MEDIA_EXPORT VideoOverlayFactory { public: VideoOverlayFactory(); + + VideoOverlayFactory(const VideoOverlayFactory&) = delete; + VideoOverlayFactory& operator=(const VideoOverlayFactory&) = delete; + ~VideoOverlayFactory(); scoped_refptr<::media::VideoFrame> CreateFrame(const gfx::Size& size); @@ -33,8 +37,6 @@ class MEDIA_EXPORT VideoOverlayFactory { private: // |overlay_plane_id_| identifies the instances of VideoOverlayFactory. const base::UnguessableToken overlay_plane_id_; - - DISALLOW_COPY_AND_ASSIGN(VideoOverlayFactory); }; } // namespace media diff --git a/chromium/media/renderers/video_renderer_impl.cc b/chromium/media/renderers/video_renderer_impl.cc index ad1e16b2870..7186f6c2f4e 100644 --- a/chromium/media/renderers/video_renderer_impl.cc +++ b/chromium/media/renderers/video_renderer_impl.cc @@ -657,8 +657,7 @@ void VideoRendererImpl::FrameReady(VideoDecoderStream::ReadResult result) { // Update average frame duration. base::TimeDelta frame_duration = algorithm_->average_frame_duration(); - if (frame_duration != kNoTimestamp && - frame_duration != base::TimeDelta::FromSeconds(0)) { + if (frame_duration != kNoTimestamp && frame_duration != base::Seconds(0)) { fps_estimator_.AddSample(frame_duration); } else { fps_estimator_.Reset(); diff --git a/chromium/media/renderers/video_renderer_impl.h b/chromium/media/renderers/video_renderer_impl.h index 00c4d08743f..c275ddd183e 100644 --- a/chromium/media/renderers/video_renderer_impl.h +++ b/chromium/media/renderers/video_renderer_impl.h @@ -61,6 +61,10 @@ class MEDIA_EXPORT VideoRendererImpl bool drop_frames, MediaLog* media_log, std::unique_ptr<GpuMemoryBufferVideoFramePool> gmb_pool); + + VideoRendererImpl(const VideoRendererImpl&) = delete; + VideoRendererImpl& operator=(const VideoRendererImpl&) = delete; + ~VideoRendererImpl() override; // VideoRenderer implementation. @@ -357,8 +361,6 @@ class MEDIA_EXPORT VideoRendererImpl // want to discard video frames that might be received after the stream has // been reset. base::WeakPtrFactory<VideoRendererImpl> cancel_on_flush_weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(VideoRendererImpl); }; } // namespace media diff --git a/chromium/media/renderers/video_renderer_impl_unittest.cc b/chromium/media/renderers/video_renderer_impl_unittest.cc index 9cebbf8bd98..9afe17711c6 100644 --- a/chromium/media/renderers/video_renderer_impl_unittest.cc +++ b/chromium/media/renderers/video_renderer_impl_unittest.cc @@ -86,7 +86,7 @@ class VideoRendererImplTest : public testing::Test { simulate_decode_delay_(false), expect_init_success_(true) { null_video_sink_ = std::make_unique<NullVideoSink>( - false, base::TimeDelta::FromSecondsD(1.0 / 60), + false, base::Seconds(1.0 / 60), base::BindRepeating(&MockCB::FrameReceived, base::Unretained(&mock_cb_)), base::ThreadTaskRunnerHandle::Get()); @@ -111,6 +111,9 @@ class VideoRendererImplTest : public testing::Test { .WillByDefault(Invoke(this, &VideoRendererImplTest::OnDemuxerRead)); } + VideoRendererImplTest(const VideoRendererImplTest&) = delete; + VideoRendererImplTest& operator=(const VideoRendererImplTest&) = delete; + ~VideoRendererImplTest() override = default; void Initialize() { @@ -152,8 +155,7 @@ class VideoRendererImplTest : public testing::Test { void StartPlayingFrom(int milliseconds) { SCOPED_TRACE(base::StringPrintf("StartPlayingFrom(%d)", milliseconds)); - const base::TimeDelta media_time = - base::TimeDelta::FromMilliseconds(milliseconds); + const base::TimeDelta media_time = base::Milliseconds(milliseconds); time_source_.SetMediaTime(media_time); renderer_->StartPlayingFrom(media_time); base::RunLoop().RunUntilIdle(); @@ -233,7 +235,7 @@ class VideoRendererImplTest : public testing::Test { gfx::Size natural_size = TestVideoConfig::NormalCodedSize(); scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( PIXEL_FORMAT_I420, natural_size, gfx::Rect(natural_size), - natural_size, base::TimeDelta::FromMilliseconds(timestamp_in_ms)); + natural_size, base::Milliseconds(timestamp_in_ms)); QueueFrame(DecodeStatus::OK, frame); continue; } @@ -324,14 +326,14 @@ class VideoRendererImplTest : public testing::Test { EXPECT_TRUE( task_environment_.GetMainThreadTaskRunner()->BelongsToCurrentThread()); base::AutoLock l(lock_); - tick_clock_.Advance(base::TimeDelta::FromMilliseconds(time_ms)); + tick_clock_.Advance(base::Milliseconds(time_ms)); } void AdvanceTimeInMs(int time_ms) { EXPECT_TRUE( task_environment_.GetMainThreadTaskRunner()->BelongsToCurrentThread()); base::AutoLock l(lock_); - time_ += base::TimeDelta::FromMilliseconds(time_ms); + time_ += base::Milliseconds(time_ms); time_source_.StopTicking(); time_source_.SetMediaTime(time_); time_source_.StartTicking(); @@ -419,8 +421,6 @@ class VideoRendererImplTest : public testing::Test { base::circular_deque<std::pair<DecodeStatus, scoped_refptr<VideoFrame>>> decode_results_; - - DISALLOW_COPY_AND_ASSIGN(VideoRendererImplTest); }; TEST_F(VideoRendererImplTest, DoNothing) { @@ -559,7 +559,7 @@ static void VideoRendererImplTest_FlushDoneCB(VideoRendererImplTest* test, VideoRenderer* renderer, base::OnceClosure success_cb) { test->QueueFrames("0 10 20 30"); - renderer->StartPlayingFrom(base::TimeDelta::FromSeconds(0)); + renderer->StartPlayingFrom(base::Seconds(0)); std::move(success_cb).Run(); } @@ -1018,19 +1018,19 @@ TEST_F(VideoRendererImplTest, NaturalSizeChange) { QueueFrame(DecodeStatus::OK, VideoFrame::CreateFrame(PIXEL_FORMAT_I420, initial_size, gfx::Rect(initial_size), initial_size, - base::TimeDelta::FromMilliseconds(0))); + base::Milliseconds(0))); QueueFrame(DecodeStatus::OK, VideoFrame::CreateFrame(PIXEL_FORMAT_I420, larger_size, gfx::Rect(larger_size), larger_size, - base::TimeDelta::FromMilliseconds(10))); + base::Milliseconds(10))); QueueFrame(DecodeStatus::OK, VideoFrame::CreateFrame(PIXEL_FORMAT_I420, larger_size, gfx::Rect(larger_size), larger_size, - base::TimeDelta::FromMilliseconds(20))); + base::Milliseconds(20))); QueueFrame(DecodeStatus::OK, VideoFrame::CreateFrame(PIXEL_FORMAT_I420, initial_size, gfx::Rect(initial_size), initial_size, - base::TimeDelta::FromMilliseconds(30))); + base::Milliseconds(30))); EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _)); EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber()); @@ -1084,19 +1084,19 @@ TEST_F(VideoRendererImplTest, OpacityChange) { QueueFrame(DecodeStatus::OK, VideoFrame::CreateFrame(non_opaque_format, frame_size, gfx::Rect(frame_size), frame_size, - base::TimeDelta::FromMilliseconds(0))); + base::Milliseconds(0))); QueueFrame(DecodeStatus::OK, VideoFrame::CreateFrame(non_opaque_format, frame_size, gfx::Rect(frame_size), frame_size, - base::TimeDelta::FromMilliseconds(10))); - QueueFrame(DecodeStatus::OK, - VideoFrame::CreateFrame(opaque_format, frame_size, - gfx::Rect(frame_size), frame_size, - base::TimeDelta::FromMilliseconds(20))); - QueueFrame(DecodeStatus::OK, - VideoFrame::CreateFrame(opaque_format, frame_size, - gfx::Rect(frame_size), frame_size, - base::TimeDelta::FromMilliseconds(30))); + base::Milliseconds(10))); + QueueFrame( + DecodeStatus::OK, + VideoFrame::CreateFrame(opaque_format, frame_size, gfx::Rect(frame_size), + frame_size, base::Milliseconds(20))); + QueueFrame( + DecodeStatus::OK, + VideoFrame::CreateFrame(opaque_format, frame_size, gfx::Rect(frame_size), + frame_size, base::Milliseconds(30))); EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _)); EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber()); @@ -1166,7 +1166,7 @@ TEST_F(VideoRendererImplTest, VideoFrameRateChange) { AdvanceTimeInMs(20); AdvanceWallclockTimeInMs(20); // This runs the sink callbacks to consume frames. - task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(20)); + task_environment_.FastForwardBy(base::Milliseconds(20)); base::RunLoop().RunUntilIdle(); } @@ -1498,10 +1498,10 @@ TEST_F(VideoRendererLatencyHintTest, HaveEnough_HighLatencyHint) { // We must provide a |buffer_duration_| for the latencyHint to take effect // immediately. The VideoRendererAlgorithm will eventually provide a PTS-delta // duration, but not until after we've started rendering. - buffer_duration_ = base::TimeDelta::FromMilliseconds(30); + buffer_duration_ = base::Milliseconds(30); // Set latencyHint to a large value. - renderer_->SetLatencyHint(base::TimeDelta::FromMilliseconds(400)); + renderer_->SetLatencyHint(base::Milliseconds(400)); // NOTE: other tests will SetLatencyHint after Initialize(). Either way should // work. Initializing later is especially interesting for "high" hints because @@ -1559,10 +1559,10 @@ TEST_F(VideoRendererLatencyHintTest, // We must provide a |buffer_duration_| for the latencyHint to take effect // immediately. The VideoRendererAlgorithm will eventually provide a PTS-delta // duration, but not until after we've started rendering. - buffer_duration_ = base::TimeDelta::FromMilliseconds(30); + buffer_duration_ = base::Milliseconds(30); // Set latency hint to a medium value. - renderer_->SetLatencyHint(base::TimeDelta::FromMilliseconds(200)); + renderer_->SetLatencyHint(base::Milliseconds(200)); // Stall the demuxer after 7 frames. simulate_demuxer_stall_after_n_reads_ = 7; @@ -1618,10 +1618,10 @@ TEST_F(VideoRendererLatencyHintTest, LatencyHintOverridesLowDelay) { // We must provide a |buffer_duration_| for the latencyHint to take effect // immediately. The VideoRendererAlgorithm will eventually provide a PTS-delta // duration, but not until after we've started rendering. - buffer_duration_ = base::TimeDelta::FromMilliseconds(30); + buffer_duration_ = base::Milliseconds(30); // Set latency hint to a medium value. - renderer_->SetLatencyHint(base::TimeDelta::FromMilliseconds(200)); + renderer_->SetLatencyHint(base::Milliseconds(200)); // Initial frames should trigger various callbacks. EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0))); @@ -1678,11 +1678,11 @@ TEST_F(VideoRendererLatencyHintTest, // We must provide a |buffer_duration_| for the latencyHint to take effect // immediately. The VideoRendererAlgorithm will eventually provide a PTS-delta // duration, but not until after we've started rendering. - buffer_duration_ = base::TimeDelta::FromMilliseconds(30); + buffer_duration_ = base::Milliseconds(30); // Set latency hint to a medium value. At a spacing of 30ms this would set // the HAVE_ENOUGH threshold to 4 frames. - renderer_->SetLatencyHint(base::TimeDelta::FromMilliseconds(200)); + renderer_->SetLatencyHint(base::Milliseconds(200)); // Initial frames should trigger various callbacks. EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0))); diff --git a/chromium/media/renderers/video_resource_updater.cc b/chromium/media/renderers/video_resource_updater.cc index 80cb1a4575d..8270054bbdf 100644 --- a/chromium/media/renderers/video_resource_updater.cc +++ b/chromium/media/renderers/video_resource_updater.cc @@ -50,7 +50,7 @@ #include "third_party/libyuv/include/libyuv.h" #include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/skia_util.h" +#include "ui/gfx/geometry/skia_conversions.h" #include "ui/gl/gl_enums.h" #include "ui/gl/trace_util.h" @@ -184,6 +184,10 @@ class SyncTokenClientImpl : public VideoFrame::SyncTokenClient { // Only one interface should be used. DCHECK((gl_ && !sii_) || (!gl_ && sii_)); } + + SyncTokenClientImpl(const SyncTokenClientImpl&) = delete; + SyncTokenClientImpl& operator=(const SyncTokenClientImpl&) = delete; + ~SyncTokenClientImpl() override = default; void GenerateSyncToken(gpu::SyncToken* sync_token) override { @@ -220,7 +224,6 @@ class SyncTokenClientImpl : public VideoFrame::SyncTokenClient { gpu::gles2::GLES2Interface* gl_; gpu::SharedImageInterface* sii_; gpu::SyncToken sync_token_; - DISALLOW_COPY_AND_ASSIGN(SyncTokenClientImpl); }; // Sync tokens passed downstream to the compositor can be unverified. @@ -265,6 +268,10 @@ class VideoResourceUpdater::PlaneResource { resource_size_(resource_size), resource_format_(resource_format), is_software_(is_software) {} + + PlaneResource(const PlaneResource&) = delete; + PlaneResource& operator=(const PlaneResource&) = delete; + virtual ~PlaneResource() = default; // Casts |this| to SoftwarePlaneResource for software compositing. @@ -316,8 +323,6 @@ class VideoResourceUpdater::PlaneResource { size_t plane_index_ = 0u; // Indicates if the above two members have been set or not. bool has_unique_frame_id_and_plane_index_ = false; - - DISALLOW_COPY_AND_ASSIGN(PlaneResource); }; class VideoResourceUpdater::SoftwarePlaneResource @@ -342,6 +347,10 @@ class VideoResourceUpdater::SoftwarePlaneResource shared_bitmap_reporter_->DidAllocateSharedBitmap(std::move(shm.region), shared_bitmap_id_); } + + SoftwarePlaneResource(const SoftwarePlaneResource&) = delete; + SoftwarePlaneResource& operator=(const SoftwarePlaneResource&) = delete; + ~SoftwarePlaneResource() override { shared_bitmap_reporter_->DidDeleteSharedBitmap(shared_bitmap_id_); } @@ -360,8 +369,6 @@ class VideoResourceUpdater::SoftwarePlaneResource viz::SharedBitmapReporter* const shared_bitmap_reporter_; const viz::SharedBitmapId shared_bitmap_id_; base::WritableSharedMemoryMapping shared_mapping_; - - DISALLOW_COPY_AND_ASSIGN(SoftwarePlaneResource); }; class VideoResourceUpdater::HardwarePlaneResource diff --git a/chromium/media/renderers/video_resource_updater.h b/chromium/media/renderers/video_resource_updater.h index d2ad861f59a..37d9297d1e7 100644 --- a/chromium/media/renderers/video_resource_updater.h +++ b/chromium/media/renderers/video_resource_updater.h @@ -101,6 +101,9 @@ class MEDIA_EXPORT VideoResourceUpdater bool use_r16_texture, int max_resource_size); + VideoResourceUpdater(const VideoResourceUpdater&) = delete; + VideoResourceUpdater& operator=(const VideoResourceUpdater&) = delete; + ~VideoResourceUpdater() override; // For each CompositorFrame the following sequence is expected: @@ -244,8 +247,6 @@ class MEDIA_EXPORT VideoResourceUpdater std::vector<std::unique_ptr<PlaneResource>> all_resources_; base::WeakPtrFactory<VideoResourceUpdater> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(VideoResourceUpdater); }; } // namespace media diff --git a/chromium/media/renderers/video_resource_updater_unittest.cc b/chromium/media/renderers/video_resource_updater_unittest.cc index 32dee8d7ec7..6e8d7c78313 100644 --- a/chromium/media/renderers/video_resource_updater_unittest.cc +++ b/chromium/media/renderers/video_resource_updater_unittest.cc @@ -383,7 +383,7 @@ TEST_F(VideoResourceUpdaterTest, WonkySoftwareFrameSoftwareCompositor) { TEST_F(VideoResourceUpdaterTest, ReuseResource) { std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware(); scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame(); - video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234)); + video_frame->set_timestamp(base::Seconds(1234)); // Allocate the resources for a YUV video frame. gl_->ResetUploadCount(); @@ -413,7 +413,7 @@ TEST_F(VideoResourceUpdaterTest, ReuseResource) { TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDelete) { std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware(); scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame(); - video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234)); + video_frame->set_timestamp(base::Seconds(1234)); // Allocate the resources for a YUV video frame. gl_->ResetUploadCount(); @@ -458,7 +458,7 @@ TEST_F(VideoResourceUpdaterTest, SoftwareFrameRGBSoftwareCompositor) { TEST_F(VideoResourceUpdaterTest, ReuseResourceSoftwareCompositor) { std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware(); scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame(); - video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234)); + video_frame->set_timestamp(base::Seconds(1234)); // Allocate the resources for a software video frame. VideoFrameExternalResources resources = @@ -487,7 +487,7 @@ TEST_F(VideoResourceUpdaterTest, ReuseResourceSoftwareCompositor) { TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDeleteSoftwareCompositor) { std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware(); scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame(); - video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234)); + video_frame->set_timestamp(base::Seconds(1234)); // Allocate the resources for a software video frame. VideoFrameExternalResources resources = diff --git a/chromium/media/renderers/win/media_engine_notify_impl.cc b/chromium/media/renderers/win/media_engine_notify_impl.cc index da71066f543..18220d53015 100644 --- a/chromium/media/renderers/win/media_engine_notify_impl.cc +++ b/chromium/media/renderers/win/media_engine_notify_impl.cc @@ -132,7 +132,7 @@ HRESULT MediaEngineNotifyImpl::EventNotify(DWORD event_code, MF_MEDIA_ENGINE_ERR error = static_cast<MF_MEDIA_ENGINE_ERR>(param1); HRESULT hr = param2; LOG(ERROR) << __func__ << ": error=" << error << ", hr=" << PrintHr(hr); - error_cb_.Run(MediaEngineErrorToPipelineStatus(error, hr)); + error_cb_.Run(MediaEngineErrorToPipelineStatus(error, hr), hr); break; } case MF_MEDIA_ENGINE_EVENT_ENDED: diff --git a/chromium/media/renderers/win/media_engine_notify_impl.h b/chromium/media/renderers/win/media_engine_notify_impl.h index cf3cafc6045..fd03064be03 100644 --- a/chromium/media/renderers/win/media_engine_notify_impl.h +++ b/chromium/media/renderers/win/media_engine_notify_impl.h @@ -15,13 +15,6 @@ namespace media { -using ErrorCB = base::RepeatingCallback<void(PipelineStatus)>; -using EndedCB = base::RepeatingClosure; -using BufferingStateChangedCB = - base::RepeatingCallback<void(BufferingState, BufferingStateChangeReason)>; -using VideoNaturalSizeChangedCB = base::RepeatingClosure; -using TimeUpdateCB = base::RepeatingClosure; - // Implements IMFMediaEngineNotify required by IMFMediaEngine // (https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/nn-mfmediaengine-imfmediaengine). // @@ -34,6 +27,13 @@ class MediaEngineNotifyImpl MediaEngineNotifyImpl(); ~MediaEngineNotifyImpl() override; + using ErrorCB = base::RepeatingCallback<void(PipelineStatus, HRESULT)>; + using EndedCB = base::RepeatingClosure; + using BufferingStateChangedCB = + base::RepeatingCallback<void(BufferingState, BufferingStateChangeReason)>; + using VideoNaturalSizeChangedCB = base::RepeatingClosure; + using TimeUpdateCB = base::RepeatingClosure; + HRESULT RuntimeClassInitialize( ErrorCB error_cb, EndedCB ended_cb, diff --git a/chromium/media/renderers/win/media_foundation_audio_stream.cc b/chromium/media/renderers/win/media_foundation_audio_stream.cc index 5a211ae8b41..c3fca8cf272 100644 --- a/chromium/media/renderers/win/media_foundation_audio_stream.cc +++ b/chromium/media/renderers/win/media_foundation_audio_stream.cc @@ -37,37 +37,37 @@ GUID AudioCodecToMediaFoundationSubtype(AudioCodec codec) { DVLOG(1) << __func__ << ": codec=" << codec; switch (codec) { - case kCodecAAC: + case AudioCodec::kAAC: return MFAudioFormat_AAC; - case kCodecMP3: + case AudioCodec::kMP3: return MFAudioFormat_MP3; - case kCodecPCM: + case AudioCodec::kPCM: return MFAudioFormat_PCM; - case kCodecVorbis: + case AudioCodec::kVorbis: return MFAudioFormat_Vorbis; - case kCodecFLAC: + case AudioCodec::kFLAC: return MFAudioFormat_FLAC; - case kCodecAMR_NB: + case AudioCodec::kAMR_NB: return MFAudioFormat_AMR_NB; - case kCodecAMR_WB: + case AudioCodec::kAMR_WB: return MFAudioFormat_AMR_WB; - case kCodecPCM_MULAW: + case AudioCodec::kPCM_MULAW: return MediaFoundationSubTypeFromWaveFormat(WAVE_FORMAT_MULAW); - case kCodecGSM_MS: + case AudioCodec::kGSM_MS: return MediaFoundationSubTypeFromWaveFormat(WAVE_FORMAT_GSM610); - case kCodecPCM_S16BE: + case AudioCodec::kPCM_S16BE: return MFAudioFormat_PCM; - case kCodecPCM_S24BE: + case AudioCodec::kPCM_S24BE: return MFAudioFormat_PCM; - case kCodecOpus: + case AudioCodec::kOpus: return MFAudioFormat_Opus; - case kCodecEAC3: + case AudioCodec::kEAC3: return MFAudioFormat_Dolby_DDPlus; - case kCodecPCM_ALAW: + case AudioCodec::kPCM_ALAW: return MediaFoundationSubTypeFromWaveFormat(WAVE_FORMAT_ALAW); - case kCodecALAC: + case AudioCodec::kALAC: return MFAudioFormat_ALAC; - case kCodecAC3: + case AudioCodec::kAC3: return MFAudioFormat_Dolby_AC3; default: return GUID_NULL; @@ -76,9 +76,9 @@ GUID AudioCodecToMediaFoundationSubtype(AudioCodec codec) { bool IsUncompressedAudio(AudioCodec codec) { switch (codec) { - case kCodecPCM: - case kCodecPCM_S16BE: - case kCodecPCM_S24BE: + case AudioCodec::kPCM: + case AudioCodec::kPCM_S16BE: + case AudioCodec::kPCM_S24BE: return true; default: return false; @@ -155,8 +155,11 @@ HRESULT GetAacAudioType(const AudioDecoderConfig decoder_config, ComPtr<IMFMediaType> media_type; RETURN_IF_FAILED(GetDefaultAudioType(decoder_config, &media_type)); - size_t wave_format_size = - sizeof(HEAACWAVEINFO) + decoder_config.extra_data().size(); + // On Windows `extra_data` is not populated for AAC in `decoder_config`. Use + // `aac_extra_data` instead. See crbug.com/1245123. + const auto& extra_data = decoder_config.aac_extra_data(); + + size_t wave_format_size = sizeof(HEAACWAVEINFO) + extra_data.size(); std::vector<uint8_t> wave_format_buffer(wave_format_size); HEAACWAVEINFO* aac_wave_format = reinterpret_cast<HEAACWAVEINFO*>(wave_format_buffer.data()); @@ -178,10 +181,9 @@ HRESULT GetAacAudioType(const AudioDecoderConfig decoder_config, aac_wave_format->wReserved1 = 0; aac_wave_format->dwReserved2 = 0; - if (decoder_config.extra_data().size() > 0) { + if (!extra_data.empty()) { memcpy(reinterpret_cast<uint8_t*>(aac_wave_format) + sizeof(HEAACWAVEINFO), - decoder_config.extra_data().data(), - decoder_config.extra_data().size()); + extra_data.data(), extra_data.size()); } RETURN_IF_FAILED(MFInitMediaTypeFromWaveFormatEx( @@ -199,6 +201,7 @@ HRESULT MediaFoundationAudioStream::Create( int stream_id, IMFMediaSource* parent_source, DemuxerStream* demuxer_stream, + std::unique_ptr<MediaLog> media_log, MediaFoundationStreamWrapper** stream_out) { DVLOG(1) << __func__ << ": stream_id=" << stream_id; @@ -206,14 +209,16 @@ HRESULT MediaFoundationAudioStream::Create( AudioCodec codec = demuxer_stream->audio_decoder_config().codec(); switch (codec) { #if BUILDFLAG(USE_PROPRIETARY_CODECS) - case kCodecAAC: + case AudioCodec::kAAC: RETURN_IF_FAILED(MakeAndInitialize<MediaFoundationAACAudioStream>( - &audio_stream, stream_id, parent_source, demuxer_stream)); + &audio_stream, stream_id, parent_source, demuxer_stream, + std::move(media_log))); break; #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) default: RETURN_IF_FAILED(MakeAndInitialize<MediaFoundationAudioStream>( - &audio_stream, stream_id, parent_source, demuxer_stream)); + &audio_stream, stream_id, parent_source, demuxer_stream, + std::move(media_log))); break; } *stream_out = diff --git a/chromium/media/renderers/win/media_foundation_audio_stream.h b/chromium/media/renderers/win/media_foundation_audio_stream.h index ebac24d07fb..1d281a3f862 100644 --- a/chromium/media/renderers/win/media_foundation_audio_stream.h +++ b/chromium/media/renderers/win/media_foundation_audio_stream.h @@ -10,6 +10,7 @@ #include "media/renderers/win/media_foundation_stream_wrapper.h" +#include "media/base/media_log.h" #include "media/media_buildflags.h" namespace media { @@ -20,6 +21,7 @@ class MediaFoundationAudioStream : public MediaFoundationStreamWrapper { static HRESULT Create(int stream_id, IMFMediaSource* parent_source, DemuxerStream* demuxer_stream, + std::unique_ptr<MediaLog> media_log, MediaFoundationStreamWrapper** stream_out); bool IsEncrypted() const override; HRESULT GetMediaType(IMFMediaType** media_type_out) override; diff --git a/chromium/media/renderers/win/media_foundation_protection_manager.cc b/chromium/media/renderers/win/media_foundation_protection_manager.cc index e19382e57e6..d9c7b087745 100644 --- a/chromium/media/renderers/win/media_foundation_protection_manager.cc +++ b/chromium/media/renderers/win/media_foundation_protection_manager.cc @@ -203,7 +203,7 @@ void MediaFoundationProtectionManager::OnBeginEnableContent() { // If EnableContent takes too long, report waiting for key status. Choose a // timeout of 500ms to be on the safe side, e.g. on slower machines. - const auto kWaitingForKeyTimeOut = base::TimeDelta::FromMilliseconds(500); + const auto kWaitingForKeyTimeOut = base::Milliseconds(500); waiting_for_key_time_out_cb_.Reset( base::BindOnce(&MediaFoundationProtectionManager::OnWaitingForKeyTimeOut, diff --git a/chromium/media/renderers/win/media_foundation_renderer.cc b/chromium/media/renderers/win/media_foundation_renderer.cc index 196d161dfa7..5a7c89ac2df 100644 --- a/chromium/media/renderers/win/media_foundation_renderer.cc +++ b/chromium/media/renderers/win/media_foundation_renderer.cc @@ -11,6 +11,7 @@ #include "base/callback_helpers.h" #include "base/guid.h" +#include "base/metrics/histogram_functions.h" #include "base/numerics/safe_conversions.h" #include "base/process/process_handle.h" #include "base/strings/string_number_conversions.h" @@ -22,6 +23,7 @@ #include "base/win/wrapped_window_proc.h" #include "media/base/bind_to_current_loop.h" #include "media/base/cdm_context.h" +#include "media/base/media_log.h" #include "media/base/timestamp_constants.h" #include "media/base/win/mf_helpers.h" #include "media/base/win/mf_initializer.h" @@ -72,8 +74,10 @@ bool MediaFoundationRenderer::IsSupported() { MediaFoundationRenderer::MediaFoundationRenderer( scoped_refptr<base::SequencedTaskRunner> task_runner, + std::unique_ptr<MediaLog> media_log, bool force_dcomp_mode_for_testing) : task_runner_(std::move(task_runner)), + media_log_(std::move(media_log)), force_dcomp_mode_for_testing_(force_dcomp_mode_for_testing) { DVLOG_FUNC(1); } @@ -191,7 +195,7 @@ HRESULT MediaFoundationRenderer::CreateMediaEngine( } RETURN_IF_FAILED(MakeAndInitialize<MediaFoundationSourceWrapper>( - &mf_source_, media_resource, task_runner_)); + &mf_source_, media_resource, media_log_.get(), task_runner_)); if (force_dcomp_mode_for_testing_) ignore_result(SetDCompModeInternal()); @@ -268,6 +272,7 @@ HRESULT MediaFoundationRenderer::InitializeDXGIDeviceManager() { D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creation_flags, feature_levels, base::size(feature_levels), D3D11_SDK_VERSION, &d3d11_device, nullptr, nullptr)); + RETURN_IF_FAILED(media::SetDebugName(d3d11_device.Get(), "Media_MFRenderer")); ComPtr<ID3D10Multithread> multithreaded_device; RETURN_IF_FAILED(d3d11_device.As(&multithreaded_device)); @@ -452,27 +457,32 @@ void MediaFoundationRenderer::SetVideoStreamEnabled(bool enabled) { } } -void MediaFoundationRenderer::SetOutputParams(const gfx::Rect& output_rect) { +void MediaFoundationRenderer::SetOutputRect(const gfx::Rect& output_rect, + SetOutputRectCB callback) { DVLOG_FUNC(2); - output_rect_ = output_rect; - if (virtual_video_window_ && !::SetWindowPos(virtual_video_window_, HWND_BOTTOM, output_rect.x(), output_rect.y(), output_rect.width(), output_rect.height(), SWP_NOACTIVATE)) { DLOG(ERROR) << "Failed to SetWindowPos: " << PrintHr(HRESULT_FROM_WIN32(GetLastError())); + std::move(callback).Run(false); + return; + } + + if (FAILED(UpdateVideoStream(output_rect))) { + std::move(callback).Run(false); return; } - ignore_result(UpdateVideoStream(output_rect)); + std::move(callback).Run(true); } HRESULT MediaFoundationRenderer::UpdateVideoStream(const gfx::Rect& rect) { ComPtr<IMFMediaEngineEx> mf_media_engine_ex; RETURN_IF_FAILED(mf_media_engine_.As(&mf_media_engine_ex)); - RECT dest_rect = rect.ToRECT(); + RECT dest_rect = {0, 0, rect.width(), rect.height()}; RETURN_IF_FAILED(mf_media_engine_ex->UpdateVideoStream( /*pSrc=*/nullptr, &dest_rect, /*pBorderClr=*/nullptr)); return S_OK; @@ -518,7 +528,8 @@ void MediaFoundationRenderer::SendStatistics() { PipelineStatistics new_stats = {}; HRESULT hr = PopulateStatistics(new_stats); if (FAILED(hr)) { - DVLOG_FUNC(3) << "Unable to populate pipeline stats: " << PrintHr(hr); + LIMITED_MEDIA_LOG(INFO, media_log_, populate_statistics_failure_count_, 3) + << "MediaFoundationRenderer failed to populate stats: " + PrintHr(hr); return; } @@ -530,8 +541,7 @@ void MediaFoundationRenderer::SendStatistics() { void MediaFoundationRenderer::StartSendingStatistics() { DVLOG_FUNC(2); - const auto kPipelineStatsPollingPeriod = - base::TimeDelta::FromMilliseconds(500); + const auto kPipelineStatsPollingPeriod = base::Milliseconds(500); statistics_timer_.Start(FROM_HERE, kPipelineStatsPollingPeriod, this, &MediaFoundationRenderer::SendStatistics); } @@ -557,18 +567,25 @@ base::TimeDelta MediaFoundationRenderer::GetMediaTime() { double current_time = mf_media_engine_->GetCurrentTime(); // Restore macro definition. #define GetCurrentTime() GetTickCount() - auto media_time = base::TimeDelta::FromSecondsD(current_time); + auto media_time = base::Seconds(current_time); DVLOG_FUNC(3) << "media_time=" << media_time; return media_time; } -void MediaFoundationRenderer::OnPlaybackError(PipelineStatus status) { - DVLOG_FUNC(1) << "status=" << status; +void MediaFoundationRenderer::OnPlaybackError(PipelineStatus status, + HRESULT hr) { + DVLOG_FUNC(1) << "status=" << status << ", hr=" << hr; DCHECK(task_runner_->RunsTasksInCurrentSequence()); + base::UmaHistogramSparse("Media.MediaFoundationRenderer.PlaybackError", hr); + if (status == PIPELINE_ERROR_HARDWARE_CONTEXT_RESET && cdm_proxy_) cdm_proxy_->OnHardwareContextReset(); + MEDIA_LOG(ERROR, media_log_) + << "MediaFoundationRenderer OnPlaybackError: " << status << ", " + << PrintHr(hr); + renderer_client_->OnError(status); StopSendingStatistics(); } @@ -628,9 +645,14 @@ void MediaFoundationRenderer::OnVideoNaturalSizeChange() { base::checked_cast<int>(native_height)}; } - // If `output_rect_` is not available yet, use `native_video_size_` for now. - if (output_rect_.IsEmpty()) - ignore_result(UpdateVideoStream(gfx::Rect(native_video_size_))); + // TODO(frankli): Let test code to call `UpdateVideoStream()`. + if (force_dcomp_mode_for_testing_) { + const gfx::Rect test_rect(/*x=*/0, /*y=*/0, /*width=*/640, /*height=*/320); + // This invokes IMFMediaEngineEx::UpdateVideoStream() for video frames to + // be presented. Otherwise, the Media Foundation video renderer will not + // request video samples from our source. + ignore_result(UpdateVideoStream(test_rect)); + } renderer_client_->OnVideoNaturalSizeChange(native_video_size_); } diff --git a/chromium/media/renderers/win/media_foundation_renderer.h b/chromium/media/renderers/win/media_foundation_renderer.h index 95d4d0499ed..5b34e30dc51 100644 --- a/chromium/media/renderers/win/media_foundation_renderer.h +++ b/chromium/media/renderers/win/media_foundation_renderer.h @@ -11,7 +11,6 @@ #include <wrl.h> #include "base/callback.h" -#include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" @@ -32,6 +31,8 @@ namespace media { +class MediaLog; + // MediaFoundationRenderer bridges the Renderer and Windows MFMediaEngine // interfaces. class MEDIA_EXPORT MediaFoundationRenderer @@ -42,13 +43,12 @@ class MEDIA_EXPORT MediaFoundationRenderer static bool IsSupported(); MediaFoundationRenderer(scoped_refptr<base::SequencedTaskRunner> task_runner, + std::unique_ptr<MediaLog> media_log, bool force_dcomp_mode_for_testing = false); - + MediaFoundationRenderer(const MediaFoundationRenderer&) = delete; + MediaFoundationRenderer& operator=(const MediaFoundationRenderer&) = delete; ~MediaFoundationRenderer() override; - // TODO(frankli): naming: Change DComp into DirectComposition for interface - // method names in a separate CL. - // Renderer implementation. void Initialize(MediaResource* media_resource, RendererClient* client, @@ -64,7 +64,8 @@ class MEDIA_EXPORT MediaFoundationRenderer // MediaFoundationRendererExtension implementation. void GetDCompSurface(GetDCompSurfaceCB callback) override; void SetVideoStreamEnabled(bool enabled) override; - void SetOutputParams(const gfx::Rect& output_rect) override; + void SetOutputRect(const gfx::Rect& output_rect, + SetOutputRectCB callback) override; private: HRESULT CreateMediaEngine(MediaResource* media_resource); @@ -77,8 +78,8 @@ class MEDIA_EXPORT MediaFoundationRenderer void StartSendingStatistics(); void StopSendingStatistics(); - // Callbacks for |mf_media_engine_notify_|. - void OnPlaybackError(PipelineStatus status); + // Callbacks for `mf_media_engine_notify_`. + void OnPlaybackError(PipelineStatus status, HRESULT hr); void OnPlaybackEnded(); void OnBufferingStateChange(BufferingState state, BufferingStateChangeReason reason); @@ -98,7 +99,10 @@ class MEDIA_EXPORT MediaFoundationRenderer // Renderer methods are running in the same sequence. scoped_refptr<base::SequencedTaskRunner> task_runner_; - // Once set, will force |mf_media_engine_| to use DirectComposition mode. + // Used to report media logs. Can be called on any thread. + std::unique_ptr<MediaLog> media_log_; + + // Once set, will force `mf_media_engine_` to use DirectComposition mode. // This is used for testing. const bool force_dcomp_mode_for_testing_; @@ -118,9 +122,6 @@ class MEDIA_EXPORT MediaFoundationRenderer // This is the same as "natural_size" in Chromium. gfx::Size native_video_size_; - // The actual output Rect for video. - gfx::Rect output_rect_; - // Keep the last volume value being set. float volume_ = 1.0; @@ -131,6 +132,10 @@ class MEDIA_EXPORT MediaFoundationRenderer PipelineStatistics statistics_ = {}; base::RepeatingTimer statistics_timer_; + // Tracks the number of MEDIA_LOGs emitted for failure to populate statistics. + // Useful to prevent log spam. + int populate_statistics_failure_count_ = 0; + // A fake window handle passed to MF-based rendering pipeline for OPM. HWND virtual_video_window_ = nullptr; @@ -143,8 +148,6 @@ class MEDIA_EXPORT MediaFoundationRenderer // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<MediaFoundationRenderer> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(MediaFoundationRenderer); }; } // namespace media diff --git a/chromium/media/renderers/win/media_foundation_renderer_extension.h b/chromium/media/renderers/win/media_foundation_renderer_extension.h index 5162dc6a934..1f48b40c59f 100644 --- a/chromium/media/renderers/win/media_foundation_renderer_extension.h +++ b/chromium/media/renderers/win/media_foundation_renderer_extension.h @@ -32,7 +32,9 @@ class MEDIA_EXPORT MediaFoundationRendererExtension { virtual void SetVideoStreamEnabled(bool enabled) = 0; // Notifies renderer of output composition parameters. - virtual void SetOutputParams(const ::gfx::Rect& rect) = 0; + using SetOutputRectCB = base::OnceCallback<void(bool)>; + virtual void SetOutputRect(const ::gfx::Rect& rect, + SetOutputRectCB callback) = 0; }; } // namespace media diff --git a/chromium/media/renderers/win/media_foundation_renderer_integration_test.cc b/chromium/media/renderers/win/media_foundation_renderer_integration_test.cc index 6d0bedb8577..257042270a0 100644 --- a/chromium/media/renderers/win/media_foundation_renderer_integration_test.cc +++ b/chromium/media/renderers/win/media_foundation_renderer_integration_test.cc @@ -8,6 +8,8 @@ #include <mfapi.h> +#include "base/win/windows_version.h" +#include "media/base/media_util.h" #include "media/test/pipeline_integration_test_base.h" #include "media/test/test_media_source.h" @@ -64,6 +66,7 @@ class MediaFoundationRendererIntegrationTest absl::optional<RendererType> /*renderer_type*/) { auto renderer = std::make_unique<MediaFoundationRenderer>( task_environment_.GetMainThreadTaskRunner(), + std::make_unique<NullMediaLog>(), /*force_dcomp_mode_for_testing=*/true); return renderer; } @@ -72,6 +75,11 @@ class MediaFoundationRendererIntegrationTest }; TEST_F(MediaFoundationRendererIntegrationTest, BasicPlayback) { + // TODO(crbug.com/1240681): This test is very flaky on win10-20h2. + if (base::win::OSInfo::GetInstance()->version() >= + base::win::Version::WIN10_20H2) { + GTEST_SKIP() << "Skipping test for WIN10_20H2 and greater"; + } if (!CanDecodeVp9()) return; @@ -81,6 +89,11 @@ TEST_F(MediaFoundationRendererIntegrationTest, BasicPlayback) { } TEST_F(MediaFoundationRendererIntegrationTest, BasicPlayback_MediaSource) { + // TODO(crbug.com/1240681): This test is very flaky on win10-20h2. + if (base::win::OSInfo::GetInstance()->version() >= + base::win::Version::WIN10_20H2) { + GTEST_SKIP() << "Skipping test for WIN10_20H2 and greater"; + } if (!CanDecodeVp9()) return; diff --git a/chromium/media/renderers/win/media_foundation_renderer_unittest.cc b/chromium/media/renderers/win/media_foundation_renderer_unittest.cc index 8678ae691f6..07b7f19dd25 100644 --- a/chromium/media/renderers/win/media_foundation_renderer_unittest.cc +++ b/chromium/media/renderers/win/media_foundation_renderer_unittest.cc @@ -15,6 +15,7 @@ #include "base/win/scoped_com_initializer.h" #include "media/base/bind_to_current_loop.h" #include "media/base/demuxer_stream.h" +#include "media/base/media_util.h" #include "media/base/mock_filters.h" #include "media/base/test_helpers.h" #include "media/base/win/test_utils.h" @@ -103,7 +104,8 @@ class MediaFoundationRendererTest : public testing::Test { &pmp_server_); mf_renderer_ = std::make_unique<MediaFoundationRenderer>( - task_environment_.GetMainThreadTaskRunner()); + task_environment_.GetMainThreadTaskRunner(), + std::make_unique<NullMediaLog>()); // Some default actions. ON_CALL(cdm_context_, GetMediaFoundationCdmProxy(_)) diff --git a/chromium/media/renderers/win/media_foundation_source_wrapper.cc b/chromium/media/renderers/win/media_foundation_source_wrapper.cc index 3a41567f5c4..a6b2cc8279a 100644 --- a/chromium/media/renderers/win/media_foundation_source_wrapper.cc +++ b/chromium/media/renderers/win/media_foundation_source_wrapper.cc @@ -8,6 +8,7 @@ #include "media/base/audio_decoder_config.h" #include "media/base/demuxer_stream.h" +#include "media/base/media_log.h" #include "media/base/video_decoder_config.h" #include "media/base/win/mf_helpers.h" @@ -34,6 +35,7 @@ MediaFoundationSourceWrapper::~MediaFoundationSourceWrapper() { HRESULT MediaFoundationSourceWrapper::RuntimeClassInitialize( MediaResource* media_resource, + MediaLog* media_log, scoped_refptr<base::SequencedTaskRunner> task_runner) { DVLOG_FUNC(1); @@ -50,7 +52,8 @@ HRESULT MediaFoundationSourceWrapper::RuntimeClassInitialize( for (DemuxerStream* demuxer_stream : demuxer_streams) { ComPtr<MediaFoundationStreamWrapper> mf_stream; RETURN_IF_FAILED(MediaFoundationStreamWrapper::Create( - stream_id++, this, demuxer_stream, task_runner, &mf_stream)); + stream_id++, this, demuxer_stream, media_log->Clone(), task_runner, + &mf_stream)); media_streams_.push_back(mf_stream); } diff --git a/chromium/media/renderers/win/media_foundation_source_wrapper.h b/chromium/media/renderers/win/media_foundation_source_wrapper.h index 88ca8f96b44..de77dac3555 100644 --- a/chromium/media/renderers/win/media_foundation_source_wrapper.h +++ b/chromium/media/renderers/win/media_foundation_source_wrapper.h @@ -20,6 +20,8 @@ namespace media { +class MediaLog; + // IMFMediaSource implementation // (https://docs.microsoft.com/en-us/windows/win32/api/mfidl/nn-mfidl-imfmediasource) // based on the given |media_resource|. @@ -47,6 +49,7 @@ class MediaFoundationSourceWrapper HRESULT RuntimeClassInitialize( MediaResource* media_resource, + MediaLog* media_log, scoped_refptr<base::SequencedTaskRunner> task_runner); // Note: All COM interface (IMFXxx) methods are called on the MF threadpool diff --git a/chromium/media/renderers/win/media_foundation_stream_wrapper.cc b/chromium/media/renderers/win/media_foundation_stream_wrapper.cc index 7eb15906d5c..0d7783695af 100644 --- a/chromium/media/renderers/win/media_foundation_stream_wrapper.cc +++ b/chromium/media/renderers/win/media_foundation_stream_wrapper.cc @@ -122,6 +122,7 @@ HRESULT MediaFoundationStreamWrapper::Create( int stream_id, IMFMediaSource* parent_source, DemuxerStream* demuxer_stream, + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> task_runner, MediaFoundationStreamWrapper** stream_out) { DVLOG(1) << __func__ << ": stream_id=" << stream_id; @@ -130,11 +131,13 @@ HRESULT MediaFoundationStreamWrapper::Create( switch (demuxer_stream->type()) { case DemuxerStream::Type::VIDEO: RETURN_IF_FAILED(MediaFoundationVideoStream::Create( - stream_id, parent_source, demuxer_stream, &stream)); + stream_id, parent_source, demuxer_stream, std::move(media_log), + &stream)); break; case DemuxerStream::Type::AUDIO: RETURN_IF_FAILED(MediaFoundationAudioStream::Create( - stream_id, parent_source, demuxer_stream, &stream)); + stream_id, parent_source, demuxer_stream, std::move(media_log), + &stream)); break; default: DLOG(ERROR) << "Unsupported demuxer stream type: " @@ -149,7 +152,8 @@ HRESULT MediaFoundationStreamWrapper::Create( HRESULT MediaFoundationStreamWrapper::RuntimeClassInitialize( int stream_id, IMFMediaSource* parent_source, - DemuxerStream* demuxer_stream) { + DemuxerStream* demuxer_stream, + std::unique_ptr<MediaLog> media_log) { { base::AutoLock auto_lock(lock_); parent_source_ = parent_source; @@ -161,6 +165,8 @@ HRESULT MediaFoundationStreamWrapper::RuntimeClassInitialize( DVLOG_FUNC(1) << "stream_id=" << stream_id << ", stream_type=" << DemuxerStream::GetTypeName(stream_type_); + media_log_ = std::move(media_log); + RETURN_IF_FAILED(GenerateStreamDescriptor()); RETURN_IF_FAILED(MFCreateEventQueue(&mf_media_event_queue_)); return S_OK; @@ -394,6 +400,11 @@ void MediaFoundationStreamWrapper::OnDemuxerStreamRead( HRESULT hr = S_OK; if (status == DemuxerStream::Status::kOk) { + if (!encryption_type_reported_) { + encryption_type_reported_ = true; + ReportEncryptionType(buffer); + } + // Push |buffer| to process later if needed. Otherwise, process it // immediately. if (flushed_ || !post_flush_buffers_.empty()) { @@ -601,4 +612,24 @@ GUID MediaFoundationStreamWrapper::GetLastKeyId() const { return last_key_id_; } +void MediaFoundationStreamWrapper::ReportEncryptionType( + const scoped_refptr<DecoderBuffer>& buffer) { + auto encryption_type = EncryptionType::kClear; + if (IsEncrypted()) { + bool is_buffer_encrypted = buffer->decrypt_config(); + encryption_type = !is_buffer_encrypted + ? EncryptionType::kEncryptedWithClearLead + : EncryptionType::kEncrypted; + } + + if (encryption_type == EncryptionType::kEncryptedWithClearLead) { + MEDIA_LOG(INFO, media_log_) << "MediaFoundationStreamWrapper: " + << DemuxerStream::GetTypeName(stream_type_) + << " stream is encrypted with clear lead"; + } + + // TODO(xhwang): Report `encryption_type` to `PipelineStatistics` so it's + // also reported to UKM. +} + } // namespace media diff --git a/chromium/media/renderers/win/media_foundation_stream_wrapper.h b/chromium/media/renderers/win/media_foundation_stream_wrapper.h index 6e9cd79fe06..521cb4683a8 100644 --- a/chromium/media/renderers/win/media_foundation_stream_wrapper.h +++ b/chromium/media/renderers/win/media_foundation_stream_wrapper.h @@ -8,6 +8,8 @@ #include <mfapi.h> #include <mfidl.h> #include <wrl.h> + +#include <memory> #include <queue> #include "base/memory/scoped_refptr.h" @@ -16,6 +18,7 @@ #include "base/synchronization/lock.h" #include "media/base/decoder_buffer.h" #include "media/base/demuxer_stream.h" +#include "media/base/media_log.h" namespace media { @@ -47,12 +50,14 @@ class MediaFoundationStreamWrapper static HRESULT Create(int stream_id, IMFMediaSource* parent_source, DemuxerStream* demuxer_stream, + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> task_runner, MediaFoundationStreamWrapper** stream_out); HRESULT RuntimeClassInitialize(int stream_id, IMFMediaSource* parent_source, - DemuxerStream* demuxer_stream); + DemuxerStream* demuxer_stream, + std::unique_ptr<MediaLog> media_log); void SetTaskRunner(scoped_refptr<base::SequencedTaskRunner> task_runner); void DetachParent(); void DetachDemuxerStream(); @@ -116,6 +121,8 @@ class MediaFoundationStreamWrapper bool ServicePostFlushSampleRequest(); virtual HRESULT GetMediaType(IMFMediaType** media_type_out) = 0; + void ReportEncryptionType(const scoped_refptr<DecoderBuffer>& buffer); + scoped_refptr<base::SequencedTaskRunner> task_runner_; enum class State { kInitialized, @@ -126,6 +133,8 @@ class MediaFoundationStreamWrapper DemuxerStream* demuxer_stream_ = nullptr; DemuxerStream::Type stream_type_ = DemuxerStream::Type::UNKNOWN; + std::unique_ptr<MediaLog> media_log_; + // Need exclusive access to some members between calls from MF threadpool // thread and calling thread from Chromium media stack. base::Lock lock_; @@ -166,6 +175,8 @@ class MediaFoundationStreamWrapper std::queue<scoped_refptr<DecoderBuffer>> post_flush_buffers_ GUARDED_BY(lock_); + bool encryption_type_reported_ = false; + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<MediaFoundationStreamWrapper> weak_factory_{this}; }; diff --git a/chromium/media/renderers/win/media_foundation_video_stream.cc b/chromium/media/renderers/win/media_foundation_video_stream.cc index 1ef146a6f04..6d623bf3d8d 100644 --- a/chromium/media/renderers/win/media_foundation_video_stream.cc +++ b/chromium/media/renderers/win/media_foundation_video_stream.cc @@ -26,27 +26,27 @@ DEFINE_MEDIATYPE_GUID(MFVideoFormat_THEORA, FCC('theo')) GUID VideoCodecToMFSubtype(VideoCodec codec) { switch (codec) { - case kCodecH264: + case VideoCodec::kH264: return MFVideoFormat_H264; - case kCodecVC1: + case VideoCodec::kVC1: return MFVideoFormat_WVC1; - case kCodecMPEG2: + case VideoCodec::kMPEG2: return MFVideoFormat_MPEG2; - case kCodecMPEG4: + case VideoCodec::kMPEG4: return MFVideoFormat_MP4V; - case kCodecTheora: + case VideoCodec::kTheora: return MFVideoFormat_THEORA; - case kCodecVP8: + case VideoCodec::kVP8: return MFVideoFormat_VP80; - case kCodecVP9: + case VideoCodec::kVP9: return MFVideoFormat_VP90; - case kCodecHEVC: + case VideoCodec::kHEVC: return MFVideoFormat_HEVC; - case kCodecDolbyVision: + case VideoCodec::kDolbyVision: // TODO(frankli): DolbyVision also supports H264 when the profile ID is 9 // (DOLBYVISION_PROFILE9). Will it be fine to use HEVC? return MFVideoFormat_HEVC; - case kCodecAV1: + case VideoCodec::kAV1: return MFVideoFormat_AV1; default: return GUID_NULL; @@ -234,6 +234,7 @@ HRESULT MediaFoundationVideoStream::Create( int stream_id, IMFMediaSource* parent_source, DemuxerStream* demuxer_stream, + std::unique_ptr<MediaLog> media_log, MediaFoundationStreamWrapper** stream_out) { DVLOG(1) << __func__ << ": stream_id=" << stream_id; @@ -241,28 +242,32 @@ HRESULT MediaFoundationVideoStream::Create( VideoCodec codec = demuxer_stream->video_decoder_config().codec(); switch (codec) { #if BUILDFLAG(USE_PROPRIETARY_CODECS) - case kCodecH264: + case VideoCodec::kH264: RETURN_IF_FAILED(MakeAndInitialize<MediaFoundationH264VideoStream>( - &video_stream, stream_id, parent_source, demuxer_stream)); + &video_stream, stream_id, parent_source, demuxer_stream, + std::move(media_log))); break; #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) #if BUILDFLAG(ENABLE_PLATFORM_HEVC) - case kCodecHEVC: + case VideoCodec::kHEVC: #endif #if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) - case kCodecDolbyVision: + case VideoCodec::kDolbyVision: #endif #if BUILDFLAG(ENABLE_PLATFORM_HEVC) || BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) RETURN_IF_FAILED(MakeAndInitialize<MediaFoundationHEVCVideoStream>( - &video_stream, stream_id, parent_source, demuxer_stream)); + &video_stream, stream_id, parent_source, demuxer_stream, + std::move(media_log))); break; #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) || // BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) default: RETURN_IF_FAILED(MakeAndInitialize<MediaFoundationVideoStream>( - &video_stream, stream_id, parent_source, demuxer_stream)); + &video_stream, stream_id, parent_source, demuxer_stream, + std::move(media_log))); break; } + *stream_out = static_cast<MediaFoundationStreamWrapper*>(video_stream.Detach()); return S_OK; diff --git a/chromium/media/renderers/win/media_foundation_video_stream.h b/chromium/media/renderers/win/media_foundation_video_stream.h index 230df187d44..33e43def6c6 100644 --- a/chromium/media/renderers/win/media_foundation_video_stream.h +++ b/chromium/media/renderers/win/media_foundation_video_stream.h @@ -20,6 +20,7 @@ class MediaFoundationVideoStream : public MediaFoundationStreamWrapper { static HRESULT Create(int stream_id, IMFMediaSource* parent_source, DemuxerStream* demuxer_stream, + std::unique_ptr<MediaLog> media_log, MediaFoundationStreamWrapper** stream_out); bool IsEncrypted() const override; |