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

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

Issue 2668293002: VPX HW encode using MediaFoundation
Patch Set: adding all Created 3 years, 10 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>
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/feature_list.h"
18 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/trace_event/trace_event.h" 20 #include "base/trace_event/trace_event.h"
20 #include "base/win/scoped_co_mem.h" 21 #include "base/win/scoped_co_mem.h"
21 #include "base/win/scoped_variant.h" 22 #include "base/win/scoped_variant.h"
22 #include "base/win/windows_version.h" 23 #include "base/win/windows_version.h"
24 #include "media/base/media_switches.h"
23 #include "media/base/win/mf_helpers.h" 25 #include "media/base/win/mf_helpers.h"
24 #include "media/base/win/mf_initializer.h" 26 #include "media/base/win/mf_initializer.h"
25 #include "third_party/libyuv/include/libyuv.h" 27 #include "third_party/libyuv/include/libyuv.h"
26 28
29 #undef DLOG
30 #define DLOG(err) LOG(ERROR)
31 #undef DVLOG
32 #define DVLOG(err) LOG(ERROR)
33
27 using base::win::ScopedComPtr; 34 using base::win::ScopedComPtr;
28 using media::mf::MediaBufferScopedPointer; 35 using media::mf::MediaBufferScopedPointer;
29 36
30 namespace media { 37 namespace media {
31 38
32 namespace { 39 namespace {
33 40
34 const int32_t kDefaultTargetBitrate = 5000000; 41 const int32_t kDefaultTargetBitrate = 5000000;
35 const size_t kMaxFrameRateNumerator = 30; 42 const size_t kMaxFrameRateNumerator = 30;
36 const size_t kMaxFrameRateDenominator = 1; 43 const size_t kMaxFrameRateDenominator = 1;
37 const size_t kMaxResolutionWidth = 1920; 44 const size_t kMaxResolutionWidth = 1920;
38 const size_t kMaxResolutionHeight = 1088; 45 const size_t kMaxResolutionHeight = 1088;
39 const size_t kNumInputBuffers = 3; 46 const size_t kNumInputBuffers = 3;
40 // Media Foundation uses 100 nanosecond units for time, see 47 // 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 48 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms697282(v=vs.85).as px
42 const size_t kOneMicrosecondInMFSampleTimeUnits = 10; 49 const size_t kOneMicrosecondInMFSampleTimeUnits = 10;
43 const size_t kOutputSampleBufferSizeRatio = 4; 50 const size_t kOutputSampleBufferSizeRatio = 4;
44 51
45 constexpr const wchar_t* const kMediaFoundationVideoEncoderDLLs[] = { 52 constexpr const wchar_t* const kMediaFoundationVideoEncoderDLLs[] = {
46 L"mf.dll", L"mfplat.dll", 53 L"mf.dll", L"mfplat.dll", L"nvEncMFTH264.dll",
47 }; 54 };
48 55
49 // Resolutions that some platforms support, should be listed in ascending order. 56 // Resolutions that some platforms support, should be listed in ascending order.
50 constexpr const gfx::Size kOptionalMaxResolutions[] = {gfx::Size(3840, 2176)}; 57 constexpr const gfx::Size kOptionalMaxResolutions[] = {gfx::Size(3840, 2176)};
51 58
59 constexpr const VideoCodecProfile kSupportedH264Profiles[] = {
60 H264PROFILE_BASELINE};
61 constexpr const VideoCodecProfile kSupportedVPXProfiles[] = {VP8PROFILE_MIN,
62 VP9PROFILE_MIN};
63
64 GUID VideoCodecProfileToGUID(VideoCodecProfile profile) {
65 switch (profile) {
66 case VP8PROFILE_MIN:
67 return MFVideoFormat_VP80;
68 case VP9PROFILE_MIN:
69 return MFVideoFormat_VP90;
70 case H264PROFILE_BASELINE:
71 return MFVideoFormat_H264;
72 default:
73 NOTREACHED();
74 return MFVideoFormat_VP80;
75 }
76 }
77
52 } // namespace 78 } // namespace
53 79
54 class MediaFoundationVideoEncodeAccelerator::EncodeOutput { 80 class MediaFoundationVideoEncodeAccelerator::EncodeOutput {
55 public: 81 public:
56 EncodeOutput(uint32_t size, bool key_frame, base::TimeDelta timestamp) 82 EncodeOutput(uint32_t size, bool key_frame, base::TimeDelta timestamp)
57 : keyframe(key_frame), capture_timestamp(timestamp), data_(size) {} 83 : keyframe(key_frame), capture_timestamp(timestamp), data_(size) {}
58 84
59 uint8_t* memory() { return data_.data(); } 85 uint8_t* memory() { return data_.data(); }
60 86
61 int size() const { return static_cast<int>(data_.size()); } 87 int size() const { return static_cast<int>(data_.size()); }
(...skipping 14 matching lines...) Expand all
76 : id(id), shm(std::move(shm)), size(size) {} 102 : id(id), shm(std::move(shm)), size(size) {}
77 const int32_t id; 103 const int32_t id;
78 const std::unique_ptr<base::SharedMemory> shm; 104 const std::unique_ptr<base::SharedMemory> shm;
79 const size_t size; 105 const size_t size;
80 106
81 private: 107 private:
82 DISALLOW_IMPLICIT_CONSTRUCTORS(BitstreamBufferRef); 108 DISALLOW_IMPLICIT_CONSTRUCTORS(BitstreamBufferRef);
83 }; 109 };
84 110
85 MediaFoundationVideoEncodeAccelerator::MediaFoundationVideoEncodeAccelerator() 111 MediaFoundationVideoEncodeAccelerator::MediaFoundationVideoEncodeAccelerator()
86 : main_client_task_runner_(base::ThreadTaskRunnerHandle::Get()), 112 : h264_enabled_(base::FeatureList::IsEnabled(kMediaFoundationH264Encoding)),
113 vpx_enabled_(base::FeatureList::IsEnabled(kMediaFoundationVPXEncoding)),
114 main_client_task_runner_(base::ThreadTaskRunnerHandle::Get()),
87 encoder_thread_("MFEncoderThread"), 115 encoder_thread_("MFEncoderThread"),
88 encoder_task_weak_factory_(this) {} 116 encoder_task_weak_factory_(this) {}
89 117
90 MediaFoundationVideoEncodeAccelerator:: 118 MediaFoundationVideoEncodeAccelerator::
91 ~MediaFoundationVideoEncodeAccelerator() { 119 ~MediaFoundationVideoEncodeAccelerator() {
92 DVLOG(3) << __func__; 120 DVLOG(3) << __func__;
93 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); 121 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
94 122
95 DCHECK(!encoder_thread_.IsRunning()); 123 DCHECK(!encoder_thread_.IsRunning());
96 DCHECK(!encoder_task_weak_factory_.HasWeakPtrs()); 124 DCHECK(!encoder_task_weak_factory_.HasWeakPtrs());
97 } 125 }
98 126
99 VideoEncodeAccelerator::SupportedProfiles 127 VideoEncodeAccelerator::SupportedProfiles
100 MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles() { 128 MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles() {
101 TRACE_EVENT0("gpu,startup", 129 TRACE_EVENT0("gpu,startup",
102 "MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles"); 130 "MediaFoundationVideoEncodeAccelerator::GetSupportedProfiles");
103 DVLOG(3) << __func__; 131 DVLOG(3) << __func__;
104 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); 132 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
105 133
106 SupportedProfiles profiles; 134 SupportedProfiles profiles;
107 target_bitrate_ = kDefaultTargetBitrate; 135 std::vector<VideoCodecProfile> candidate_codecs;
108 frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator; 136 if (h264_enabled_) {
109 input_visible_size_ = gfx::Size(kMaxResolutionWidth, kMaxResolutionHeight); 137 for (const auto codec : kSupportedH264Profiles)
110 if (!CreateHardwareEncoderMFT() || !SetEncoderModes() || 138 candidate_codecs.push_back(codec);
111 !InitializeInputOutputSamples()) { 139 }
112 ReleaseEncoderResources(); 140 if (vpx_enabled_) {
113 DVLOG(1) 141 for (const auto codec : kSupportedVPXProfiles)
114 << "Hardware encode acceleration is not available on this platform."; 142 candidate_codecs.push_back(codec);
115 return profiles;
116 } 143 }
117 144
118 gfx::Size highest_supported_resolution = input_visible_size_; 145 for (const auto codec : candidate_codecs) {
119 for (const auto& resolution : kOptionalMaxResolutions) { 146 output_profile_ = codec;
120 DCHECK_GT(resolution.GetArea(), highest_supported_resolution.GetArea()); 147 target_bitrate_ = kDefaultTargetBitrate;
121 if (!IsResolutionSupported(resolution)) 148 frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator;
122 break; 149 input_visible_size_ = gfx::Size(kMaxResolutionWidth, kMaxResolutionHeight);
123 highest_supported_resolution = resolution; 150 if (!CreateHardwareEncoderMFT() || !SetEncoderModes() ||
151 !InitializeInputOutputSamples()) {
152 ReleaseEncoderResources();
153 DVLOG(1) << "Hardware encode is not available on this platform for "
154 << GetProfileName(codec);
155 continue;
156 }
157
158 gfx::Size highest_supported_resolution = input_visible_size_;
159 for (const auto& resolution : kOptionalMaxResolutions) {
160 DCHECK_GT(resolution.GetArea(), highest_supported_resolution.GetArea());
161 if (!IsResolutionSupported(resolution))
162 break;
163 highest_supported_resolution = resolution;
164 }
165 ReleaseEncoderResources();
166
167 SupportedProfile profile;
168 // More profiles can be supported here, but they should be available in SW
169 // fallback as well.
170 profile.profile = codec;
171 DVLOG(1) << "Hardware encode IS available on this platform for "
172 << GetProfileName(codec);
173 LOG(ERROR) << highest_supported_resolution.ToString();
174 profile.max_framerate_numerator = kMaxFrameRateNumerator;
175 profile.max_framerate_denominator = kMaxFrameRateDenominator;
176 profile.max_resolution = highest_supported_resolution;
177 profiles.push_back(profile);
124 } 178 }
125 ReleaseEncoderResources();
126
127 SupportedProfile profile;
128 // More profiles can be supported here, but they should be available in SW
129 // fallback as well.
130 profile.profile = H264PROFILE_BASELINE;
131 profile.max_framerate_numerator = kMaxFrameRateNumerator;
132 profile.max_framerate_denominator = kMaxFrameRateDenominator;
133 profile.max_resolution = highest_supported_resolution;
134 profiles.push_back(profile);
135 return profiles; 179 return profiles;
136 } 180 }
137 181
138 bool MediaFoundationVideoEncodeAccelerator::Initialize( 182 bool MediaFoundationVideoEncodeAccelerator::Initialize(
139 VideoPixelFormat format, 183 VideoPixelFormat format,
140 const gfx::Size& input_visible_size, 184 const gfx::Size& input_visible_size,
141 VideoCodecProfile output_profile, 185 VideoCodecProfile output_profile,
142 uint32_t initial_bitrate, 186 uint32_t initial_bitrate,
143 Client* client) { 187 Client* client) {
144 DVLOG(3) << __func__ << ": input_format=" << VideoPixelFormatToString(format) 188 DVLOG(3) << __func__ << ": input_format=" << VideoPixelFormatToString(format)
145 << ", input_visible_size=" << input_visible_size.ToString() 189 << ", input_visible_size=" << input_visible_size.ToString()
146 << ", output_profile=" << output_profile 190 << ", output_profile=" << output_profile
147 << ", initial_bitrate=" << initial_bitrate; 191 << ", initial_bitrate=" << initial_bitrate;
148 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); 192 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
149 193
150 if (PIXEL_FORMAT_I420 != format) { 194 if (PIXEL_FORMAT_I420 != format) {
151 DLOG(ERROR) << "Input format not supported= " 195 DLOG(ERROR) << "Input format not supported= "
152 << VideoPixelFormatToString(format); 196 << VideoPixelFormatToString(format);
153 return false; 197 return false;
154 } 198 }
155 199
156 if (H264PROFILE_BASELINE != output_profile) { 200 if (!((H264PROFILE_BASELINE == output_profile && h264_enabled_) ||
201 ((VP8PROFILE_MIN == output_profile ||
202 VP9PROFILE_MIN == output_profile) &&
203 vpx_enabled_))) {
157 DLOG(ERROR) << "Output profile not supported= " << output_profile; 204 DLOG(ERROR) << "Output profile not supported= " << output_profile;
158 return false; 205 return false;
159 } 206 }
207 output_profile_ = output_profile;
160 208
161 encoder_thread_.init_com_with_mta(false); 209 encoder_thread_.init_com_with_mta(false);
162 if (!encoder_thread_.Start()) { 210 if (!encoder_thread_.Start()) {
163 DLOG(ERROR) << "Failed spawning encoder thread."; 211 DLOG(ERROR) << "Failed spawning encoder thread.";
164 return false; 212 return false;
165 } 213 }
166 encoder_thread_task_runner_ = encoder_thread_.task_runner(); 214 encoder_thread_task_runner_ = encoder_thread_.task_runner();
167 215
168 if (!CreateHardwareEncoderMFT()) { 216 if (!CreateHardwareEncoderMFT()) {
169 DLOG(ERROR) << "Failed creating a hardware encoder MFT."; 217 DLOG(ERROR) << "Failed creating a hardware encoder MFT.";
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 380
333 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) { 381 for (const wchar_t* mfdll : kMediaFoundationVideoEncoderDLLs) {
334 if (!::GetModuleHandle(mfdll)) { 382 if (!::GetModuleHandle(mfdll)) {
335 DVLOG(ERROR) << mfdll << " is required for encoding"; 383 DVLOG(ERROR) << mfdll << " is required for encoding";
336 return false; 384 return false;
337 } 385 }
338 } 386 }
339 387
340 InitializeMediaFoundation(); 388 InitializeMediaFoundation();
341 389
342 uint32_t flags = MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SORTANDFILTER; 390 uint32_t flags = MFT_ENUM_FLAG_SORTANDFILTER | MFT_ENUM_FLAG_SYNCMFT;
391 if (output_profile_ == H264PROFILE_BASELINE)
392 flags |= MFT_ENUM_FLAG_HARDWARE;
343 MFT_REGISTER_TYPE_INFO input_info; 393 MFT_REGISTER_TYPE_INFO input_info;
344 input_info.guidMajorType = MFMediaType_Video; 394 input_info.guidMajorType = MFMediaType_Video;
345 input_info.guidSubtype = MFVideoFormat_NV12; 395 input_info.guidSubtype = MFVideoFormat_NV12;
346 MFT_REGISTER_TYPE_INFO output_info; 396 MFT_REGISTER_TYPE_INFO output_info;
347 output_info.guidMajorType = MFMediaType_Video; 397 output_info.guidMajorType = MFMediaType_Video;
348 output_info.guidSubtype = MFVideoFormat_H264; 398 output_info.guidSubtype = VideoCodecProfileToGUID(output_profile_);
349 399
350 base::win::ScopedCoMem<CLSID> CLSIDs; 400 base::win::ScopedCoMem<IMFActivate*> devices;
351 uint32_t count = 0; 401 uint32_t count = 0;
352 HRESULT hr = MFTEnum(MFT_CATEGORY_VIDEO_ENCODER, flags, &input_info, 402 HRESULT hr = MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, flags, &input_info,
353 &output_info, NULL, &CLSIDs, &count); 403 &output_info, &devices, &count);
354 RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false); 404 RETURN_ON_HR_FAILURE(hr, "Couldn't enumerate hardware encoder", false);
355 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false); 405 RETURN_ON_FAILURE((count > 0), "No HW encoder found", false);
356 DVLOG(3) << "HW encoder(s) found: " << count; 406
357 hr = encoder_.CreateInstance(CLSIDs[0]); 407 bool succeeded = true;
358 RETURN_ON_HR_FAILURE(hr, "Couldn't activate hardware encoder", false); 408 if (count < 2) return false;
359 RETURN_ON_FAILURE((encoder_.get() != nullptr), 409 // hr = devices[0]->ActivateObject(IID_PPV_ARGS(encoder_.Receive()));
360 "No HW encoder instance created", false); 410 GUID guid = {0};
361 return true; 411 hr = devices[1]->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &guid);
412 LPOLESTR name;
413 StringFromCLSID(guid, &name);
414 LOG(ERROR) << __func__ << name;
415 RETURN_ON_HR_FAILURE(hr, "No HW encoder found", false);
416 hr = encoder_.CreateInstance(guid);
417
418 if (!SUCCEEDED(hr) || encoder_.get() == nullptr) {
419 DLOG(ERROR) << "Couldn't activate hardware encoder, HRESULT: 0x" << std::hex
420 << hr;
421 succeeded = false;
422 }
423 for (uint32_t i = 0; i < count; ++i)
424 devices[i]->Release();
425 return succeeded;
362 } 426 }
363 427
364 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() { 428 bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() {
365 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); 429 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
366 430
431 base::win::ScopedComPtr<IMFAttributes> attributes;
432 HRESULT hr = encoder_->GetAttributes(attributes.Receive());
433 RETURN_ON_HR_FAILURE(hr, "Couldn't get attributes", false);
434 hr = attributes->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
435 RETURN_ON_HR_FAILURE(hr, "Couldn't unlock", false);
436
367 DWORD input_count = 0; 437 DWORD input_count = 0;
368 DWORD output_count = 0; 438 DWORD output_count = 0;
369 HRESULT hr = encoder_->GetStreamCount(&input_count, &output_count); 439 hr = encoder_->GetStreamCount(&input_count, &output_count);
370 RETURN_ON_HR_FAILURE(hr, "Couldn't get stream count", false); 440 RETURN_ON_HR_FAILURE(hr, "Couldn't get stream count", false);
371 if (input_count < 1 || output_count < 1) { 441 if (input_count < 1 || output_count < 1) {
372 LOG(ERROR) << "Stream count too few: input " << input_count << ", output " 442 LOG(ERROR) << "Stream count too few: input " << input_count << ", output "
373 << output_count; 443 << output_count;
374 return false; 444 return false;
375 } 445 }
376 446
377 std::vector<DWORD> input_ids(input_count, 0); 447 std::vector<DWORD> input_ids(input_count, 0);
378 std::vector<DWORD> output_ids(output_count, 0); 448 std::vector<DWORD> output_ids(output_count, 0);
379 hr = encoder_->GetStreamIDs(input_count, input_ids.data(), output_count, 449 hr = encoder_->GetStreamIDs(input_count, input_ids.data(), output_count,
380 output_ids.data()); 450 output_ids.data());
381 if (hr == S_OK) { 451 if (hr == S_OK) {
382 input_stream_id_ = input_ids[0]; 452 input_stream_id_ = input_ids[0];
383 output_stream_id_ = output_ids[0]; 453 output_stream_id_ = output_ids[0];
384 } else if (hr == E_NOTIMPL) { 454 } else {
385 input_stream_id_ = 0; 455 input_stream_id_ = 0;
386 output_stream_id_ = 0; 456 output_stream_id_ = 0;
387 } else {
388 LOG(ERROR) << "Couldn't find stream ids.";
389 return false;
390 } 457 }
458 // } else if (hr == E_NOTIMPL) {
459 // input_stream_id_ = 0;
460 // output_stream_id_ = 0;
461 // } else {
462 // LOG(ERROR) << "Couldn't find stream ids, HRESULT: 0x" << std::hex <<
463 // hr;
464 // return false;
465 // }
391 466
392 // Initialize output parameters. 467 // Initialize output parameters.
393 hr = MFCreateMediaType(imf_output_media_type_.Receive()); 468 hr = MFCreateMediaType(imf_output_media_type_.Receive());
394 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); 469 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false);
395 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 470 hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
396 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); 471 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false);
397 hr = imf_output_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); 472 hr = imf_output_media_type_->SetGUID(
473 MF_MT_SUBTYPE, VideoCodecProfileToGUID(output_profile_));
398 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); 474 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false);
399 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); 475 hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_);
400 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); 476 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false);
401 hr = MFSetAttributeRatio(imf_output_media_type_.get(), MF_MT_FRAME_RATE, 477 hr = MFSetAttributeRatio(imf_output_media_type_.get(), MF_MT_FRAME_RATE,
402 frame_rate_, 1); 478 frame_rate_, 1);
403 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); 479 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false);
404 hr = MFSetAttributeSize(imf_output_media_type_.get(), MF_MT_FRAME_SIZE, 480 hr = MFSetAttributeSize(imf_output_media_type_.get(), MF_MT_FRAME_SIZE,
405 input_visible_size_.width(), 481 input_visible_size_.width(),
406 input_visible_size_.height()); 482 input_visible_size_.height());
407 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); 483 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false);
408 hr = imf_output_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, 484 hr = imf_output_media_type_->SetUINT32(MF_MT_INTERLACE_MODE,
409 MFVideoInterlace_Progressive); 485 MFVideoInterlace_Progressive);
410 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); 486 RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false);
411 hr = imf_output_media_type_->SetUINT32(MF_MT_MPEG2_PROFILE, 487 if (output_profile_ == H264PROFILE_BASELINE) {
412 eAVEncH264VProfile_Base); 488 hr = imf_output_media_type_->SetUINT32(MF_MT_MPEG2_PROFILE,
413 RETURN_ON_HR_FAILURE(hr, "Couldn't set codec profile", false); 489 eAVEncH264VProfile_Base);
490 RETURN_ON_HR_FAILURE(hr, "Couldn't set codec profile", false);
491 }
414 hr = encoder_->SetOutputType(output_stream_id_, imf_output_media_type_.get(), 492 hr = encoder_->SetOutputType(output_stream_id_, imf_output_media_type_.get(),
415 0); 493 0);
416 RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", false); 494 RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", false);
417 495
418 // Initialize input parameters. 496 // Initialize input parameters.
419 hr = MFCreateMediaType(imf_input_media_type_.Receive()); 497 hr = MFCreateMediaType(imf_input_media_type_.Receive());
420 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); 498 RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false);
421 hr = imf_input_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 499 hr = imf_input_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
422 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); 500 RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false);
423 hr = imf_input_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12); 501 hr = imf_input_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
424 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); 502 RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false);
425 hr = MFSetAttributeRatio(imf_input_media_type_.get(), MF_MT_FRAME_RATE, 503 hr = MFSetAttributeRatio(imf_input_media_type_.get(), MF_MT_FRAME_RATE,
426 frame_rate_, 1); 504 frame_rate_, 1);
427 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); 505 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false);
428 hr = MFSetAttributeSize(imf_input_media_type_.get(), MF_MT_FRAME_SIZE, 506 hr = MFSetAttributeSize(imf_input_media_type_.get(), MF_MT_FRAME_SIZE,
429 input_visible_size_.width(), 507 input_visible_size_.width(),
430 input_visible_size_.height()); 508 input_visible_size_.height());
431 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false); 509 RETURN_ON_HR_FAILURE(hr, "Couldn't set frame size", false);
432 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, 510 hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE,
433 MFVideoInterlace_Progressive); 511 MFVideoInterlace_Progressive);
(...skipping 12 matching lines...) Expand all
446 HRESULT hr = encoder_.QueryInterface(codec_api_.Receive()); 524 HRESULT hr = encoder_.QueryInterface(codec_api_.Receive());
447 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false); 525 RETURN_ON_HR_FAILURE(hr, "Couldn't get ICodecAPI", false);
448 VARIANT var; 526 VARIANT var;
449 var.vt = VT_UI4; 527 var.vt = VT_UI4;
450 var.ulVal = eAVEncCommonRateControlMode_CBR; 528 var.ulVal = eAVEncCommonRateControlMode_CBR;
451 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); 529 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var);
452 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false); 530 RETURN_ON_HR_FAILURE(hr, "Couldn't set CommonRateControlMode", false);
453 var.ulVal = target_bitrate_; 531 var.ulVal = target_bitrate_;
454 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); 532 hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var);
455 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); 533 RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false);
456 var.ulVal = eAVEncAdaptiveMode_Resolution;
457 hr = codec_api_->SetValue(&CODECAPI_AVEncAdaptiveMode, &var);
458 RETURN_ON_HR_FAILURE(hr, "Couldn't set FrameRate", false);
459 var.vt = VT_BOOL; 534 var.vt = VT_BOOL;
460 var.boolVal = VARIANT_TRUE; 535 var.boolVal = VARIANT_TRUE;
461 hr = codec_api_->SetValue(&CODECAPI_AVLowLatencyMode, &var); 536 hr = codec_api_->SetValue(&CODECAPI_AVLowLatencyMode, &var);
462 RETURN_ON_HR_FAILURE(hr, "Couldn't set LowLatencyMode", false); 537 RETURN_ON_HR_FAILURE(hr, "Couldn't set LowLatencyMode", false);
538 // if (output_profile_ == H264PROFILE_BASELINE) {
539 // var.ulVal = eAVEncAdaptiveMode_Resolution;
540 // hr = codec_api_->SetValue(&CODECAPI_AVEncAdaptiveMode, &var);
541 // RETURN_ON_HR_FAILURE(hr, "Couldn't set FrameRate", false);
542 // }
463 return SUCCEEDED(hr); 543 return SUCCEEDED(hr);
464 } 544 }
465 545
466 bool MediaFoundationVideoEncodeAccelerator::IsResolutionSupported( 546 bool MediaFoundationVideoEncodeAccelerator::IsResolutionSupported(
467 const gfx::Size& resolution) { 547 const gfx::Size& resolution) {
468 DCHECK(main_client_task_runner_->BelongsToCurrentThread()); 548 DCHECK(main_client_task_runner_->BelongsToCurrentThread());
469 DCHECK(encoder_); 549 DCHECK(encoder_);
470 550
471 HRESULT hr = 551 HRESULT hr =
472 MFSetAttributeSize(imf_output_media_type_.get(), MF_MT_FRAME_SIZE, 552 MFSetAttributeSize(imf_output_media_type_.get(), MF_MT_FRAME_SIZE,
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() { 775 void MediaFoundationVideoEncodeAccelerator::ReleaseEncoderResources() {
696 encoder_.Release(); 776 encoder_.Release();
697 codec_api_.Release(); 777 codec_api_.Release();
698 imf_input_media_type_.Release(); 778 imf_input_media_type_.Release();
699 imf_output_media_type_.Release(); 779 imf_output_media_type_.Release();
700 input_sample_.Release(); 780 input_sample_.Release();
701 output_sample_.Release(); 781 output_sample_.Release();
702 } 782 }
703 783
704 } // namespace content 784 } // 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