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

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: Fix log order. Created 4 years, 1 month 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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 DVLOG(3) << __func__; 90 DVLOG(3) << __func__;
91 DCHECK(sequence_checker_.CalledOnValidSequence()); 91 DCHECK(thread_checker_.CalledOnValidThread());
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 } 216 }
217 217
218 void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBuffer( 218 void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBuffer(
219 const BitstreamBuffer& buffer) { 219 const BitstreamBuffer& buffer) {
220 DVLOG(3) << __func__ << ": buffer size=" << buffer.size(); 220 DVLOG(3) << __func__ << ": buffer size=" << buffer.size();
221 DCHECK(sequence_checker_.CalledOnValidSequence()); 221 DCHECK(sequence_checker_.CalledOnValidSequence());
222 222
223 if (buffer.size() < bitstream_buffer_size_) { 223 if (buffer.size() < bitstream_buffer_size_) {
224 DLOG(ERROR) << "Output BitstreamBuffer isn't big enough: " << buffer.size() 224 DLOG(ERROR) << "Output BitstreamBuffer isn't big enough: " << buffer.size()
225 << " vs. " << bitstream_buffer_size_; 225 << " vs. " << bitstream_buffer_size_;
226 client_->NotifyError(kInvalidArgumentError); 226 client_->NotifyError(kInvalidArgumentError);
Pawel Osciak 2016/10/25 01:44:05 client_ is a WeakPtr, so we should always if (clie
emircan 2016/10/25 21:57:51 Done.
227 return; 227 return;
228 } 228 }
229 229
230 std::unique_ptr<base::SharedMemory> shm( 230 std::unique_ptr<base::SharedMemory> shm(
231 new base::SharedMemory(buffer.handle(), false)); 231 new base::SharedMemory(buffer.handle(), false));
232 if (!shm->Map(buffer.size())) { 232 if (!shm->Map(buffer.size())) {
233 DLOG(ERROR) << "Failed mapping shared memory."; 233 DLOG(ERROR) << "Failed mapping shared memory.";
234 client_->NotifyError(kPlatformFailureError); 234 client_->NotifyError(kPlatformFailureError);
235 return; 235 return;
236 } 236 }
(...skipping 16 matching lines...) Expand all
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();
267 client_.reset();
Pawel Osciak 2016/10/25 01:44:05 Hm, do we need to InvalidateWeakPtrs() on factory
emircan 2016/10/25 21:57:51 It already gets invalidated from GPUVEA's OnWillDe
Pawel Osciak 2016/10/27 01:45:19 In that case I feel InvalidateWeakPtrs() is more e
267 268
268 if (encoder_thread_.IsRunning()) { 269 if (encoder_thread_.IsRunning()) {
269 encoder_thread_task_runner_->PostTask( 270 encoder_thread_task_runner_->PostTask(
270 FROM_HERE, 271 FROM_HERE,
271 base::Bind(&MediaFoundationVideoEncodeAccelerator::DestroyTask, 272 base::Bind(&MediaFoundationVideoEncodeAccelerator::DestroyTask,
272 encoder_task_weak_factory_.GetWeakPtr())); 273 encoder_task_weak_factory_.GetWeakPtr()));
273 encoder_thread_.Stop(); 274 encoder_thread_.Stop();
274 } 275 }
275 276
276 delete this; 277 delete this;
277 } 278 }
278 279
280 bool MediaFoundationVideoEncodeAccelerator::TryToSetupEncodeOnSeparateThread(
281 const base::WeakPtr<Client>& encode_client,
282 const scoped_refptr<base::SingleThreadTaskRunner>& encode_task_runner) {
283 DVLOG(3) << __func__;
284 DCHECK(thread_checker_.CalledOnValidThread());
285 client_ = encode_client;
286 client_task_runner_ = encode_task_runner;
287 sequence_checker_.DetachFromSequence();
288 return true;
289 }
290
279 // static 291 // static
280 void MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() { 292 void MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() {
281 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) 293 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs)
282 ::LoadLibrary(mfdll); 294 ::LoadLibrary(mfdll);
283 } 295 }
284 296
285 bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() { 297 bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() {
286 DVLOG(3) << __func__; 298 DVLOG(3) << __func__;
287 DCHECK(sequence_checker_.CalledOnValidSequence()); 299 DCHECK(thread_checker_.CalledOnValidThread());
288 300
289 if (base::win::GetVersion() < base::win::VERSION_WIN8) { 301 if (base::win::GetVersion() < base::win::VERSION_WIN8) {
290 DVLOG(ERROR) << "Windows versions earlier than 8 are not supported."; 302 DVLOG(ERROR) << "Windows versions earlier than 8 are not supported.";
291 return false; 303 return false;
292 } 304 }
293 305
294 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) { 306 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) {
295 if (!::GetModuleHandle(mfdll)) { 307 if (!::GetModuleHandle(mfdll)) {
296 DVLOG(ERROR) << mfdll << " is required for encoding"; 308 DVLOG(ERROR) << mfdll << " is required for encoding";
297 return false; 309 return false;
(...skipping 16 matching lines...) Expand all
314 &output_info, NULL, &CLSIDs, &count); 326 &output_info, NULL, &CLSIDs, &count);
315 RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false); 327 RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false);
316 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false); 328 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false);
317 DVLOG(3) << "HW encoder(s) found: " << count; 329 DVLOG(3) << "HW encoder(s) found: " << count;
318 hr = encoder_.CreateInstance(CLSIDs[0]); 330 hr = encoder_.CreateInstance(CLSIDs[0]);
319 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false); 331 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false);
320 return true; 332 return true;
321 } 333 }
322 334
323 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() { 335 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() {
324 DCHECK(sequence_checker_.CalledOnValidSequence()); 336 DCHECK(thread_checker_.CalledOnValidThread());
325 337
326 // Initialize output parameters. 338 // Initialize output parameters.
327 HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive()); 339 HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive());
328 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); 340 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false);
329 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 341 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
330 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); 342 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false);
331 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); 343 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
332 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); 344 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false);
333 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); 345 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_);
334 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); 346 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, 377 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE,
366 MFVideoInterlace_Progressive); 378 MFVideoInterlace_Progressive);
367 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); 379 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false);
368 hr = encoder_->SetInputType(0, imf_input_media_type_.get(), 0); 380 hr = encoder_->SetInputType(0, imf_input_media_type_.get(), 0);
369 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false); 381 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false);
370 382
371 return SUCCEEDED(hr); 383 return SUCCEEDED(hr);
372 } 384 }
373 385
374 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() { 386 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() {
375 DCHECK(sequence_checker_.CalledOnValidSequence()); 387 DCHECK(thread_checker_.CalledOnValidThread());
376 388
377 HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid()); 389 HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid());
378 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false); 390 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false);
379 VARIANT var; 391 VARIANT var;
380 var.vt = VT_UI4; 392 var.vt = VT_UI4;
381 var.ulVal = eAVEncCommonRateControlMode_CBR; 393 var.ulVal = eAVEncCommonRateControlMode_CBR;
382 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); 394 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var);
383 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false); 395 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false);
384 var.ulVal = target_bitrate_; 396 var.ulVal = target_bitrate_;
385 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); 397 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var);
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() { 604 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() {
593 encoder_.Release(); 605 encoder_.Release();
594 codec_api_.Release(); 606 codec_api_.Release();
595 imf_input_media_type_.Release(); 607 imf_input_media_type_.Release();
596 imf_output_media_type_.Release(); 608 imf_output_media_type_.Release();
597 input_sample_.Release(); 609 input_sample_.Release();
598 output_sample_.Release(); 610 output_sample_.Release();
599 } 611 }
600 612
601 } // namespace content 613 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698