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

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

Issue 2576073002: Update max supported resolution on MediaFoundationVideoEncodeAccelerator (Closed)
Patch Set: Created 3 years, 12 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
« no previous file with comments | « media/gpu/media_foundation_video_encode_accelerator_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 16 matching lines...) Expand all
27 using base::win::ScopedComPtr; 27 using base::win::ScopedComPtr;
28 using media::mf::MediaBufferScopedPointer; 28 using media::mf::MediaBufferScopedPointer;
29 29
30 namespace media { 30 namespace media {
31 31
32 namespace { 32 namespace {
33 33
34 const int32_t kDefaultTargetBitrate = 5000000; 34 const int32_t kDefaultTargetBitrate = 5000000;
35 const size_t kMaxFrameRateNumerator = 30; 35 const size_t kMaxFrameRateNumerator = 30;
36 const size_t kMaxFrameRateDenominator = 1; 36 const size_t kMaxFrameRateDenominator = 1;
37 const size_t kMaxResolutionWidth = 1920; 37 const size_t kMaxResolutionWidth = 3840;
38 const size_t kMaxResolutionHeight = 1088; 38 const size_t kMaxResolutionHeight = 2176;
39 const size_t kNumInputBuffers = 3; 39 const size_t kNumInputBuffers = 3;
40 // Media Foundation uses 100 nanosecond units for time, see 40 // Media Foundation uses 100 nanosecond units for time, see
41 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms697282(v=vs.85).as px 41 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms697282(v=vs.85).as px
42 const size_t kOneMicrosecondInMFSampleTimeUnits = 10; 42 const size_t kOneMicrosecondInMFSampleTimeUnits = 10;
43 const size_t kOneSecondInMFSampleTimeUnits = 10000000;
44 const size_t kOutputSampleBufferSizeRatio = 4; 43 const size_t kOutputSampleBufferSizeRatio = 4;
45 44
46 constexpr const wchar_t* const kMediaFoundationVideoEncoderDLLs[] = { 45 constexpr const wchar_t* const kMediaFoundationVideoEncoderDLLs[] = {
47 L"mf.dll", L"mfplat.dll", 46 L"mf.dll", L"mfplat.dll",
48 }; 47 };
49 48
50 } // namespace 49 } // namespace
51 50
52 class MediaFoundationVideoEncodeAccelerator::EncodeOutput { 51 class MediaFoundationVideoEncodeAccelerator::EncodeOutput {
53 public: 52 public:
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 u_plane_offset_ = 169 u_plane_offset_ =
171 VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kYPlane, 170 VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kYPlane,
172 input_visible_size_) 171 input_visible_size_)
173 .GetArea(); 172 .GetArea();
174 v_plane_offset_ = 173 v_plane_offset_ =
175 u_plane_offset_ + 174 u_plane_offset_ +
176 VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kUPlane, 175 VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kUPlane,
177 input_visible_size_) 176 input_visible_size_)
178 .GetArea(); 177 .GetArea();
179 178
180
181 if (!SetEncoderModes()) { 179 if (!SetEncoderModes()) {
182 DLOG(ERROR) << "Failed setting encoder parameters."; 180 DLOG(ERROR) << "Failed setting encoder parameters.";
183 return false; 181 return false;
184 } 182 }
185 183
186 if (!InitializeInputOutputSamples()) { 184 if (!InitializeInputOutputSamples()) {
187 DLOG(ERROR) << "Failed initializing input-output samples."; 185 DLOG(ERROR) << "Failed initializing input-output samples.";
188 return false; 186 return false;
189 } 187 }
188
189 MFT_INPUT_STREAM_INFO input_stream_info;
190 HRESULT hr =
191 encoder_->GetInputStreamInfo(input_stream_id_, &input_stream_info);
192 RETURN_ON_HR_FAILURE(hr, "Couldn't get input stream info", false);
190 input_sample_.Attach(mf::CreateEmptySampleWithBuffer( 193 input_sample_.Attach(mf::CreateEmptySampleWithBuffer(
191 VideoFrame::AllocationSize(PIXEL_FORMAT_I420, input_visible_size_), 2)); 194 input_stream_info.cbSize
195 ? input_stream_info.cbSize
196 : VideoFrame::AllocationSize(PIXEL_FORMAT_I420, input_visible_size_),
197 input_stream_info.cbAlignment));
198
199 MFT_OUTPUT_STREAM_INFO output_stream_info;
200 hr = encoder_->GetOutputStreamInfo(output_stream_id_, &output_stream_info);
201 RETURN_ON_HR_FAILURE(hr, "Couldn't get output stream info", false);
192 output_sample_.Attach(mf::CreateEmptySampleWithBuffer( 202 output_sample_.Attach(mf::CreateEmptySampleWithBuffer(
193 bitstream_buffer_size_ * kOutputSampleBufferSizeRatio, 2)); 203 output_stream_info.cbSize
204 ? output_stream_info.cbSize
205 : bitstream_buffer_size_ * kOutputSampleBufferSizeRatio,
206 output_stream_info.cbAlignment));
194 207
195 HRESULT hr = 208 hr = 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); 209 RETURN_ON_HR_FAILURE(hr, "Couldn't set ProcessMessage", false);
198 210
199 // Pin all client callbacks to the main task runner initially. It can be 211 // Pin all client callbacks to the main task runner initially. It can be
200 // reassigned by TryToSetupEncodeOnSeparateThread(). 212 // reassigned by TryToSetupEncodeOnSeparateThread().
201 if (!encode_client_task_runner_) { 213 if (!encode_client_task_runner_) {
202 encode_client_task_runner_ = main_client_task_runner_; 214 encode_client_task_runner_ = main_client_task_runner_;
203 encode_client_ = main_client_; 215 encode_client_ = main_client_;
204 } 216 }
205 217
206 main_client_task_runner_->PostTask( 218 main_client_task_runner_->PostTask(
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false); 345 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false);
334 DVLOG(3) << "HW encoder(s) found: " << count; 346 DVLOG(3) << "HW encoder(s) found: " << count;
335 hr = encoder_.CreateInstance(CLSIDs[0]); 347 hr = encoder_.CreateInstance(CLSIDs[0]);
336 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false); 348 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false);
337 return true; 349 return true;
338 } 350 }
339 351
340 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() { 352 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() {
341 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); 353 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
342 354
355 DWORD input_count = 0;
356 DWORD output_count = 0;
357 HRESULT hr = encoder_->GetStreamCount(&input_count, &output_count);
358 RETURN_ON_HR_FAILURE(hr, "Couldn't get stream count", false);
359 if (input_count < 1 || output_count < 1) {
360 LOG(ERROR) << "Stream count too few: input " << input_count << ", output "
361 << output_count;
362 return false;
363 }
364
365 std::vector<DWORD> input_ids(input_count, 0);
366 std::vector<DWORD> output_ids(output_count, 0);
367 hr = encoder_->GetStreamIDs(input_count, input_ids.data(), output_count,
368 output_ids.data());
369 if (hr == S_OK) {
370 input_stream_id_ = input_ids[0];
371 output_stream_id_ = output_ids[0];
372 } else if (hr == E_NOTIMPL) {
373 input_stream_id_ = 0;
374 output_stream_id_ = 0;
375 } else {
376 LOG(ERROR) << "Couldn't find stream ids.";
377 return false;
378 }
379
343 // Initialize output parameters. 380 // Initialize output parameters.
344 HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive()); 381 hr = MFCreateMediaType(imf_output_media_type_.Receive());
345 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); 382 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false);
346 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 383 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
347 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); 384 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false);
348 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); 385 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
349 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); 386 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false);
350 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); 387 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_);
351 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); 388 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false);
352 hr = MFSetAttributeRatio(imf_output_media_type_.get(), MF_MT_FRAME_RATE, 389 hr = MFSetAttributeRatio(imf_output_media_type_.get(), MF_MT_FRAME_RATE,
353 frame_rate_, kMaxFrameRateDenominator); 390 frame_rate_, 1);
354 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); 391 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false);
355 hr = MFSetAttributeSize(imf_output_media_type_.get(), MF_MT_FRAME_SIZE, 392 hr = MFSetAttributeSize(imf_output_media_type_.get(), MF_MT_FRAME_SIZE,
356 input_visible_size_.width(), 393 input_visible_size_.width(),
357 input_visible_size_.height()); 394 input_visible_size_.height());
358 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); 395 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false);
359 hr = imf_output_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, 396 hr = imf_output_media_type_->SetUINT32(MF_MT_INTERLACE_MODE,
360 MFVideoInterlace_Progressive); 397 MFVideoInterlace_Progressive);
361 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); 398 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false);
362 hr = imf_output_media_type_->SetUINT32(MF_MT_MPEG2_PROFILE, 399 hr = imf_output_media_type_->SetUINT32(MF_MT_MPEG2_PROFILE,
363 eAVEncH264VProfile_Base); 400 eAVEncH264VProfile_Base);
364 RETURN_ON_HR_FAILURE(hr, "Couldn't set codec profile", false); 401 RETURN_ON_HR_FAILURE(hr, "Couldn't set codec profile", false);
365 hr = encoder_->SetOutputType(0, imf_output_media_type_.get(), 0); 402 hr = encoder_->SetOutputType(output_stream_id_, imf_output_media_type_.get(),
403 0);
366 RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", false); 404 RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", false);
367 405
368 // Initialize input parameters. 406 // Initialize input parameters.
369 hr = MFCreateMediaType(imf_input_media_type_.Receive()); 407 hr = MFCreateMediaType(imf_input_media_type_.Receive());
370 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); 408 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false);
371 hr = imf_input_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 409 hr = imf_input_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
372 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); 410 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false);
373 hr = imf_input_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12); 411 hr = imf_input_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12);
374 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); 412 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false);
375 hr = MFSetAttributeRatio(imf_input_media_type_.get(), MF_MT_FRAME_RATE, 413 hr = MFSetAttributeRatio(imf_input_media_type_.get(), MF_MT_FRAME_RATE,
376 frame_rate_, kMaxFrameRateDenominator); 414 frame_rate_, 1);
377 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); 415 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false);
378 hr = MFSetAttributeSize(imf_input_media_type_.get(), MF_MT_FRAME_SIZE, 416 hr = MFSetAttributeSize(imf_input_media_type_.get(), MF_MT_FRAME_SIZE,
379 input_visible_size_.width(), 417 input_visible_size_.width(),
380 input_visible_size_.height()); 418 input_visible_size_.height());
381 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); 419 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false);
382 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, 420 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE,
383 MFVideoInterlace_Progressive); 421 MFVideoInterlace_Progressive);
384 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); 422 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false);
385 hr = encoder_->SetInputType(0, imf_input_media_type_.get(), 0); 423 hr = encoder_->SetInputType(input_stream_id_, imf_input_media_type_.get(), 0);
386 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false); 424 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false);
387 425
388 return SUCCEEDED(hr); 426 return SUCCEEDED(hr);
389 } 427 }
390 428
391 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() { 429 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() {
392 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); 430 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
393 431
394 HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid()); 432 HRESULT hr = encoder_.QueryInterface(IID_ICodecAPI, codec_api_.ReceiveVoid());
395 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false); 433 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false);
396 VARIANT var; 434 VARIANT var;
397 var.vt = VT_UI4; 435 var.vt = VT_UI4;
398 var.ulVal = eAVEncCommonRateControlMode_CBR; 436 var.ulVal = eAVEncCommonRateControlMode_CBR;
399 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); 437 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var);
400 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false); 438 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false);
401 var.ulVal = target_bitrate_; 439 var.ulVal = target_bitrate_;
402 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); 440 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var);
403 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); 441 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false);
404 var.ulVal = eAVEncAdaptiveMode_FrameRate; 442 var.ulVal = eAVEncAdaptiveMode_Resolution;
405 hr = codec_api_->SetValue(&CODECAPI_AVEncAdaptiveMode, &var); 443 hr = codec_api_->SetValue(&CODECAPI_AVEncAdaptiveMode, &var);
406 RETURN_ON_HR_FAILURE(hr, "Couldn't set FrameRate", false); 444 RETURN_ON_HR_FAILURE(hr, "Couldn't set FrameRate", false);
407 var.vt = VT_BOOL; 445 var.vt = VT_BOOL;
408 var.boolVal = VARIANT_TRUE; 446 var.boolVal = VARIANT_TRUE;
409 hr = codec_api_->SetValue(&CODECAPI_AVLowLatencyMode, &var); 447 hr = codec_api_->SetValue(&CODECAPI_AVLowLatencyMode, &var);
410 RETURN_ON_HR_FAILURE(hr, "Couldn't set LowLatencyMode", false); 448 RETURN_ON_HR_FAILURE(hr, "Couldn't set LowLatencyMode", false);
411 return SUCCEEDED(hr); 449 return SUCCEEDED(hr);
412 } 450 }
413 451
414 void MediaFoundationVideoEncodeAccelerator::NotifyError( 452 void MediaFoundationVideoEncodeAccelerator::NotifyError(
(...skipping 24 matching lines...) Expand all
439 frame->stride(VideoFrame::kYPlane), 477 frame->stride(VideoFrame::kYPlane),
440 scoped_buffer.get() + u_plane_offset_, 478 scoped_buffer.get() + u_plane_offset_,
441 frame->stride(VideoFrame::kUPlane), 479 frame->stride(VideoFrame::kUPlane),
442 scoped_buffer.get() + v_plane_offset_, 480 scoped_buffer.get() + v_plane_offset_,
443 frame->stride(VideoFrame::kVPlane), 481 frame->stride(VideoFrame::kVPlane),
444 input_visible_size_.width(), input_visible_size_.height()); 482 input_visible_size_.width(), input_visible_size_.height());
445 } 483 }
446 484
447 input_sample_->SetSampleTime(frame->timestamp().InMicroseconds() * 485 input_sample_->SetSampleTime(frame->timestamp().InMicroseconds() *
448 kOneMicrosecondInMFSampleTimeUnits); 486 kOneMicrosecondInMFSampleTimeUnits);
449 input_sample_->SetSampleDuration(kOneSecondInMFSampleTimeUnits / frame_rate_); 487 UINT64 sample_duration = 1;
488 HRESULT hr =
489 MFFrameRateToAverageTimePerFrame(frame_rate_, 1, &sample_duration);
490 RETURN_ON_HR_FAILURE(hr, "Couldn't calculate sample duration", );
491 input_sample_->SetSampleDuration(sample_duration);
450 492
451 // Release frame after input is copied. 493 // Release frame after input is copied.
452 frame = nullptr; 494 frame = nullptr;
453 495
454 HRESULT hr = encoder_->ProcessInput(0, input_sample_.get(), 0); 496 hr = encoder_->ProcessInput(input_stream_id_, input_sample_.get(), 0);
455 // According to MSDN, if encoder returns MF_E_NOTACCEPTING, we need to try 497 // According to MSDN, if encoder returns MF_E_NOTACCEPTING, we need to try
456 // processing the output. This error indicates that encoder does not accept 498 // processing the output. This error indicates that encoder does not accept
457 // any more input data. 499 // any more input data.
458 if (hr == MF_E_NOTACCEPTING) { 500 if (hr == MF_E_NOTACCEPTING) {
459 DVLOG(3) << "MF_E_NOTACCEPTING"; 501 DVLOG(3) << "MF_E_NOTACCEPTING";
460 ProcessOutput(); 502 ProcessOutput();
461 hr = encoder_->ProcessInput(0, input_sample_.get(), 0); 503 hr = encoder_->ProcessInput(input_stream_id_, input_sample_.get(), 0);
462 if (!SUCCEEDED(hr)) { 504 if (!SUCCEEDED(hr)) {
463 NotifyError(kPlatformFailureError); 505 NotifyError(kPlatformFailureError);
464 RETURN_ON_HR_FAILURE(hr, "Couldn't encode", ); 506 RETURN_ON_HR_FAILURE(hr, "Couldn't encode", );
465 } 507 }
466 } else if (!SUCCEEDED(hr)) { 508 } else if (!SUCCEEDED(hr)) {
467 NotifyError(kPlatformFailureError); 509 NotifyError(kPlatformFailureError);
468 RETURN_ON_HR_FAILURE(hr, "Couldn't encode", ); 510 RETURN_ON_HR_FAILURE(hr, "Couldn't encode", );
469 } 511 }
470 DVLOG(3) << "Sent for encode " << hr; 512 DVLOG(3) << "Sent for encode " << hr;
471 513
472 ProcessOutput(); 514 ProcessOutput();
473 } 515 }
474 516
475 void MediaFoundationVideoEncodeAccelerator::ProcessOutput() { 517 void MediaFoundationVideoEncodeAccelerator::ProcessOutput() {
476 DVLOG(3) << __func__; 518 DVLOG(3) << __func__;
477 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); 519 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
478 520
521 DWORD output_status = 0;
522 HRESULT hr = encoder_->GetOutputStatus(&output_status);
523 RETURN_ON_HR_FAILURE(hr, "Couldn't get output status", );
524 if (output_status != MFT_OUTPUT_STATUS_SAMPLE_READY) {
525 DVLOG(3) << "Output isnt ready";
526 return;
527 }
528
479 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; 529 MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0};
480 output_data_buffer.dwStreamID = 0; 530 output_data_buffer.dwStreamID = 0;
481 output_data_buffer.dwStatus = 0; 531 output_data_buffer.dwStatus = 0;
482 output_data_buffer.pEvents = NULL; 532 output_data_buffer.pEvents = NULL;
483 output_data_buffer.pSample = output_sample_.get(); 533 output_data_buffer.pSample = output_sample_.get();
484 DWORD status = 0; 534 DWORD status = 0;
485 HRESULT hr = encoder_->ProcessOutput(0, 1, &output_data_buffer, &status); 535 hr = encoder_->ProcessOutput(output_stream_id_, 1, &output_data_buffer,
536 &status);
486 if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { 537 if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
487 DVLOG(3) << "MF_E_TRANSFORM_NEED_MORE_INPUT"; 538 DVLOG(3) << "MF_E_TRANSFORM_NEED_MORE_INPUT" << status;
488 return; 539 return;
489 } 540 }
490 RETURN_ON_HR_FAILURE(hr, "Couldn't get encoded data", ); 541 RETURN_ON_HR_FAILURE(hr, "Couldn't get encoded data", );
491 DVLOG(3) << "Got encoded data " << hr; 542 DVLOG(3) << "Got encoded data " << hr;
492 543
493 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 544 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
494 hr = output_sample_->GetBufferByIndex(0, output_buffer.Receive()); 545 hr = output_sample_->GetBufferByIndex(0, output_buffer.Receive());
495 RETURN_ON_HR_FAILURE(hr, "Couldn't get buffer by index", ); 546 RETURN_ON_HR_FAILURE(hr, "Couldn't get buffer by index", );
496 DWORD size = 0; 547 DWORD size = 0;
497 hr = output_buffer->GetCurrentLength(&size); 548 hr = output_buffer->GetCurrentLength(&size);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 encode_output->size(), encode_output->keyframe, 624 encode_output->size(), encode_output->keyframe,
574 encode_output->capture_timestamp)); 625 encode_output->capture_timestamp));
575 } 626 }
576 627
577 void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChangeTask( 628 void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChangeTask(
578 uint32_t bitrate, 629 uint32_t bitrate,
579 uint32_t framerate) { 630 uint32_t framerate) {
580 DVLOG(3) << __func__; 631 DVLOG(3) << __func__;
581 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); 632 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
582 633
583 frame_rate_ = framerate ? framerate : 1; 634 frame_rate_ =
584 target_bitrate_ = bitrate ? bitrate : 1; 635 framerate
636 ? std::min(framerate, static_cast<uint32_t>(kMaxFrameRateNumerator))
637 : 1;
585 638
586 VARIANT var; 639 if (target_bitrate_ != bitrate) {
587 var.vt = VT_UI4; 640 target_bitrate_ = bitrate ? bitrate : 1;
588 var.ulVal = target_bitrate_; 641 VARIANT var;
589 HRESULT hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); 642 var.vt = VT_UI4;
590 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", ); 643 var.ulVal = target_bitrate_;
591 644 HRESULT hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var);
592 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); 645 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", );
593 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", ); 646 }
594 hr = MFSetAttributeRatio(imf_output_media_type_.get(), MF_MT_FRAME_RATE,
595 frame_rate_, kMaxFrameRateDenominator);
596 RETURN_ON_HR_FAILURE(hr, "Couldn't set output type params", );
597 } 647 }
598 648
599 void MediaFoundationVideoEncodeAccelerator::DestroyTask() { 649 void MediaFoundationVideoEncodeAccelerator::DestroyTask() {
600 DVLOG(3) << __func__; 650 DVLOG(3) << __func__;
601 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); 651 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
602 652
603 // Cancel all encoder thread callbacks. 653 // Cancel all encoder thread callbacks.
604 encoder_task_weak_factory_.InvalidateWeakPtrs(); 654 encoder_task_weak_factory_.InvalidateWeakPtrs();
605 655
606 ReleaseEncoderResources(); 656 ReleaseEncoderResources();
607 } 657 }
608 658
609 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() { 659 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() {
610 encoder_.Release(); 660 encoder_.Release();
611 codec_api_.Release(); 661 codec_api_.Release();
612 imf_input_media_type_.Release(); 662 imf_input_media_type_.Release();
613 imf_output_media_type_.Release(); 663 imf_output_media_type_.Release();
614 input_sample_.Release(); 664 input_sample_.Release();
615 output_sample_.Release(); 665 output_sample_.Release();
616 } 666 }
617 667
618 } // namespace content 668 } // namespace content
OLDNEW
« no previous file with comments | « media/gpu/media_foundation_video_encode_accelerator_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698