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

Side by Side Diff: media/gpu/media_foundation_video_encode_accelerator_win.cc

Issue 2427053002: Move video encode accelerator IPC messages to GPU IO thread (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/gpu/media_foundation_video_encode_accelerator_win.h" 5 #include "media/gpu/media_foundation_video_encode_accelerator_win.h"
6 6
7 #pragma warning(push) 7 #pragma warning(push)
8 #pragma warning(disable : 4800) // Disable warning for added padding. 8 #pragma warning(disable : 4800) // Disable warning for added padding.
9 9
10 #include <codecapi.h> 10 #include <codecapi.h>
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 DISALLOW_IMPLICIT_CONSTRUCTORS(BitstreamBufferRef); 80 DISALLOW_IMPLICIT_CONSTRUCTORS(BitstreamBufferRef);
81 }; 81 };
82 82
83 MediaFoundationVideoEncodeAccelerator::MediaFoundationVideoEncodeAccelerator() 83 MediaFoundationVideoEncodeAccelerator::MediaFoundationVideoEncodeAccelerator()
84 : client_task_runner_(base::SequencedTaskRunnerHandle::Get()), 84 : client_task_runner_(base::SequencedTaskRunnerHandle::Get()),
85 encoder_thread_("MFEncoderThread"), 85 encoder_thread_("MFEncoderThread"),
86 encoder_task_weak_factory_(this) {} 86 encoder_task_weak_factory_(this) {}
87 87
88 MediaFoundationVideoEncodeAccelerator:: 88 MediaFoundationVideoEncodeAccelerator::
89 ~MediaFoundationVideoEncodeAccelerator() { 89 ~MediaFoundationVideoEncodeAccelerator() {
90 DCHECK(thread_checker_.CalledOnValidThread());
90 DVLOG(3) << __func__; 91 DVLOG(3) << __func__;
sandersd (OOO until July 31) 2016/10/21 01:01:00 Nit: Prefer __func__ logging first.
emircan 2016/10/24 19:44:53 Done.
91 DCHECK(sequence_checker_.CalledOnValidSequence());
92 92
93 DCHECK(!encoder_thread_.IsRunning()); 93 DCHECK(!encoder_thread_.IsRunning());
94 DCHECK(!encoder_task_weak_factory_.HasWeakPtrs()); 94 DCHECK(!encoder_task_weak_factory_.HasWeakPtrs());
95 } 95 }
96 96
97 VideoEncodeAccelerator::SupportedProfiles 97 VideoEncodeAccelerator::SupportedProfiles
98 MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles() { 98 MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles() {
99 TRACE_EVENT0("gpu,startup", 99 TRACE_EVENT0("gpu,startup",
100 "MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles"); 100 "MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles");
101 DVLOG(3) << __func__; 101 DVLOG(3) << __func__;
102 DCHECK(sequence_checker_.CalledOnValidSequence()); 102 DCHECK(thread_checker_.CalledOnValidThread());
103 103
104 SupportedProfiles profiles; 104 SupportedProfiles profiles;
105 105
106 target_bitrate_ = kDefaultTargetBitrate; 106 target_bitrate_ = kDefaultTargetBitrate;
107 frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator; 107 frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator;
108 input_visible_size_ = gfx::Size(kMaxResolutionWidth, kMaxResolutionHeight); 108 input_visible_size_ = gfx::Size(kMaxResolutionWidth, kMaxResolutionHeight);
109 if (!CreateHardwareEncoderMFT() || !SetEncoderModes() || 109 if (!CreateHardwareEncoderMFT() || !SetEncoderModes() ||
110 !InitializeInputOutputSamples()) { 110 !InitializeInputOutputSamples()) {
111 ReleaseEncoderResources(); 111 ReleaseEncoderResources();
112 DVLOG(1) 112 DVLOG(1)
(...skipping 16 matching lines...) Expand all
129 bool MediaFoundationVideoEncodeAccelerator::Initialize( 129 bool MediaFoundationVideoEncodeAccelerator::Initialize(
130 VideoPixelFormat format, 130 VideoPixelFormat format,
131 const gfx::Size& input_visible_size, 131 const gfx::Size& input_visible_size,
132 VideoCodecProfile output_profile, 132 VideoCodecProfile output_profile,
133 uint32_t initial_bitrate, 133 uint32_t initial_bitrate,
134 Client* client) { 134 Client* client) {
135 DVLOG(3) << __func__ << ": input_format=" << VideoPixelFormatToString(format) 135 DVLOG(3) << __func__ << ": input_format=" << VideoPixelFormatToString(format)
136 << ", input_visible_size=" << input_visible_size.ToString() 136 << ", input_visible_size=" << input_visible_size.ToString()
137 << ", output_profile=" << output_profile 137 << ", output_profile=" << output_profile
138 << ", initial_bitrate=" << initial_bitrate; 138 << ", initial_bitrate=" << initial_bitrate;
139 DCHECK(sequence_checker_.CalledOnValidSequence()); 139 DCHECK(thread_checker_.CalledOnValidThread());
140 140
141 if (PIXEL_FORMAT_I420 != format) { 141 if (PIXEL_FORMAT_I420 != format) {
142 DLOG(ERROR) << "Input format not supported= " 142 DLOG(ERROR) << "Input format not supported= "
143 << VideoPixelFormatToString(format); 143 << VideoPixelFormatToString(format);
144 return false; 144 return false;
145 } 145 }
146 146
147 if (H264PROFILE_BASELINE != output_profile) { 147 if (H264PROFILE_BASELINE != output_profile) {
148 DLOG(ERROR) << "Output profile not supported= " << output_profile; 148 DLOG(ERROR) << "Output profile not supported= " << output_profile;
149 return false; 149 return false;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 253
254 encoder_thread_task_runner_->PostTask( 254 encoder_thread_task_runner_->PostTask(
255 FROM_HERE, 255 FROM_HERE,
256 base::Bind(&MediaFoundationVideoEncodeAccelerator:: 256 base::Bind(&MediaFoundationVideoEncodeAccelerator::
257 RequestEncodingParametersChangeTask, 257 RequestEncodingParametersChangeTask,
258 encoder_task_weak_factory_.GetWeakPtr(), bitrate, framerate)); 258 encoder_task_weak_factory_.GetWeakPtr(), bitrate, framerate));
259 } 259 }
260 260
261 void MediaFoundationVideoEncodeAccelerator::Destroy() { 261 void MediaFoundationVideoEncodeAccelerator::Destroy() {
262 DVLOG(3) << __func__; 262 DVLOG(3) << __func__;
263 DCHECK(sequence_checker_.CalledOnValidSequence()); 263 DCHECK(thread_checker_.CalledOnValidThread());
264 264
265 // Cancel all callbacks. 265 // Cancel all callbacks.
266 client_ptr_factory_.reset(); 266 client_ptr_factory_.reset();
sandersd (OOO until July 31) 2016/10/21 18:41:03 Note that this no longer has the stated side effec
emircan 2016/10/24 19:44:53 Thanks for pointing this out. I added a reset to m
267 267
268 if (encoder_thread_.IsRunning()) { 268 if (encoder_thread_.IsRunning()) {
269 encoder_thread_task_runner_->PostTask( 269 encoder_thread_task_runner_->PostTask(
270 FROM_HERE, 270 FROM_HERE,
271 base::Bind(&MediaFoundationVideoEncodeAccelerator::DestroyTask, 271 base::Bind(&MediaFoundationVideoEncodeAccelerator::DestroyTask,
272 encoder_task_weak_factory_.GetWeakPtr())); 272 encoder_task_weak_factory_.GetWeakPtr()));
273 encoder_thread_.Stop(); 273 encoder_thread_.Stop();
274 } 274 }
275 275
276 delete this; 276 delete this;
277 } 277 }
278 278
279 bool MediaFoundationVideoEncodeAccelerator::TryToSetupEncodeOnSeparateThread(
280 const base::WeakPtr<Client>& encode_client,
281 const scoped_refptr<base::SingleThreadTaskRunner>& encode_task_runner) {
282 DCHECK(thread_checker_.CalledOnValidThread());
283 client_ = encode_client;
284 client_task_runner_ = encode_task_runner;
285 sequence_checker_.DetachFromSequence();
286 return true;
287 }
288
279 // static 289 // static
280 void MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() { 290 void MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() {
281 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) 291 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs)
282 ::LoadLibrary(mfdll); 292 ::LoadLibrary(mfdll);
283 } 293 }
284 294
285 bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() { 295 bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() {
286 DVLOG(3) << __func__; 296 DVLOG(3) << __func__;
287 DCHECK(sequence_checker_.CalledOnValidSequence()); 297 DCHECK(thread_checker_.CalledOnValidThread());
288 298
289 if (base::win::GetVersion() < base::win::VERSION_WIN8) { 299 if (base::win::GetVersion() < base::win::VERSION_WIN8) {
290 DVLOG(ERROR) << "Windows versions earlier than 8 are not supported."; 300 DVLOG(ERROR) << "Windows versions earlier than 8 are not supported.";
291 return false; 301 return false;
292 } 302 }
293 303
294 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) { 304 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) {
295 if (!::GetModuleHandle(mfdll)) { 305 if (!::GetModuleHandle(mfdll)) {
296 DVLOG(ERROR) << mfdll << " is required for encoding"; 306 DVLOG(ERROR) << mfdll << " is required for encoding";
297 return false; 307 return false;
(...skipping 16 matching lines...) Expand all
314 &output_info, NULL, &CLSIDs, &count); 324 &output_info, NULL, &CLSIDs, &count);
315 RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false); 325 RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false);
316 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false); 326 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false);
317 DVLOG(3) << "HW encoder(s) found: " << count; 327 DVLOG(3) << "HW encoder(s) found: " << count;
318 hr = encoder_.CreateInstance(CLSIDs[0]); 328 hr = encoder_.CreateInstance(CLSIDs[0]);
319 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false); 329 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false);
320 return true; 330 return true;
321 } 331 }
322 332
323 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() { 333 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() {
324 DCHECK(sequence_checker_.CalledOnValidSequence()); 334 DCHECK(thread_checker_.CalledOnValidThread());
325 335
326 // Initialize output parameters. 336 // Initialize output parameters.
327 HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive()); 337 HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive());
328 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); 338 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false);
329 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 339 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
330 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); 340 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false);
331 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); 341 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
332 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); 342 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false);
333 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); 343 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_);
334 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); 344 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false);
(...skipping 30 matching lines...) Expand all
365 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, 375 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE,
366 MFVideoInterlace_Progressive); 376 MFVideoInterlace_Progressive);
367 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); 377 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false);
368 hr = encoder_->SetInputType(0, imf_input_media_type_.get(), 0); 378 hr = encoder_->SetInputType(0, imf_input_media_type_.get(), 0);
369 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false); 379 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false);
370 380
371 return SUCCEEDED(hr); 381 return SUCCEEDED(hr);
372 } 382 }
373 383
374 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() { 384 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() {
375 DCHECK(sequence_checker_.CalledOnValidSequence()); 385 DCHECK(thread_checker_.CalledOnValidThread());
376 386
377 HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid()); 387 HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid());
378 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false); 388 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false);
379 VARIANT var; 389 VARIANT var;
380 var.vt = VT_UI4; 390 var.vt = VT_UI4;
381 var.ulVal = eAVEncCommonRateControlMode_CBR; 391 var.ulVal = eAVEncCommonRateControlMode_CBR;
382 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); 392 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var);
383 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false); 393 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false);
384 var.ulVal = target_bitrate_; 394 var.ulVal = target_bitrate_;
385 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); 395 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var);
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() { 602 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() {
593 encoder_.Release(); 603 encoder_.Release();
594 codec_api_.Release(); 604 codec_api_.Release();
595 imf_input_media_type_.Release(); 605 imf_input_media_type_.Release();
596 imf_output_media_type_.Release(); 606 imf_output_media_type_.Release();
597 input_sample_.Release(); 607 input_sample_.Release();
598 output_sample_.Release(); 608 output_sample_.Release();
599 } 609 }
600 610
601 } // namespace content 611 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698