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

Side by Side Diff: media/filters/gpu_video_decoder.cc

Issue 795633005: Add VDA supported profile to GPUInfo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: edit description Created 6 years 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/filters/gpu_video_decoder.h" 5 #include "media/filters/gpu_video_decoder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/cpu.h"
13 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
15 #include "base/stl_util.h" 14 #include "base/stl_util.h"
16 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
17 #include "base/task_runner_util.h" 16 #include "base/task_runner_util.h"
18 #include "gpu/command_buffer/common/mailbox_holder.h" 17 #include "gpu/command_buffer/common/mailbox_holder.h"
19 #include "media/base/bind_to_current_loop.h" 18 #include "media/base/bind_to_current_loop.h"
20 #include "media/base/decoder_buffer.h" 19 #include "media/base/decoder_buffer.h"
21 #include "media/base/media_switches.h"
22 #include "media/base/pipeline.h" 20 #include "media/base/pipeline.h"
23 #include "media/base/pipeline_status.h" 21 #include "media/base/pipeline_status.h"
24 #include "media/base/video_decoder_config.h" 22 #include "media/base/video_decoder_config.h"
25 #include "media/filters/gpu_video_accelerator_factories.h" 23 #include "media/filters/gpu_video_accelerator_factories.h"
26 #include "third_party/skia/include/core/SkBitmap.h" 24 #include "third_party/skia/include/core/SkBitmap.h"
27 25
28 namespace media { 26 namespace media {
29 27
30 const char GpuVideoDecoder::kDecoderName[] = "GpuVideoDecoder"; 28 const char GpuVideoDecoder::kDecoderName[] = "GpuVideoDecoder";
31 29
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 base::MessageLoop::current()->PostTask(FROM_HERE, closure); 89 base::MessageLoop::current()->PostTask(FROM_HERE, closure);
92 return; 90 return;
93 } 91 }
94 92
95 DCHECK(pending_reset_cb_.is_null()); 93 DCHECK(pending_reset_cb_.is_null());
96 pending_reset_cb_ = BindToCurrentLoop(closure); 94 pending_reset_cb_ = BindToCurrentLoop(closure);
97 95
98 vda_->Reset(); 96 vda_->Reset();
99 } 97 }
100 98
101 static bool IsCodedSizeSupported(const gfx::Size& coded_size) {
102 #if defined(OS_WIN)
103 // Windows Media Foundation H.264 decoding does not support decoding videos
104 // with any dimension smaller than 48 pixels:
105 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815
106 if (coded_size.width() < 48 || coded_size.height() < 48)
107 return false;
108 #endif
109
110 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080.
111 // We test against 1088 to account for 16x16 macroblocks.
112 if (coded_size.width() <= 1920 && coded_size.height() <= 1088)
113 return true;
114
115 // NOTE: additional autodetection logic may require updating input buffer size
116 // selection in platform-specific implementations, such as
117 // V4L2VideoDecodeAccelerator.
118 base::CPU cpu;
119 bool hw_large_video_support =
120 CommandLine::ForCurrentProcess()->HasSwitch(
121 switches::kIgnoreResolutionLimitsForAcceleratedVideoDecode) ||
122 ((cpu.vendor_name() == "GenuineIntel") && cpu.model() >= 55);
123 bool os_large_video_support = true;
124 #if defined(OS_WIN)
125 os_large_video_support = false;
126 #endif
127 return os_large_video_support && hw_large_video_support;
128 }
129
130 // Report |status| to UMA and run |cb| with it. This is super-specific to the 99 // Report |status| to UMA and run |cb| with it. This is super-specific to the
131 // UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a 100 // UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a
132 // callsite to always be called with the same stat name (can't parameterize it). 101 // callsite to always be called with the same stat name (can't parameterize it).
133 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( 102 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB(
134 const PipelineStatusCB& cb, 103 const PipelineStatusCB& cb,
135 PipelineStatus status) { 104 PipelineStatus status) {
136 UMA_HISTOGRAM_ENUMERATION( 105 UMA_HISTOGRAM_ENUMERATION(
137 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); 106 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1);
138 cb.Run(status); 107 cb.Run(status);
139 } 108 }
(...skipping 20 matching lines...) Expand all
160 << config.AsHumanReadableString(); 129 << config.AsHumanReadableString();
161 130
162 // TODO(posciak): destroy and create a new VDA on codec/profile change 131 // TODO(posciak): destroy and create a new VDA on codec/profile change
163 // (http://crbug.com/260224). 132 // (http://crbug.com/260224).
164 if (previously_initialized && (config_.profile() != config.profile())) { 133 if (previously_initialized && (config_.profile() != config.profile())) {
165 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; 134 DVLOG(1) << "Codec or profile changed, cannot reinitialize.";
166 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 135 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
167 return; 136 return;
168 } 137 }
169 138
170 if (!IsCodedSizeSupported(config.coded_size())) { 139 if (!IsCodedSizeSupported(config.coded_size())) {
wuchengli 2014/12/19 03:35:18 Combine IsCodedSizeSupported and IsProfileSupporte
171 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 140 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
172 return; 141 return;
173 } 142 }
174 143
175 config_ = config; 144 config_ = config;
176 needs_bitstream_conversion_ = (config.codec() == kCodecH264); 145 needs_bitstream_conversion_ = (config.codec() == kCodecH264);
177 output_cb_ = BindToCurrentLoop(output_cb); 146 output_cb_ = BindToCurrentLoop(output_cb);
178 147
179 if (previously_initialized) { 148 if (previously_initialized) {
180 // Reinitialization with a different config (but same codec and profile). 149 // Reinitialization with a different config (but same codec and profile).
181 // VDA should handle it by detecting this in-stream by itself, 150 // VDA should handle it by detecting this in-stream by itself,
182 // no need to notify it. 151 // no need to notify it.
183 status_cb.Run(PIPELINE_OK); 152 status_cb.Run(PIPELINE_OK);
184 return; 153 return;
185 } 154 }
186 155
156 if (!IsProfileSupported(config.profile())) {
157 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
158 return;
159 }
160
187 vda_ = factories_->CreateVideoDecodeAccelerator().Pass(); 161 vda_ = factories_->CreateVideoDecodeAccelerator().Pass();
188 if (!vda_ || !vda_->Initialize(config.profile(), this)) { 162 if (!vda_ || !vda_->Initialize(config.profile(), this)) {
189 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 163 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
wuchengli 2014/12/19 03:35:18 PIPELINE_ERROR_INITIALIZATION_FAILED? Please find
190 return; 164 return;
191 } 165 }
192 166
193 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; 167 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded.";
194 status_cb.Run(PIPELINE_OK); 168 status_cb.Run(PIPELINE_OK);
195 } 169 }
196 170
197 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { 171 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) {
198 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 172 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
199 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); 173 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end();
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 590 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
617 if (!vda_) 591 if (!vda_)
618 return; 592 return;
619 593
620 state_ = kError; 594 state_ = kError;
621 595
622 DLOG(ERROR) << "VDA Error: " << error; 596 DLOG(ERROR) << "VDA Error: " << error;
623 DestroyVDA(); 597 DestroyVDA();
624 } 598 }
625 599
600 bool GpuVideoDecoder::IsCodedSizeSupported(const gfx::Size& coded_size) {
601 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
602 std::vector<VideoDecodeAccelerator::SupportedProfile> supported_profiles =
603 factories_->GetVideoDecodeAcceleratorSupportedProfiles();
604 for (size_t i = 0; i < supported_profiles.size(); i++) {
wuchengli 2014/12/19 03:35:18 You have to check the corresponding profile. You c
605 if (coded_size.width() <= supported_profiles[i].max_resolution.width() &&
606 coded_size.height() <= supported_profiles[i].max_resolution.height() &&
607 coded_size.width() >= supported_profiles[i].min_resolution.width() &&
608 coded_size.height() >= supported_profiles[i].min_resolution.height()) {
609 return true;
610 }
611 }
612 return false;
613 }
614
615 bool GpuVideoDecoder::IsProfileSupported(const VideoCodecProfile& profile) {
616 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
617 std::vector<VideoDecodeAccelerator::SupportedProfile> supported_profiles =
618 factories_->GetVideoDecodeAcceleratorSupportedProfiles();
619 for (size_t i = 0; i < supported_profiles.size(); i++) {
620 if (profile == supported_profiles[i].profile)
621 return true;
622 }
623 return false;
624 }
625
626 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() 626 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent()
627 const { 627 const {
628 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); 628 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread());
629 } 629 }
630 630
631 } // namespace media 631 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698