OLD | NEW |
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 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 output_stream_id_ = output_ids[0]; | 384 output_stream_id_ = output_ids[0]; |
385 } else if (hr == E_NOTIMPL) { | 385 } else if (hr == E_NOTIMPL) { |
386 input_stream_id_ = 0; | 386 input_stream_id_ = 0; |
387 output_stream_id_ = 0; | 387 output_stream_id_ = 0; |
388 } else { | 388 } else { |
389 LOG(ERROR) << "Couldn't find stream ids."; | 389 LOG(ERROR) << "Couldn't find stream ids."; |
390 return false; | 390 return false; |
391 } | 391 } |
392 | 392 |
393 // Initialize output parameters. | 393 // Initialize output parameters. |
394 hr = MFCreateMediaType(imf_output_media_type_.Receive()); | 394 hr = MFCreateMediaType(imf_output_media_type_.GetAddressOf()); |
395 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); | 395 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); |
396 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); | 396 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); |
397 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); | 397 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); |
398 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); | 398 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); |
399 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); | 399 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); |
400 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); | 400 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); |
401 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); | 401 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); |
402 hr = MFSetAttributeRatio(imf_output_media_type_.Get(), MF_MT_FRAME_RATE, | 402 hr = MFSetAttributeRatio(imf_output_media_type_.Get(), MF_MT_FRAME_RATE, |
403 frame_rate_, 1); | 403 frame_rate_, 1); |
404 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); | 404 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); |
405 hr = MFSetAttributeSize(imf_output_media_type_.Get(), MF_MT_FRAME_SIZE, | 405 hr = MFSetAttributeSize(imf_output_media_type_.Get(), MF_MT_FRAME_SIZE, |
406 input_visible_size_.width(), | 406 input_visible_size_.width(), |
407 input_visible_size_.height()); | 407 input_visible_size_.height()); |
408 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); | 408 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); |
409 hr = imf_output_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, | 409 hr = imf_output_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, |
410 MFVideoInterlace_Progressive); | 410 MFVideoInterlace_Progressive); |
411 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); | 411 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); |
412 hr = imf_output_media_type_->SetUINT32(MF_MT_MPEG2_PROFILE, | 412 hr = imf_output_media_type_->SetUINT32(MF_MT_MPEG2_PROFILE, |
413 eAVEncH264VProfile_Base); | 413 eAVEncH264VProfile_Base); |
414 RETURN_ON_HR_FAILURE(hr, "Couldn't set codec profile", false); | 414 RETURN_ON_HR_FAILURE(hr, "Couldn't set codec profile", false); |
415 hr = encoder_->SetOutputType(output_stream_id_, imf_output_media_type_.Get(), | 415 hr = encoder_->SetOutputType(output_stream_id_, imf_output_media_type_.Get(), |
416 0); | 416 0); |
417 RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", false); | 417 RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", false); |
418 | 418 |
419 // Initialize input parameters. | 419 // Initialize input parameters. |
420 hr = MFCreateMediaType(imf_input_media_type_.Receive()); | 420 hr = MFCreateMediaType(imf_input_media_type_.GetAddressOf()); |
421 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); | 421 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); |
422 hr = imf_input_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); | 422 hr = imf_input_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); |
423 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); | 423 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); |
424 hr = imf_input_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12); | 424 hr = imf_input_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12); |
425 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); | 425 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); |
426 hr = MFSetAttributeRatio(imf_input_media_type_.Get(), MF_MT_FRAME_RATE, | 426 hr = MFSetAttributeRatio(imf_input_media_type_.Get(), MF_MT_FRAME_RATE, |
427 frame_rate_, 1); | 427 frame_rate_, 1); |
428 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); | 428 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); |
429 hr = MFSetAttributeSize(imf_input_media_type_.Get(), MF_MT_FRAME_SIZE, | 429 hr = MFSetAttributeSize(imf_input_media_type_.Get(), MF_MT_FRAME_SIZE, |
430 input_visible_size_.width(), | 430 input_visible_size_.width(), |
431 input_visible_size_.height()); | 431 input_visible_size_.height()); |
432 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); | 432 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); |
433 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, | 433 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, |
434 MFVideoInterlace_Progressive); | 434 MFVideoInterlace_Progressive); |
435 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); | 435 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); |
436 hr = encoder_->SetInputType(input_stream_id_, imf_input_media_type_.Get(), 0); | 436 hr = encoder_->SetInputType(input_stream_id_, imf_input_media_type_.Get(), 0); |
437 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false); | 437 RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false); |
438 | 438 |
439 return SUCCEEDED(hr); | 439 return SUCCEEDED(hr); |
440 } | 440 } |
441 | 441 |
442 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() { | 442 bool MediaFoundationVideoEncodeAccelerator::SetEncoderModes() { |
443 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); | 443 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); |
444 RETURN_ON_FAILURE((encoder_.Get() != nullptr), | 444 RETURN_ON_FAILURE((encoder_.Get() != nullptr), |
445 "No HW encoder instance created", false); | 445 "No HW encoder instance created", false); |
446 | 446 |
447 HRESULT hr = encoder_.CopyTo(codec_api_.Receive()); | 447 HRESULT hr = encoder_.CopyTo(codec_api_.GetAddressOf()); |
448 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false); | 448 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false); |
449 VARIANT var; | 449 VARIANT var; |
450 var.vt = VT_UI4; | 450 var.vt = VT_UI4; |
451 var.ulVal = eAVEncCommonRateControlMode_CBR; | 451 var.ulVal = eAVEncCommonRateControlMode_CBR; |
452 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); | 452 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); |
453 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false); | 453 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false); |
454 var.ulVal = target_bitrate_; | 454 var.ulVal = target_bitrate_; |
455 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); | 455 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); |
456 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); | 456 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); |
457 var.ulVal = eAVEncAdaptiveMode_Resolution; | 457 var.ulVal = eAVEncAdaptiveMode_Resolution; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 FROM_HERE, base::Bind(&Client::NotifyError, main_client_, error)); | 493 FROM_HERE, base::Bind(&Client::NotifyError, main_client_, error)); |
494 } | 494 } |
495 | 495 |
496 void MediaFoundationVideoEncodeAccelerator::EncodeTask( | 496 void MediaFoundationVideoEncodeAccelerator::EncodeTask( |
497 scoped_refptr<VideoFrame> frame, | 497 scoped_refptr<VideoFrame> frame, |
498 bool force_keyframe) { | 498 bool force_keyframe) { |
499 DVLOG(3) << __func__; | 499 DVLOG(3) << __func__; |
500 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); | 500 DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); |
501 | 501 |
502 base::win::ScopedComPtr<IMFMediaBuffer> input_buffer; | 502 base::win::ScopedComPtr<IMFMediaBuffer> input_buffer; |
503 input_sample_->GetBufferByIndex(0, input_buffer.Receive()); | 503 input_sample_->GetBufferByIndex(0, input_buffer.GetAddressOf()); |
504 | 504 |
505 { | 505 { |
506 MediaBufferScopedPointer scoped_buffer(input_buffer.Get()); | 506 MediaBufferScopedPointer scoped_buffer(input_buffer.Get()); |
507 DCHECK(scoped_buffer.get()); | 507 DCHECK(scoped_buffer.get()); |
508 libyuv::I420Copy(frame->visible_data(VideoFrame::kYPlane), | 508 libyuv::I420Copy(frame->visible_data(VideoFrame::kYPlane), |
509 frame->stride(VideoFrame::kYPlane), | 509 frame->stride(VideoFrame::kYPlane), |
510 frame->visible_data(VideoFrame::kVPlane), | 510 frame->visible_data(VideoFrame::kVPlane), |
511 frame->stride(VideoFrame::kVPlane), | 511 frame->stride(VideoFrame::kVPlane), |
512 frame->visible_data(VideoFrame::kUPlane), | 512 frame->visible_data(VideoFrame::kUPlane), |
513 frame->stride(VideoFrame::kUPlane), scoped_buffer.get(), | 513 frame->stride(VideoFrame::kUPlane), scoped_buffer.get(), |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 hr = encoder_->ProcessOutput(output_stream_id_, 1, &output_data_buffer, | 572 hr = encoder_->ProcessOutput(output_stream_id_, 1, &output_data_buffer, |
573 &status); | 573 &status); |
574 if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { | 574 if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { |
575 DVLOG(3) << "MF_E_TRANSFORM_NEED_MORE_INPUT" << status; | 575 DVLOG(3) << "MF_E_TRANSFORM_NEED_MORE_INPUT" << status; |
576 return; | 576 return; |
577 } | 577 } |
578 RETURN_ON_HR_FAILURE(hr, "Couldn't get encoded data", ); | 578 RETURN_ON_HR_FAILURE(hr, "Couldn't get encoded data", ); |
579 DVLOG(3) << "Got encoded data " << hr; | 579 DVLOG(3) << "Got encoded data " << hr; |
580 | 580 |
581 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; | 581 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; |
582 hr = output_sample_->GetBufferByIndex(0, output_buffer.Receive()); | 582 hr = output_sample_->GetBufferByIndex(0, output_buffer.GetAddressOf()); |
583 RETURN_ON_HR_FAILURE(hr, "Couldn't get buffer by index", ); | 583 RETURN_ON_HR_FAILURE(hr, "Couldn't get buffer by index", ); |
584 DWORD size = 0; | 584 DWORD size = 0; |
585 hr = output_buffer->GetCurrentLength(&size); | 585 hr = output_buffer->GetCurrentLength(&size); |
586 RETURN_ON_HR_FAILURE(hr, "Couldn't get buffer length", ); | 586 RETURN_ON_HR_FAILURE(hr, "Couldn't get buffer length", ); |
587 | 587 |
588 base::TimeDelta timestamp; | 588 base::TimeDelta timestamp; |
589 LONGLONG sample_time; | 589 LONGLONG sample_time; |
590 hr = output_sample_->GetSampleTime(&sample_time); | 590 hr = output_sample_->GetSampleTime(&sample_time); |
591 if (SUCCEEDED(hr)) { | 591 if (SUCCEEDED(hr)) { |
592 timestamp = base::TimeDelta::FromMicroseconds( | 592 timestamp = base::TimeDelta::FromMicroseconds( |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() { | 696 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() { |
697 encoder_.Reset(); | 697 encoder_.Reset(); |
698 codec_api_.Reset(); | 698 codec_api_.Reset(); |
699 imf_input_media_type_.Reset(); | 699 imf_input_media_type_.Reset(); |
700 imf_output_media_type_.Reset(); | 700 imf_output_media_type_.Reset(); |
701 input_sample_.Reset(); | 701 input_sample_.Reset(); |
702 output_sample_.Reset(); | 702 output_sample_.Reset(); |
703 } | 703 } |
704 | 704 |
705 } // namespace content | 705 } // namespace content |
OLD | NEW |