| 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 |