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

Side by Side Diff: content/common/gpu/media/vaapi_video_decode_accelerator.cc

Issue 385793002: content: Add support for Video Decode Acceleration on GBM (Closed) Base URL: 038ca4ab40c387bf3bc1541d56578bc522df9f41
Patch Set: merge changes into one single vaapi_video_decode_accelerator Created 6 years, 4 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
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 "content/common/gpu/media/vaapi_video_decode_accelerator.h"
6
7 #if !defined(USE_X11)
8 #include <gbm.h>
9 #endif
10
5 #include "base/bind.h" 11 #include "base/bind.h"
6 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
7 #include "base/logging.h" 13 #include "base/logging.h"
8 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
9 #include "base/stl_util.h" 15 #include "base/stl_util.h"
10 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
11 #include "base/synchronization/waitable_event.h" 17 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/non_thread_safe.h" 18 #include "base/threading/non_thread_safe.h"
13 #include "content/common/gpu/gpu_channel.h" 19 #include "content/common/gpu/gpu_channel.h"
14 #include "content/common/gpu/media/vaapi_video_decode_accelerator.h"
15 #include "media/base/bind_to_current_loop.h" 20 #include "media/base/bind_to_current_loop.h"
16 #include "media/video/picture.h" 21 #include "media/video/picture.h"
17 #include "ui/gl/gl_bindings.h" 22 #include "ui/gl/gl_bindings.h"
23 #if !defined(USE_X11)
24 #include "ui/gl/gl_surface_egl.h"
25 #endif
18 #include "ui/gl/scoped_binders.h" 26 #include "ui/gl/scoped_binders.h"
19 27
20 static void ReportToUMA( 28 static void ReportToUMA(
21 content::VaapiH264Decoder::VAVDAH264DecoderFailure failure) { 29 content::VaapiH264Decoder::VAVDAH264DecoderFailure failure) {
22 UMA_HISTOGRAM_ENUMERATION( 30 UMA_HISTOGRAM_ENUMERATION(
23 "Media.VAVDAH264.DecoderFailure", 31 "Media.VAVDAH264.DecoderFailure",
24 failure, 32 failure,
25 content::VaapiH264Decoder::VAVDA_H264_DECODER_FAILURES_MAX); 33 content::VaapiH264Decoder::VAVDA_H264_DECODER_FAILURES_MAX);
26 } 34 }
27 35
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 // at the end of decode (or when a new set of PictureBuffers is required). 75 // at the end of decode (or when a new set of PictureBuffers is required).
68 // 76 //
69 // TFPPictures are used for output, contents of VASurfaces passed from decoder 77 // TFPPictures are used for output, contents of VASurfaces passed from decoder
70 // are put into the associated pixmap memory and sent to client. 78 // are put into the associated pixmap memory and sent to client.
71 class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe { 79 class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe {
72 public: 80 public:
73 ~TFPPicture(); 81 ~TFPPicture();
74 82
75 static linked_ptr<TFPPicture> Create( 83 static linked_ptr<TFPPicture> Create(
76 const base::Callback<bool(void)>& make_context_current, 84 const base::Callback<bool(void)>& make_context_current,
85 #if defined(USE_X11)
77 const GLXFBConfig& fb_config, 86 const GLXFBConfig& fb_config,
78 Display* x_display, 87 Display* x_display,
88 #else
89 int fd,
90 VaapiWrapper* va_wrapper,
91 #endif
79 int32 picture_buffer_id, 92 int32 picture_buffer_id,
80 uint32 texture_id, 93 uint32 texture_id,
81 gfx::Size size); 94 gfx::Size size);
82 95
83 int32 picture_buffer_id() { 96 int32 picture_buffer_id() {
84 return picture_buffer_id_; 97 return picture_buffer_id_;
85 } 98 }
86 99
87 gfx::Size size() { 100 gfx::Size size() {
88 return size_; 101 return size_;
89 } 102 }
90 103 #if defined(USE_X11)
91 int x_pixmap() { 104 int x_pixmap() {
92 return x_pixmap_; 105 return x_pixmap_;
93 } 106 }
94 107
95 // Bind texture to pixmap. Needs to be called every frame. 108 // Bind texture to pixmap. Needs to be called every frame.
96 bool Bind(); 109 bool Bind();
110 #else
111 // Upload vaimage data to texture. Needs to be called every frame.
112 bool Upload(VASurfaceID id);
113 #endif
97 114
98 private: 115 private:
99 TFPPicture(const base::Callback<bool(void)>& make_context_current, 116 TFPPicture(const base::Callback<bool(void)>& make_context_current,
117 #if defined(USE_X11)
100 Display* x_display, 118 Display* x_display,
119 #else
120 int fd,
121 VaapiWrapper* va_wrapper,
122 #endif
101 int32 picture_buffer_id, 123 int32 picture_buffer_id,
102 uint32 texture_id, 124 uint32 texture_id,
103 gfx::Size size); 125 gfx::Size size);
104 126
127 #if defined(USE_X11)
105 bool Initialize(const GLXFBConfig& fb_config); 128 bool Initialize(const GLXFBConfig& fb_config);
106 129
107 base::Callback<bool(void)> make_context_current_; 130 base::Callback<bool(void)> make_context_current_;
108 131
109 Display* x_display_; 132 Display* x_display_;
133 #else
134 bool Initialize();
135
136 base::Callback<bool(void)> make_context_current_;
137
138 VaapiWrapper* va_wrapper_;
139 #endif
110 140
111 // Output id for the client. 141 // Output id for the client.
112 int32 picture_buffer_id_; 142 int32 picture_buffer_id_;
113 uint32 texture_id_; 143 uint32 texture_id_;
114 144
115 gfx::Size size_; 145 gfx::Size size_;
116 146 #if defined(USE_X11)
117 // Pixmaps bound to this texture. 147 // Pixmaps bound to this texture.
118 Pixmap x_pixmap_; 148 Pixmap x_pixmap_;
119 GLXPixmap glx_pixmap_; 149 GLXPixmap glx_pixmap_;
120 150 #else
151 VAImage va_image_;
152 #endif
121 DISALLOW_COPY_AND_ASSIGN(TFPPicture); 153 DISALLOW_COPY_AND_ASSIGN(TFPPicture);
122 }; 154 };
123 155
124 VaapiVideoDecodeAccelerator::TFPPicture::TFPPicture( 156 VaapiVideoDecodeAccelerator::TFPPicture::TFPPicture(
125 const base::Callback<bool(void)>& make_context_current, 157 const base::Callback<bool(void)>& make_context_current,
158 #if defined(USE_X11)
126 Display* x_display, 159 Display* x_display,
160 #else
161 int fd,
162 VaapiWrapper* va_wrapper,
163 #endif
127 int32 picture_buffer_id, 164 int32 picture_buffer_id,
128 uint32 texture_id, 165 uint32 texture_id,
129 gfx::Size size) 166 gfx::Size size)
130 : make_context_current_(make_context_current), 167 : make_context_current_(make_context_current),
168 #if defined(USE_X11)
131 x_display_(x_display), 169 x_display_(x_display),
170 x_pixmap_(0),
171 glx_pixmap_(0),
172 #else
173 va_wrapper_(va_wrapper),
174 #endif
132 picture_buffer_id_(picture_buffer_id), 175 picture_buffer_id_(picture_buffer_id),
133 texture_id_(texture_id), 176 texture_id_(texture_id),
134 size_(size), 177 size_(size) {
135 x_pixmap_(0),
136 glx_pixmap_(0) {
137 DCHECK(!make_context_current_.is_null()); 178 DCHECK(!make_context_current_.is_null());
138 }; 179 };
139 180
140 linked_ptr<VaapiVideoDecodeAccelerator::TFPPicture> 181 linked_ptr<VaapiVideoDecodeAccelerator::TFPPicture>
141 VaapiVideoDecodeAccelerator::TFPPicture::Create( 182 VaapiVideoDecodeAccelerator::TFPPicture::Create(
142 const base::Callback<bool(void)>& make_context_current, 183 const base::Callback<bool(void)>& make_context_current,
184 #if defined(USE_X11)
143 const GLXFBConfig& fb_config, 185 const GLXFBConfig& fb_config,
144 Display* x_display, 186 Display* x_display,
187 #else
188 int fd,
189 VaapiWrapper* va_wrapper,
190 #endif
145 int32 picture_buffer_id, 191 int32 picture_buffer_id,
146 uint32 texture_id, 192 uint32 texture_id,
147 gfx::Size size) { 193 gfx::Size size) {
148 194
149 linked_ptr<TFPPicture> tfp_picture( 195 linked_ptr<TFPPicture> tfp_picture(
150 new TFPPicture(make_context_current, x_display, picture_buffer_id, 196 new TFPPicture(make_context_current,
151 texture_id, size)); 197 #if defined(USE_X11)
152 198 x_display,
199 #else
200 fd,
201 va_wrapper,
202 #endif
203 picture_buffer_id,
204 texture_id,
205 size));
206 #if defined(USE_X11)
153 if (!tfp_picture->Initialize(fb_config)) 207 if (!tfp_picture->Initialize(fb_config))
208 #else
209 if (!tfp_picture->Initialize())
210 #endif
154 tfp_picture.reset(); 211 tfp_picture.reset();
155 212
156 return tfp_picture; 213 return tfp_picture;
157 } 214 }
158 215
216 #if defined(USE_X11)
159 bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize( 217 bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize(
160 const GLXFBConfig& fb_config) { 218 const GLXFBConfig& fb_config) {
219 #else
220 bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize() {
221 #endif
161 DCHECK(CalledOnValidThread()); 222 DCHECK(CalledOnValidThread());
162 if (!make_context_current_.Run()) 223 if (!make_context_current_.Run())
163 return false; 224 return false;
164 225 #if defined(USE_X11)
165 XWindowAttributes win_attr; 226 XWindowAttributes win_attr;
166 int screen = DefaultScreen(x_display_); 227 int screen = DefaultScreen(x_display_);
167 XGetWindowAttributes(x_display_, RootWindow(x_display_, screen), &win_attr); 228 XGetWindowAttributes(x_display_, RootWindow(x_display_, screen), &win_attr);
168 //TODO(posciak): pass the depth required by libva, not the RootWindow's depth 229 //TODO(posciak): pass the depth required by libva, not the RootWindow's depth
169 x_pixmap_ = XCreatePixmap(x_display_, RootWindow(x_display_, screen), 230 x_pixmap_ = XCreatePixmap(x_display_, RootWindow(x_display_, screen),
170 size_.width(), size_.height(), win_attr.depth); 231 size_.width(), size_.height(), win_attr.depth);
171 if (!x_pixmap_) { 232 if (!x_pixmap_) {
172 DVLOG(1) << "Failed creating an X Pixmap for TFP"; 233 DVLOG(1) << "Failed creating an X Pixmap for TFP";
173 return false; 234 return false;
174 } 235 }
175 236
176 static const int pixmap_attr[] = { 237 static const int pixmap_attr[] = {
177 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, 238 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
178 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, 239 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
179 GL_NONE, 240 GL_NONE,
180 }; 241 };
181 242
182 glx_pixmap_ = glXCreatePixmap(x_display_, fb_config, x_pixmap_, pixmap_attr); 243 glx_pixmap_ = glXCreatePixmap(x_display_, fb_config, x_pixmap_, pixmap_attr);
183 if (!glx_pixmap_) { 244 if (!glx_pixmap_) {
184 // x_pixmap_ will be freed in the destructor. 245 // x_pixmap_ will be freed in the destructor.
185 DVLOG(1) << "Failed creating a GLX Pixmap for TFP"; 246 DVLOG(1) << "Failed creating a GLX Pixmap for TFP";
186 return false; 247 return false;
187 } 248 }
188 249 #else
250 if (!va_wrapper_->CreateRGBImage(size_, &va_image_)) {
251 DVLOG(1) << "Failed to create VAImage";
252 return false;
253 }
254 #endif
189 return true; 255 return true;
190 } 256 }
191 257
192 VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() { 258 VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() {
193 DCHECK(CalledOnValidThread()); 259 DCHECK(CalledOnValidThread());
260 #if defined(USE_X11)
194 // Unbind surface from texture and deallocate resources. 261 // Unbind surface from texture and deallocate resources.
195 if (glx_pixmap_ && make_context_current_.Run()) { 262 if (glx_pixmap_ && make_context_current_.Run()) {
196 glXReleaseTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT); 263 glXReleaseTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT);
197 glXDestroyPixmap(x_display_, glx_pixmap_); 264 glXDestroyPixmap(x_display_, glx_pixmap_);
198 } 265 }
199 266
200 if (x_pixmap_) 267 if (x_pixmap_)
201 XFreePixmap(x_display_, x_pixmap_); 268 XFreePixmap(x_display_, x_pixmap_);
202 XSync(x_display_, False); // Needed to work around buggy vdpau-driver. 269 XSync(x_display_, False); // Needed to work around buggy vdpau-driver.
270 #else
271 if (va_wrapper_)
272 va_wrapper_->DestroyImage(&va_image_);
273 #endif
203 } 274 }
204 275
276 #if defined(USE_X11)
205 bool VaapiVideoDecodeAccelerator::TFPPicture::Bind() { 277 bool VaapiVideoDecodeAccelerator::TFPPicture::Bind() {
206 DCHECK(CalledOnValidThread()); 278 DCHECK(CalledOnValidThread());
207 DCHECK(x_pixmap_); 279 DCHECK(x_pixmap_);
208 DCHECK(glx_pixmap_); 280 DCHECK(glx_pixmap_);
209 if (!make_context_current_.Run()) 281 if (!make_context_current_.Run())
210 return false; 282 return false;
211 283
212 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_); 284 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_);
213 glXBindTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); 285 glXBindTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
214 286
215 return true; 287 return true;
216 } 288 }
289 #else
290 bool VaapiVideoDecodeAccelerator::TFPPicture::Upload(VASurfaceID surface) {
291 DCHECK(CalledOnValidThread());
292 if (!make_context_current_.Run())
293 return false;
294
295
296 if (!va_wrapper_->PutSurfaceIntoImage(surface, &va_image_)) {
297 DVLOG(1) << "Failed to put va surface to image";
298 return false;
299 }
300
301 void* buffer = NULL;
302 if (!va_wrapper_->MapImage(&va_image_, &buffer)) {
303 DVLOG(1) << "Failed to map VAImage";
304 return false;
305 }
306
307 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_);
308 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
309 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
310 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(),
311 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
marcheu 2014/08/07 01:26:25 This is a synchronous, CPU-side copy. This copy do
vignatti (out of this project) 2014/08/12 08:19:02 FYI point taken. We are working on that.
312
313 va_wrapper_->UnmapImage(&va_image_);
314
315 return true;
316 }
317 #endif
217 318
218 VaapiVideoDecodeAccelerator::TFPPicture* 319 VaapiVideoDecodeAccelerator::TFPPicture*
219 VaapiVideoDecodeAccelerator::TFPPictureById(int32 picture_buffer_id) { 320 VaapiVideoDecodeAccelerator::TFPPictureById(int32 picture_buffer_id) {
220 TFPPictures::iterator it = tfp_pictures_.find(picture_buffer_id); 321 TFPPictures::iterator it = tfp_pictures_.find(picture_buffer_id);
221 if (it == tfp_pictures_.end()) { 322 if (it == tfp_pictures_.end()) {
222 DVLOG(1) << "Picture id " << picture_buffer_id << " does not exist"; 323 DVLOG(1) << "Picture id " << picture_buffer_id << " does not exist";
223 return NULL; 324 return NULL;
224 } 325 }
225 326
226 return it->second.get(); 327 return it->second.get();
227 } 328 }
228 329
229 VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( 330 VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
331 #if defined(USE_X11)
230 Display* x_display, 332 Display* x_display,
333 #endif
231 const base::Callback<bool(void)>& make_context_current) 334 const base::Callback<bool(void)>& make_context_current)
335 #if defined(USE_X11)
232 : x_display_(x_display), 336 : x_display_(x_display),
337 #else
338 : fd_(0),
339 #endif
233 make_context_current_(make_context_current), 340 make_context_current_(make_context_current),
234 state_(kUninitialized), 341 state_(kUninitialized),
235 input_ready_(&lock_), 342 input_ready_(&lock_),
236 surfaces_available_(&lock_), 343 surfaces_available_(&lock_),
237 message_loop_(base::MessageLoop::current()), 344 message_loop_(base::MessageLoop::current()),
238 decoder_thread_("VaapiDecoderThread"), 345 decoder_thread_("VaapiDecoderThread"),
239 num_frames_at_client_(0), 346 num_frames_at_client_(0),
240 num_stream_bufs_at_decoder_(0), 347 num_stream_bufs_at_decoder_(0),
241 finish_flush_pending_(false), 348 finish_flush_pending_(false),
242 awaiting_va_surfaces_recycle_(false), 349 awaiting_va_surfaces_recycle_(false),
243 requested_num_pics_(0), 350 requested_num_pics_(0),
244 weak_this_factory_(this) { 351 weak_this_factory_(this) {
245 weak_this_ = weak_this_factory_.GetWeakPtr(); 352 weak_this_ = weak_this_factory_.GetWeakPtr();
246 va_surface_release_cb_ = media::BindToCurrentLoop( 353 va_surface_release_cb_ = media::BindToCurrentLoop(
247 base::Bind(&VaapiVideoDecodeAccelerator::RecycleVASurfaceID, weak_this_)); 354 base::Bind(&VaapiVideoDecodeAccelerator::RecycleVASurfaceID, weak_this_));
248 } 355 }
249 356
250 VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() { 357 VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() {
251 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 358 DCHECK_EQ(message_loop_, base::MessageLoop::current());
359 #if !defined(USE_X11)
360 fd_ = 0;
361 #endif
252 } 362 }
253 363
364 #if defined(USE_X11)
254 class XFreeDeleter { 365 class XFreeDeleter {
255 public: 366 public:
256 void operator()(void* x) const { 367 void operator()(void* x) const {
257 ::XFree(x); 368 ::XFree(x);
258 } 369 }
259 }; 370 };
260 371
261 bool VaapiVideoDecodeAccelerator::InitializeFBConfig() { 372 bool VaapiVideoDecodeAccelerator::InitializeFBConfig() {
262 const int fbconfig_attr[] = { 373 const int fbconfig_attr[] = {
263 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, 374 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
264 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, 375 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
265 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, 376 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE,
266 GLX_Y_INVERTED_EXT, GL_TRUE, 377 GLX_Y_INVERTED_EXT, GL_TRUE,
267 GL_NONE, 378 GL_NONE,
268 }; 379 };
269 380
270 int num_fbconfigs; 381 int num_fbconfigs;
271 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs( 382 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(
272 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, 383 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr,
273 &num_fbconfigs)); 384 &num_fbconfigs));
274 if (!glx_fb_configs) 385 if (!glx_fb_configs)
275 return false; 386 return false;
276 if (!num_fbconfigs) 387 if (!num_fbconfigs)
277 return false; 388 return false;
278 389
279 fb_config_ = glx_fb_configs.get()[0]; 390 fb_config_ = glx_fb_configs.get()[0];
280 return true; 391 return true;
281 } 392 }
393 #endif
282 394
283 bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, 395 bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
284 Client* client) { 396 Client* client) {
285 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 397 DCHECK_EQ(message_loop_, base::MessageLoop::current());
286 398
287 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); 399 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
288 client_ = client_ptr_factory_->GetWeakPtr(); 400 client_ = client_ptr_factory_->GetWeakPtr();
289 401
290 base::AutoLock auto_lock(lock_); 402 base::AutoLock auto_lock(lock_);
291 DCHECK_EQ(state_, kUninitialized); 403 DCHECK_EQ(state_, kUninitialized);
292 DVLOG(2) << "Initializing VAVDA, profile: " << profile; 404 DVLOG(2) << "Initializing VAVDA, profile: " << profile;
293 405
294 if (!make_context_current_.Run()) 406 if (!make_context_current_.Run())
295 return false; 407 return false;
296 408
409 #if defined(USE_X11)
297 if (!InitializeFBConfig()) { 410 if (!InitializeFBConfig()) {
298 DVLOG(1) << "Could not get a usable FBConfig"; 411 DVLOG(1) << "Could not get a usable FBConfig";
299 return false; 412 return false;
300 } 413 }
414 #else
415 gbm_device* device = NULL;
416 device = reinterpret_cast<gbm_device*>(
417 gfx::GetPlatformDefaultEGLNativeDisplay());
418 fd_ = gbm_device_get_fd(device);
419 if (!fd_) {
420 DVLOG(1) << "Could not get a usable DRM device";
421 return false;
422 }
423 #endif
301 424
302 vaapi_wrapper_ = VaapiWrapper::Create( 425 vaapi_wrapper_ = VaapiWrapper::Create(
303 VaapiWrapper::kDecode, 426 VaapiWrapper::kDecode,
304 profile, 427 profile,
428 #if defined(USE_X11)
305 x_display_, 429 x_display_,
430 #else
431 fd_,
432 #endif
306 base::Bind(&ReportToUMA, content::VaapiH264Decoder::VAAPI_ERROR)); 433 base::Bind(&ReportToUMA, content::VaapiH264Decoder::VAAPI_ERROR));
307 434
308 if (!vaapi_wrapper_.get()) { 435 if (!vaapi_wrapper_.get()) {
309 DVLOG(1) << "Failed initializing VAAPI"; 436 DVLOG(1) << "Failed initializing VAAPI";
310 return false; 437 return false;
311 } 438 }
312 439
313 decoder_.reset( 440 decoder_.reset(
314 new VaapiH264Decoder( 441 new VaapiH264Decoder(
315 vaapi_wrapper_.get(), 442 vaapi_wrapper_.get(),
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 475 DCHECK_EQ(message_loop_, base::MessageLoop::current());
349 476
350 int32 output_id = tfp_picture->picture_buffer_id(); 477 int32 output_id = tfp_picture->picture_buffer_id();
351 478
352 TRACE_EVENT2("Video Decoder", "VAVDA::OutputSurface", 479 TRACE_EVENT2("Video Decoder", "VAVDA::OutputSurface",
353 "input_id", input_id, 480 "input_id", input_id,
354 "output_id", output_id); 481 "output_id", output_id);
355 482
356 DVLOG(3) << "Outputting VASurface " << va_surface->id() 483 DVLOG(3) << "Outputting VASurface " << va_surface->id()
357 << " into pixmap bound to picture buffer id " << output_id; 484 << " into pixmap bound to picture buffer id " << output_id;
358 485 #if defined(USE_X11)
359 RETURN_AND_NOTIFY_ON_FAILURE(tfp_picture->Bind(), 486 RETURN_AND_NOTIFY_ON_FAILURE(tfp_picture->Bind(),
360 "Failed binding texture to pixmap", 487 "Failed binding texture to pixmap",
361 PLATFORM_FAILURE, ); 488 PLATFORM_FAILURE, );
362 489
363 RETURN_AND_NOTIFY_ON_FAILURE( 490 RETURN_AND_NOTIFY_ON_FAILURE(
364 vaapi_wrapper_->PutSurfaceIntoPixmap(va_surface->id(), 491 vaapi_wrapper_->PutSurfaceIntoPixmap(va_surface->id(),
365 tfp_picture->x_pixmap(), 492 tfp_picture->x_pixmap(),
366 tfp_picture->size()), 493 tfp_picture->size()),
367 "Failed putting surface into pixmap", PLATFORM_FAILURE, ); 494 "Failed putting surface into pixmap", PLATFORM_FAILURE, );
368 495 #else
496 RETURN_AND_NOTIFY_ON_FAILURE(
497 tfp_picture->Upload(va_surface->id()),
498 "Failed putting surface into pixmap", PLATFORM_FAILURE, );
499 #endif
369 // Notify the client a picture is ready to be displayed. 500 // Notify the client a picture is ready to be displayed.
370 ++num_frames_at_client_; 501 ++num_frames_at_client_;
371 TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_); 502 TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_);
372 DVLOG(4) << "Notifying output picture id " << output_id 503 DVLOG(4) << "Notifying output picture id " << output_id
373 << " for input "<< input_id << " is ready"; 504 << " for input "<< input_id << " is ready";
374 if (client_) 505 if (client_)
375 client_->PictureReady(media::Picture(output_id, input_id)); 506 client_->PictureReady(media::Picture(output_id, input_id));
376 } 507 }
377 508
378 void VaapiVideoDecodeAccelerator::TryOutputSurface() { 509 void VaapiVideoDecodeAccelerator::TryOutputSurface() {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 561
431 bool VaapiVideoDecodeAccelerator::GetInputBuffer_Locked() { 562 bool VaapiVideoDecodeAccelerator::GetInputBuffer_Locked() {
432 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread()); 563 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
433 lock_.AssertAcquired(); 564 lock_.AssertAcquired();
434 565
435 if (curr_input_buffer_.get()) 566 if (curr_input_buffer_.get())
436 return true; 567 return true;
437 568
438 // Will only wait if it is expected that in current state new buffers will 569 // Will only wait if it is expected that in current state new buffers will
439 // be queued from the client via Decode(). The state can change during wait. 570 // be queued from the client via Decode(). The state can change during wait.
440 while (input_buffers_.empty() && (state_ == kDecoding || state_ == kIdle)) { 571 while (input_buffers_.empty() && (state_ == kDecoding || state_ == kIdle))
441 input_ready_.Wait(); 572 input_ready_.Wait();
442 }
443 573
444 // We could have got woken up in a different state or never got to sleep 574 // We could have got woken up in a different state or never got to sleep
445 // due to current state; check for that. 575 // due to current state; check for that.
446 switch (state_) { 576 switch (state_) {
447 case kFlushing: 577 case kFlushing:
448 // Here we are only interested in finishing up decoding buffers that are 578 // Here we are only interested in finishing up decoding buffers that are
449 // already queued up. Otherwise will stop decoding. 579 // already queued up. Otherwise will stop decoding.
450 if (input_buffers_.empty()) 580 if (input_buffers_.empty())
451 return false; 581 return false;
452 // else fallthrough 582 // else fallthrough
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 --num_stream_bufs_at_decoder_; 617 --num_stream_bufs_at_decoder_;
488 TRACE_COUNTER1("Video Decoder", "Stream buffers at decoder", 618 TRACE_COUNTER1("Video Decoder", "Stream buffers at decoder",
489 num_stream_bufs_at_decoder_); 619 num_stream_bufs_at_decoder_);
490 } 620 }
491 621
492 bool VaapiVideoDecodeAccelerator::FeedDecoderWithOutputSurfaces_Locked() { 622 bool VaapiVideoDecodeAccelerator::FeedDecoderWithOutputSurfaces_Locked() {
493 lock_.AssertAcquired(); 623 lock_.AssertAcquired();
494 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread()); 624 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
495 625
496 while (available_va_surfaces_.empty() && 626 while (available_va_surfaces_.empty() &&
497 (state_ == kDecoding || state_ == kFlushing || state_ == kIdle)) { 627 (state_ == kDecoding || state_ == kFlushing || state_ == kIdle))
498 surfaces_available_.Wait(); 628 surfaces_available_.Wait();
499 }
500 629
501 if (state_ != kDecoding && state_ != kFlushing && state_ != kIdle) 630 if (state_ != kDecoding && state_ != kFlushing && state_ != kIdle)
502 return false; 631 return false;
503 632
504 while (!available_va_surfaces_.empty()) { 633 while (!available_va_surfaces_.empty()) {
505 scoped_refptr<VASurface> va_surface( 634 scoped_refptr<VASurface> va_surface(
506 new VASurface(available_va_surfaces_.front(), va_surface_release_cb_)); 635 new VASurface(available_va_surfaces_.front(), va_surface_release_cb_));
507 available_va_surfaces_.pop_front(); 636 available_va_surfaces_.pop_front();
508 decoder_->ReuseSurface(va_surface); 637 decoder_->ReuseSurface(va_surface);
509 } 638 }
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 &va_surface_ids), 826 &va_surface_ids),
698 "Failed creating VA Surfaces", PLATFORM_FAILURE, ); 827 "Failed creating VA Surfaces", PLATFORM_FAILURE, );
699 DCHECK_EQ(va_surface_ids.size(), buffers.size()); 828 DCHECK_EQ(va_surface_ids.size(), buffers.size());
700 829
701 for (size_t i = 0; i < buffers.size(); ++i) { 830 for (size_t i = 0; i < buffers.size(); ++i) {
702 DVLOG(2) << "Assigning picture id: " << buffers[i].id() 831 DVLOG(2) << "Assigning picture id: " << buffers[i].id()
703 << " to texture id: " << buffers[i].texture_id() 832 << " to texture id: " << buffers[i].texture_id()
704 << " VASurfaceID: " << va_surface_ids[i]; 833 << " VASurfaceID: " << va_surface_ids[i];
705 834
706 linked_ptr<TFPPicture> tfp_picture( 835 linked_ptr<TFPPicture> tfp_picture(
707 TFPPicture::Create(make_context_current_, fb_config_, x_display_, 836 TFPPicture::Create(make_context_current_,
708 buffers[i].id(), buffers[i].texture_id(), 837 #if defined(USE_X11)
838 fb_config_,
839 x_display_,
840 #else
841 fd_,
842 vaapi_wrapper_.get(),
843 #endif
844 buffers[i].id(),
845 buffers[i].texture_id(),
709 requested_pic_size_)); 846 requested_pic_size_));
710 847
711 RETURN_AND_NOTIFY_ON_FAILURE( 848 RETURN_AND_NOTIFY_ON_FAILURE(
712 tfp_picture.get(), "Failed assigning picture buffer to a texture.", 849 tfp_picture.get(), "Failed assigning picture buffer to a texture.",
713 PLATFORM_FAILURE, ); 850 PLATFORM_FAILURE, );
714 851
715 bool inserted = tfp_pictures_.insert(std::make_pair( 852 bool inserted = tfp_pictures_.insert(std::make_pair(
716 buffers[i].id(), tfp_picture)).second; 853 buffers[i].id(), tfp_picture)).second;
717 DCHECK(inserted); 854 DCHECK(inserted);
718 855
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 1051 DCHECK_EQ(message_loop_, base::MessageLoop::current());
915 Cleanup(); 1052 Cleanup();
916 delete this; 1053 delete this;
917 } 1054 }
918 1055
919 bool VaapiVideoDecodeAccelerator::CanDecodeOnIOThread() { 1056 bool VaapiVideoDecodeAccelerator::CanDecodeOnIOThread() {
920 return false; 1057 return false;
921 } 1058 }
922 1059
923 } // namespace content 1060 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/vaapi_video_decode_accelerator.h ('k') | content/common/gpu/media/vaapi_wrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698