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

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: posciak@ comments. 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>
11 #include <mferror.h> 11 #include <mferror.h>
12 #include <mftransform.h> 12 #include <mftransform.h>
13 13
14 #include <iterator> 14 #include <iterator>
15 #include <utility> 15 #include <utility>
16 #include <vector> 16 #include <vector>
17 17
18 #include "base/threading/sequenced_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/trace_event/trace_event.h" 19 #include "base/trace_event/trace_event.h"
20 #include "base/win/scoped_co_mem.h" 20 #include "base/win/scoped_co_mem.h"
21 #include "base/win/scoped_variant.h" 21 #include "base/win/scoped_variant.h"
22 #include "base/win/windows_version.h" 22 #include "base/win/windows_version.h"
23 #include "media/base/win/mf_helpers.h" 23 #include "media/base/win/mf_helpers.h"
24 #include "media/base/win/mf_initializer.h" 24 #include "media/base/win/mf_initializer.h"
25 #include "third_party/libyuv/include/libyuv.h" 25 #include "third_party/libyuv/include/libyuv.h"
26 26
27 using base::win::ScopedComPtr; 27 using base::win::ScopedComPtr;
28 using media::mf::MediaBufferScopedPointer; 28 using media::mf::MediaBufferScopedPointer;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 : id(id), shm(std::move(shm)), size(size) {} 74 : id(id), shm(std::move(shm)), size(size) {}
75 const int32_t id; 75 const int32_t id;
76 const std::unique_ptr<base::SharedMemory> shm; 76 const std::unique_ptr<base::SharedMemory> shm;
77 const size_t size; 77 const size_t size;
78 78
79 private: 79 private:
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 : main_client_task_runner_(base::ThreadTaskRunnerHandle::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(main_client_task_runner_->BelongsToCurrentThread());
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(main_client_task_runner_->BelongsToCurrentThread());
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(main_client_task_runner_->BelongsToCurrentThread());
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;
150 } 150 }
151 151
152 encoder_thread_.init_com_with_mta(false); 152 encoder_thread_.init_com_with_mta(false);
153 if (!encoder_thread_.Start()) { 153 if (!encoder_thread_.Start()) {
154 DLOG(ERROR) << "Failed spawning encoder thread."; 154 DLOG(ERROR) << "Failed spawning encoder thread.";
155 return false; 155 return false;
156 } 156 }
157 encoder_thread_task_runner_ = encoder_thread_.task_runner(); 157 encoder_thread_task_runner_ = encoder_thread_.task_runner();
158 158
159 if (!CreateHardwareEncoderMFT()) { 159 if (!CreateHardwareEncoderMFT()) {
160 DLOG(ERROR) << "Failed creating a hardware encoder MFT."; 160 DLOG(ERROR) << "Failed creating a hardware encoder MFT.";
161 return false; 161 return false;
162 } 162 }
163 163
164 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); 164 main_client_weak_factory_.reset(new base::WeakPtrFactory<Client>(client));
165 client_ = client_ptr_factory_->GetWeakPtr(); 165 main_client_ = main_client_weak_factory_->GetWeakPtr();
166 input_visible_size_ = input_visible_size; 166 input_visible_size_ = input_visible_size;
167 frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator; 167 frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator;
168 target_bitrate_ = initial_bitrate; 168 target_bitrate_ = initial_bitrate;
169 bitstream_buffer_size_ = input_visible_size.GetArea(); 169 bitstream_buffer_size_ = input_visible_size.GetArea();
170 u_plane_offset_ = 170 u_plane_offset_ =
171 VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kYPlane, 171 VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kYPlane,
172 input_visible_size_) 172 input_visible_size_)
173 .GetArea(); 173 .GetArea();
174 v_plane_offset_ = 174 v_plane_offset_ =
175 u_plane_offset_ + 175 u_plane_offset_ +
(...skipping 13 matching lines...) Expand all
189 } 189 }
190 input_sample_.Attach(mf::CreateEmptySampleWithBuffer( 190 input_sample_.Attach(mf::CreateEmptySampleWithBuffer(
191 VideoFrame::AllocationSize(PIXEL_FORMAT_I420, input_visible_size_), 2)); 191 VideoFrame::AllocationSize(PIXEL_FORMAT_I420, input_visible_size_), 2));
192 output_sample_.Attach(mf::CreateEmptySampleWithBuffer( 192 output_sample_.Attach(mf::CreateEmptySampleWithBuffer(
193 bitstream_buffer_size_ * kOutputSampleBufferSizeRatio, 2)); 193 bitstream_buffer_size_ * kOutputSampleBufferSizeRatio, 2));
194 194
195 HRESULT hr = 195 HRESULT hr =
196 encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL); 196 encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL);
197 RETURN_ON_HR_FAILURE(hr, "Couldn't set ProcessMessage", false); 197 RETURN_ON_HR_FAILURE(hr, "Couldn't set ProcessMessage", false);
198 198
199 client_task_runner_->PostTask( 199 // Pin all client callbacks to the main task runner initially. It can be
200 FROM_HERE, 200 // reassigned by TryToSetupEncodeOnSeparateThread().
201 base::Bind(&Client::RequireBitstreamBuffers, client_, kNumInputBuffers, 201 if (!encode_client_task_runner_) {
202 input_visible_size_, bitstream_buffer_size_)); 202 encode_client_task_runner_ = main_client_task_runner_;
203 encode_client_ = main_client_;
204 }
205
206 main_client_task_runner_->PostTask(
207 FROM_HERE, base::Bind(&Client::RequireBitstreamBuffers, main_client_,
208 kNumInputBuffers, input_visible_size_,
209 bitstream_buffer_size_));
203 return SUCCEEDED(hr); 210 return SUCCEEDED(hr);
204 } 211 }
205 212
206 void MediaFoundationVideoEncodeAccelerator::Encode( 213 void MediaFoundationVideoEncodeAccelerator::Encode(
207 const scoped_refptr<VideoFrame>& frame, 214 const scoped_refptr<VideoFrame>& frame,
208 bool force_keyframe) { 215 bool force_keyframe) {
209 DVLOG(3) << __func__; 216 DVLOG(3) << __func__;
210 DCHECK(sequence_checker_.CalledOnValidSequence()); 217 DCHECK(encode_client_task_runner_->BelongsToCurrentThread());
211 218
212 encoder_thread_task_runner_->PostTask( 219 encoder_thread_task_runner_->PostTask(
213 FROM_HERE, base::Bind(&MediaFoundationVideoEncodeAccelerator::EncodeTask, 220 FROM_HERE, base::Bind(&MediaFoundationVideoEncodeAccelerator::EncodeTask,
214 encoder_task_weak_factory_.GetWeakPtr(), frame, 221 encoder_task_weak_factory_.GetWeakPtr(), frame,
215 force_keyframe)); 222 force_keyframe));
216 } 223 }
217 224
218 void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBuffer( 225 void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBuffer(
219 const BitstreamBuffer& buffer) { 226 const BitstreamBuffer& buffer) {
220 DVLOG(3) << __func__ << ": buffer size=" << buffer.size(); 227 DVLOG(3) << __func__ << ": buffer size=" << buffer.size();
221 DCHECK(sequence_checker_.CalledOnValidSequence()); 228 DCHECK(encode_client_task_runner_->BelongsToCurrentThread());
222 229
223 if (buffer.size() < bitstream_buffer_size_) { 230 if (buffer.size() < bitstream_buffer_size_) {
224 DLOG(ERROR) << "Output BitstreamBuffer isn't big enough: " << buffer.size() 231 DLOG(ERROR) << "Output BitstreamBuffer isn't big enough: " << buffer.size()
225 << " vs. " << bitstream_buffer_size_; 232 << " vs. " << bitstream_buffer_size_;
226 client_->NotifyError(kInvalidArgumentError); 233 NotifyError(kInvalidArgumentError);
227 return; 234 return;
228 } 235 }
229 236
230 std::unique_ptr<base::SharedMemory> shm( 237 std::unique_ptr<base::SharedMemory> shm(
231 new base::SharedMemory(buffer.handle(), false)); 238 new base::SharedMemory(buffer.handle(), false));
232 if (!shm->Map(buffer.size())) { 239 if (!shm->Map(buffer.size())) {
233 DLOG(ERROR) << "Failed mapping shared memory."; 240 DLOG(ERROR) << "Failed mapping shared memory.";
234 client_->NotifyError(kPlatformFailureError); 241 NotifyError(kPlatformFailureError);
235 return; 242 return;
236 } 243 }
237 244
238 std::unique_ptr<BitstreamBufferRef> buffer_ref( 245 std::unique_ptr<BitstreamBufferRef> buffer_ref(
239 new BitstreamBufferRef(buffer.id(), std::move(shm), buffer.size())); 246 new BitstreamBufferRef(buffer.id(), std::move(shm), buffer.size()));
240 encoder_thread_task_runner_->PostTask( 247 encoder_thread_task_runner_->PostTask(
241 FROM_HERE, 248 FROM_HERE,
242 base::Bind( 249 base::Bind(
243 &MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBufferTask, 250 &MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBufferTask,
244 encoder_task_weak_factory_.GetWeakPtr(), base::Passed(&buffer_ref))); 251 encoder_task_weak_factory_.GetWeakPtr(), base::Passed(&buffer_ref)));
245 } 252 }
246 253
247 void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChange( 254 void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChange(
248 uint32_t bitrate, 255 uint32_t bitrate,
249 uint32_t framerate) { 256 uint32_t framerate) {
250 DVLOG(3) << __func__ << ": bitrate=" << bitrate 257 DVLOG(3) << __func__ << ": bitrate=" << bitrate
251 << ": framerate=" << framerate; 258 << ": framerate=" << framerate;
252 DCHECK(sequence_checker_.CalledOnValidSequence()); 259 DCHECK(encode_client_task_runner_->BelongsToCurrentThread());
253 260
254 encoder_thread_task_runner_->PostTask( 261 encoder_thread_task_runner_->PostTask(
255 FROM_HERE, 262 FROM_HERE,
256 base::Bind(&MediaFoundationVideoEncodeAccelerator:: 263 base::Bind(&MediaFoundationVideoEncodeAccelerator::
257 RequestEncodingParametersChangeTask, 264 RequestEncodingParametersChangeTask,
258 encoder_task_weak_factory_.GetWeakPtr(), bitrate, framerate)); 265 encoder_task_weak_factory_.GetWeakPtr(), bitrate, framerate));
259 } 266 }
260 267
261 void MediaFoundationVideoEncodeAccelerator::Destroy() { 268 void MediaFoundationVideoEncodeAccelerator::Destroy() {
262 DVLOG(3) << __func__; 269 DVLOG(3) << __func__;
263 DCHECK(sequence_checker_.CalledOnValidSequence()); 270 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
264 271
265 // Cancel all callbacks. 272 // Cancel all callbacks.
266 client_ptr_factory_.reset(); 273 main_client_weak_factory_.reset();
267 274
268 if (encoder_thread_.IsRunning()) { 275 if (encoder_thread_.IsRunning()) {
269 encoder_thread_task_runner_->PostTask( 276 encoder_thread_task_runner_->PostTask(
270 FROM_HERE, 277 FROM_HERE,
271 base::Bind(&MediaFoundationVideoEncodeAccelerator::DestroyTask, 278 base::Bind(&MediaFoundationVideoEncodeAccelerator::DestroyTask,
272 encoder_task_weak_factory_.GetWeakPtr())); 279 encoder_task_weak_factory_.GetWeakPtr()));
273 encoder_thread_.Stop(); 280 encoder_thread_.Stop();
274 } 281 }
275 282
276 delete this; 283 delete this;
277 } 284 }
278 285
286 bool MediaFoundationVideoEncodeAccelerator::TryToSetupEncodeOnSeparateThread(
287 const base::WeakPtr<Client>& encode_client,
288 const scoped_refptr<base::SingleThreadTaskRunner>& encode_task_runner) {
289 DVLOG(3) << __func__;
290 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
291 encode_client_ = encode_client;
292 encode_client_task_runner_ = encode_task_runner;
293 return true;
294 }
295
279 // static 296 // static
280 void MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() { 297 void MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization() {
281 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) 298 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs)
282 ::LoadLibrary(mfdll); 299 ::LoadLibrary(mfdll);
283 } 300 }
284 301
285 bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() { 302 bool MediaFoundationVideoEncodeAccelerator::CreateHardwareEncoderMFT() {
286 DVLOG(3) << __func__; 303 DVLOG(3) << __func__;
287 DCHECK(sequence_checker_.CalledOnValidSequence()); 304 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
288 305
289 if (base::win::GetVersion() < base::win::VERSION_WIN8) { 306 if (base::win::GetVersion() < base::win::VERSION_WIN8) {
290 DVLOG(ERROR) << "Windows versions earlier than 8 are not supported."; 307 DVLOG(ERROR) << "Windows versions earlier than 8 are not supported.";
291 return false; 308 return false;
292 } 309 }
293 310
294 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) { 311 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) {
295 if (!::GetModuleHandle(mfdll)) { 312 if (!::GetModuleHandle(mfdll)) {
296 DVLOG(ERROR) << mfdll << " is required for encoding"; 313 DVLOG(ERROR) << mfdll << " is required for encoding";
297 return false; 314 return false;
(...skipping 16 matching lines...) Expand all
314 &output_info, NULL, &CLSIDs, &count); 331 &output_info, NULL, &CLSIDs, &count);
315 RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false); 332 RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false);
316 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false); 333 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false);
317 DVLOG(3) << "HW encoder(s) found: " << count; 334 DVLOG(3) << "HW encoder(s) found: " << count;
318 hr = encoder_.CreateInstance(CLSIDs[0]); 335 hr = encoder_.CreateInstance(CLSIDs[0]);
319 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false); 336 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false);
320 return true; 337 return true;
321 } 338 }
322 339
323 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() { 340 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() {
324 DCHECK(sequence_checker_.CalledOnValidSequence()); 341 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
325 342
326 // Initialize output parameters. 343 // Initialize output parameters.
327 HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive()); 344 HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive());
328 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); 345 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false);
329 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 346 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
330 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); 347 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false);
331 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); 348 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
332 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); 349 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false);
333 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); 350 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_);
334 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); 351 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, 382 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE,
366 MFVideoInterlace_Progressive); 383 MFVideoInterlace_Progressive);
367 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); 384 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false);
368 hr = encoder_->SetInputType(0, imf_input_media_type_.get(), 0); 385 hr = encoder_->SetInputType(0, imf_input_media_type_.get(), 0);
369 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false); 386 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false);
370 387
371 return SUCCEEDED(hr); 388 return SUCCEEDED(hr);
372 } 389 }
373 390
374 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() { 391 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() {
375 DCHECK(sequence_checker_.CalledOnValidSequence()); 392 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
376 393
377 HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid()); 394 HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid());
378 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false); 395 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false);
379 VARIANT var; 396 VARIANT var;
380 var.vt = VT_UI4; 397 var.vt = VT_UI4;
381 var.ulVal = eAVEncCommonRateControlMode_CBR; 398 var.ulVal = eAVEncCommonRateControlMode_CBR;
382 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); 399 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var);
383 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false); 400 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false);
384 var.ulVal = target_bitrate_; 401 var.ulVal = target_bitrate_;
385 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); 402 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var);
386 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); 403 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false);
387 var.ulVal = eAVEncAdaptiveMode_FrameRate; 404 var.ulVal = eAVEncAdaptiveMode_FrameRate;
388 hr = codec_api_->SetValue(&CODECAPI_AVEncAdaptiveMode, &var); 405 hr = codec_api_->SetValue(&CODECAPI_AVEncAdaptiveMode, &var);
389 RETURN_ON_HR_FAILURE(hr, "Couldn't set FrameRate", false); 406 RETURN_ON_HR_FAILURE(hr, "Couldn't set FrameRate", false);
390 var.vt = VT_BOOL; 407 var.vt = VT_BOOL;
391 var.boolVal = VARIANT_TRUE; 408 var.boolVal = VARIANT_TRUE;
392 hr = codec_api_->SetValue(&CODECAPI_AVLowLatencyMode, &var); 409 hr = codec_api_->SetValue(&CODECAPI_AVLowLatencyMode, &var);
393 RETURN_ON_HR_FAILURE(hr, "Couldn't set LowLatencyMode", false); 410 RETURN_ON_HR_FAILURE(hr, "Couldn't set LowLatencyMode", false);
394 return SUCCEEDED(hr); 411 return SUCCEEDED(hr);
395 } 412 }
396 413
397 void MediaFoundationVideoEncodeAccelerator::NotifyError( 414 void MediaFoundationVideoEncodeAccelerator::NotifyError(
398 VideoEncodeAccelerator::Error error) { 415 VideoEncodeAccelerator::Error error) {
399 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); 416 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
400 client_task_runner_->PostTask( 417 main_client_task_runner_->PostTask(
401 FROM_HERE, base::Bind(&Client::NotifyError, client_, error)); 418 FROM_HERE, base::Bind(&Client::NotifyError, main_client_, error));
402 } 419 }
403 420
404 void MediaFoundationVideoEncodeAccelerator::EncodeTask( 421 void MediaFoundationVideoEncodeAccelerator::EncodeTask(
405 scoped_refptr<VideoFrame> frame, 422 scoped_refptr<VideoFrame> frame,
406 bool force_keyframe) { 423 bool force_keyframe) {
407 DVLOG(3) << __func__; 424 DVLOG(3) << __func__;
408 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); 425 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
409 426
410 base::win::ScopedComPtr<IMFMediaBuffer> input_buffer; 427 base::win::ScopedComPtr<IMFMediaBuffer> input_buffer;
411 input_sample_->GetBufferByIndex(0, input_buffer.Receive()); 428 input_sample_->GetBufferByIndex(0, input_buffer.Receive());
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 525
509 std::unique_ptr<MediaFoundationVideoEncodeAccelerator::BitstreamBufferRef> 526 std::unique_ptr<MediaFoundationVideoEncodeAccelerator::BitstreamBufferRef>
510 buffer_ref = std::move(bitstream_buffer_queue_.front()); 527 buffer_ref = std::move(bitstream_buffer_queue_.front());
511 bitstream_buffer_queue_.pop_front(); 528 bitstream_buffer_queue_.pop_front();
512 529
513 { 530 {
514 MediaBufferScopedPointer scoped_buffer(output_buffer.get()); 531 MediaBufferScopedPointer scoped_buffer(output_buffer.get());
515 memcpy(buffer_ref->shm->memory(), scoped_buffer.get(), size); 532 memcpy(buffer_ref->shm->memory(), scoped_buffer.get(), size);
516 } 533 }
517 534
518 client_task_runner_->PostTask( 535 encode_client_task_runner_->PostTask(
519 FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_, 536 FROM_HERE, base::Bind(&Client::BitstreamBufferReady, encode_client_,
520 buffer_ref->id, size, keyframe, timestamp)); 537 buffer_ref->id, size, keyframe, timestamp));
521 538
522 // Keep calling ProcessOutput recursively until MF_E_TRANSFORM_NEED_MORE_INPUT 539 // Keep calling ProcessOutput recursively until MF_E_TRANSFORM_NEED_MORE_INPUT
523 // is returned to flush out all the output. 540 // is returned to flush out all the output.
524 ProcessOutput(); 541 ProcessOutput();
525 } 542 }
526 543
527 void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBufferTask( 544 void MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBufferTask(
528 std::unique_ptr<BitstreamBufferRef> buffer_ref) { 545 std::unique_ptr<BitstreamBufferRef> buffer_ref) {
529 DVLOG(3) << __func__; 546 DVLOG(3) << __func__;
(...skipping 13 matching lines...) Expand all
543 560
544 void MediaFoundationVideoEncodeAccelerator::ReturnBitstreamBuffer( 561 void MediaFoundationVideoEncodeAccelerator::ReturnBitstreamBuffer(
545 std::unique_ptr<EncodeOutput> encode_output, 562 std::unique_ptr<EncodeOutput> encode_output,
546 std::unique_ptr<MediaFoundationVideoEncodeAccelerator::BitstreamBufferRef> 563 std::unique_ptr<MediaFoundationVideoEncodeAccelerator::BitstreamBufferRef>
547 buffer_ref) { 564 buffer_ref) {
548 DVLOG(3) << __func__; 565 DVLOG(3) << __func__;
549 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); 566 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
550 567
551 memcpy(buffer_ref->shm->memory(), encode_output->memory(), 568 memcpy(buffer_ref->shm->memory(), encode_output->memory(),
552 encode_output->size()); 569 encode_output->size());
553 client_task_runner_->PostTask( 570 encode_client_task_runner_->PostTask(
554 FROM_HERE, 571 FROM_HERE,
555 base::Bind(&Client::BitstreamBufferReady, client_, buffer_ref->id, 572 base::Bind(&Client::BitstreamBufferReady, encode_client_, buffer_ref->id,
556 encode_output->size(), encode_output->keyframe, 573 encode_output->size(), encode_output->keyframe,
557 encode_output->capture_timestamp)); 574 encode_output->capture_timestamp));
558 } 575 }
559 576
560 void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChangeTask( 577 void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChangeTask(
561 uint32_t bitrate, 578 uint32_t bitrate,
562 uint32_t framerate) { 579 uint32_t framerate) {
563 DVLOG(3) << __func__; 580 DVLOG(3) << __func__;
564 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); 581 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
565 582
(...skipping 26 matching lines...) Expand all
592 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() { 609 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() {
593 encoder_.Release(); 610 encoder_.Release();
594 codec_api_.Release(); 611 codec_api_.Release();
595 imf_input_media_type_.Release(); 612 imf_input_media_type_.Release();
596 imf_output_media_type_.Release(); 613 imf_output_media_type_.Release();
597 input_sample_.Release(); 614 input_sample_.Release();
598 output_sample_.Release(); 615 output_sample_.Release();
599 } 616 }
600 617
601 } // namespace content 618 } // namespace content
OLDNEW
« no previous file with comments | « media/gpu/media_foundation_video_encode_accelerator_win.h ('k') | media/gpu/video_encode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698