| Index: media/gpu/media_foundation_video_encode_accelerator_win.cc
|
| diff --git a/media/gpu/media_foundation_video_encode_accelerator_win.cc b/media/gpu/media_foundation_video_encode_accelerator_win.cc
|
| index dfd27106cc9ea0047cabba1ad4854dcf9ab49d92..92052e814db6b12c8b5a8e31132db57babfe113f 100644
|
| --- a/media/gpu/media_foundation_video_encode_accelerator_win.cc
|
| +++ b/media/gpu/media_foundation_video_encode_accelerator_win.cc
|
| @@ -15,7 +15,7 @@
|
| #include <utility>
|
| #include <vector>
|
|
|
| -#include "base/threading/sequenced_task_runner_handle.h"
|
| +#include "base/threading/thread_task_runner_handle.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "base/win/scoped_co_mem.h"
|
| #include "base/win/scoped_variant.h"
|
| @@ -81,14 +81,14 @@ struct MediaFoundationVideoEncodeAccelerator::BitstreamBufferRef {
|
| };
|
|
|
| MediaFoundationVideoEncodeAccelerator::MediaFoundationVideoEncodeAccelerator()
|
| - : client_task_runner_(base::SequencedTaskRunnerHandle::Get()),
|
| + : main_client_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
| encoder_thread_("MFEncoderThread"),
|
| encoder_task_weak_factory_(this) {}
|
|
|
| MediaFoundationVideoEncodeAccelerator::
|
| ~MediaFoundationVideoEncodeAccelerator() {
|
| DVLOG(3) << __func__;
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(main_client_task_runner_->BelongsToCurrentThread());
|
|
|
| DCHECK(!encoder_thread_.IsRunning());
|
| DCHECK(!encoder_task_weak_factory_.HasWeakPtrs());
|
| @@ -99,7 +99,7 @@ MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles() {
|
| TRACE_EVENT0("gpu,startup",
|
| "MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles");
|
| DVLOG(3) << __func__;
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(main_client_task_runner_->BelongsToCurrentThread());
|
|
|
| SupportedProfiles profiles;
|
|
|
| @@ -136,7 +136,7 @@ bool MediaFoundationVideoEncodeAccelerator::Initialize(
|
| << ", input_visible_size=" << input_visible_size.ToString()
|
| << ", output_profile=" << output_profile
|
| << ", initial_bitrate=" << initial_bitrate;
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(main_client_task_runner_->BelongsToCurrentThread());
|
|
|
| if (PIXEL_FORMAT_I420 != format) {
|
| DLOG(ERROR) << "Input format not supported= "
|
| @@ -161,8 +161,8 @@ bool MediaFoundationVideoEncodeAccelerator::Initialize(
|
| return false;
|
| }
|
|
|
| - client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
|
| - client_ = client_ptr_factory_->GetWeakPtr();
|
| + main_client_weak_factory_.reset(new base::WeakPtrFactory<Client>(client));
|
| + main_client_ = main_client_weak_factory_->GetWeakPtr();
|
| input_visible_size_ = input_visible_size;
|
| frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator;
|
| target_bitrate_ = initial_bitrate;
|
| @@ -196,10 +196,15 @@ bool MediaFoundationVideoEncodeAccelerator::Initialize(
|
| encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL);
|
| RETURN_ON_HR_FAILURE(hr, "Couldn't set ProcessMessage", false);
|
|
|
| - client_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&Client::RequireBitstreamBuffers, client_, kNumInputBuffers,
|
| - input_visible_size_, bitstream_buffer_size_));
|
| + // Pin all client callbacks to the main task runner initially. It can be
|
| + // reassigned by TryToSetupEncodeOnSeparateThread().
|
| + encode_client_task_runner_ = main_client_task_runner_;
|
| + encode_client_ = main_client_;
|
| +
|
| + main_client_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&Client::RequireBitstreamBuffers, main_client_,
|
| + kNumInputBuffers, input_visible_size_,
|
| + bitstream_buffer_size_));
|
| return SUCCEEDED(hr);
|
| }
|
|
|
| @@ -207,7 +212,7 @@ void MediaFoundationVideoEncodeAccelerator::Encode(
|
| const scoped_refptr<VideoFrame>& frame,
|
| bool force_keyframe) {
|
| DVLOG(3) << __func__;
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(encode_client_task_runner_->BelongsToCurrentThread());
|
|
|
| encoder_thread_task_runner_->PostTask(
|
| FROM_HERE, base::Bind(&MediaFoundationVideoEncodeAccelerator::EncodeTask,
|
| @@ -218,12 +223,12 @@ void MediaFoundationVideoEncodeAccelerator::Encode(
|
| void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBuffer(
|
| const BitstreamBuffer& buffer) {
|
| DVLOG(3) << __func__ << ": buffer size=" << buffer.size();
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(encode_client_task_runner_->BelongsToCurrentThread());
|
|
|
| if (buffer.size() < bitstream_buffer_size_) {
|
| DLOG(ERROR) << "Output BitstreamBuffer isn't big enough: " << buffer.size()
|
| << " vs. " << bitstream_buffer_size_;
|
| - client_->NotifyError(kInvalidArgumentError);
|
| + NotifyError(kInvalidArgumentError);
|
| return;
|
| }
|
|
|
| @@ -231,7 +236,7 @@ void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBuffer(
|
| new base::SharedMemory(buffer.handle(), false));
|
| if (!shm->Map(buffer.size())) {
|
| DLOG(ERROR) << "Failed mapping shared memory.";
|
| - client_->NotifyError(kPlatformFailureError);
|
| + NotifyError(kPlatformFailureError);
|
| return;
|
| }
|
|
|
| @@ -249,7 +254,7 @@ void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChange(
|
| uint32_t framerate) {
|
| DVLOG(3) << __func__ << ": bitrate=" << bitrate
|
| << ": framerate=" << framerate;
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(encode_client_task_runner_->BelongsToCurrentThread());
|
|
|
| encoder_thread_task_runner_->PostTask(
|
| FROM_HERE,
|
| @@ -260,10 +265,14 @@ void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChange(
|
|
|
| void MediaFoundationVideoEncodeAccelerator::Destroy() {
|
| DVLOG(3) << __func__;
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(main_client_task_runner_->BelongsToCurrentThread());
|
|
|
| // Cancel all callbacks.
|
| - client_ptr_factory_.reset();
|
| + main_client_weak_factory_.reset();
|
| +
|
| + // If TryToSetupEncodeOnSeparateThread() is called, this WeakPtr is received
|
| + // from the client and it is responsible for invalidating.
|
| + encode_client_.reset();
|
|
|
| if (encoder_thread_.IsRunning()) {
|
| encoder_thread_task_runner_->PostTask(
|
| @@ -276,6 +285,16 @@ void MediaFoundationVideoEncodeAccelerator::Destroy() {
|
| delete this;
|
| }
|
|
|
| +bool MediaFoundationVideoEncodeAccelerator::TryToSetupEncodeOnSeparateThread(
|
| + const base::WeakPtr<Client>& encode_client,
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& encode_task_runner) {
|
| + DVLOG(3) << __func__;
|
| + DCHECK(main_client_task_runner_->BelongsToCurrentThread());
|
| + encode_client_ = encode_client;
|
| + encode_client_task_runner_ = encode_task_runner;
|
| + return true;
|
| +}
|
| +
|
| // static
|
| void MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() {
|
| for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs)
|
| @@ -284,7 +303,7 @@ void MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() {
|
|
|
| bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() {
|
| DVLOG(3) << __func__;
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(main_client_task_runner_->BelongsToCurrentThread());
|
|
|
| if (base::win::GetVersion() < base::win::VERSION_WIN8) {
|
| DVLOG(ERROR) << "Windows versions earlier than 8 are not supported.";
|
| @@ -321,7 +340,7 @@ bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() {
|
| }
|
|
|
| bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() {
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(main_client_task_runner_->BelongsToCurrentThread());
|
|
|
| // Initialize output parameters.
|
| HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive());
|
| @@ -372,7 +391,7 @@ bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() {
|
| }
|
|
|
| bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() {
|
| - DCHECK(sequence_checker_.CalledOnValidSequence());
|
| + DCHECK(main_client_task_runner_->BelongsToCurrentThread());
|
|
|
| HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid());
|
| RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false);
|
| @@ -397,8 +416,8 @@ bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() {
|
| void MediaFoundationVideoEncodeAccelerator::NotifyError(
|
| VideoEncodeAccelerator::Error error) {
|
| DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
|
| - client_task_runner_->PostTask(
|
| - FROM_HERE, base::Bind(&Client::NotifyError, client_, error));
|
| + main_client_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&Client::NotifyError, main_client_, error));
|
| }
|
|
|
| void MediaFoundationVideoEncodeAccelerator::EncodeTask(
|
| @@ -515,8 +534,8 @@ void MediaFoundationVideoEncodeAccelerator::ProcessOutput() {
|
| memcpy(buffer_ref->shm->memory(), scoped_buffer.get(), size);
|
| }
|
|
|
| - client_task_runner_->PostTask(
|
| - FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_,
|
| + encode_client_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&Client::BitstreamBufferReady, encode_client_,
|
| buffer_ref->id, size, keyframe, timestamp));
|
|
|
| // Keep calling ProcessOutput recursively until MF_E_TRANSFORM_NEED_MORE_INPUT
|
| @@ -550,9 +569,9 @@ void MediaFoundationVideoEncodeAccelerator::ReturnBitstreamBuffer(
|
|
|
| memcpy(buffer_ref->shm->memory(), encode_output->memory(),
|
| encode_output->size());
|
| - client_task_runner_->PostTask(
|
| + encode_client_task_runner_->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&Client::BitstreamBufferReady, client_, buffer_ref->id,
|
| + base::Bind(&Client::BitstreamBufferReady, encode_client_, buffer_ref->id,
|
| encode_output->size(), encode_output->keyframe,
|
| encode_output->capture_timestamp));
|
| }
|
|
|