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

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

Issue 817023005: Reland: Refactor Vaapi video decoder/encoder in preparation of Freon support (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_wrapper.h" 5 #include "content/common/gpu/media/vaapi_wrapper.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
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/logging.h" 11 #include "base/logging.h"
12 #include "base/numerics/safe_conversions.h" 12 #include "base/numerics/safe_conversions.h"
13 #include "base/sys_info.h" 13 #include "base/sys_info.h"
14 // Auto-generated for dlopen libva libraries 14 // Auto-generated for dlopen libva libraries
15 #include "content/common/gpu/media/va_stubs.h" 15 #include "content/common/gpu/media/va_stubs.h"
16 #include "content/common/gpu/media/vaapi_picture.h"
16 #include "third_party/libyuv/include/libyuv.h" 17 #include "third_party/libyuv/include/libyuv.h"
18 #include "ui/gl/gl_bindings.h"
19 #if defined(USE_X11)
20 #include "ui/gfx/x/x11_types.h"
21 #endif // USE_X11
17 22
18 using content_common_gpu_media::kModuleVa; 23 using content_common_gpu_media::kModuleVa;
24 #if defined(USE_X11)
25 using content_common_gpu_media::kModuleVa_x11;
26 #endif // USE_X11
19 using content_common_gpu_media::InitializeStubs; 27 using content_common_gpu_media::InitializeStubs;
20 using content_common_gpu_media::StubPathMap; 28 using content_common_gpu_media::StubPathMap;
21 29
22 // libva-x11 depends on libva, so dlopen libva-x11 is enough
23 static const base::FilePath::CharType kVaLib[] =
24 FILE_PATH_LITERAL("libva-x11.so.1");
25
26 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ 30 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \
27 do { \ 31 do { \
28 LOG(ERROR) << err_msg \ 32 LOG(ERROR) << err_msg \
29 << " VA error: " << vaErrorStr(va_error); \ 33 << " VA error: " << vaErrorStr(va_error); \
30 report_error_to_uma_cb_.Run(); \ 34 report_error_to_uma_cb_.Run(); \
31 } while (0) 35 } while (0)
32 36
33 #define VA_LOG_ON_ERROR(va_error, err_msg) \ 37 #define VA_LOG_ON_ERROR(va_error, err_msg) \
34 do { \ 38 do { \
35 if ((va_error) != VA_STATUS_SUCCESS) \ 39 if ((va_error) != VA_STATUS_SUCCESS) \
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 VAProfileH264ConstrainedBaseline) != 120 VAProfileH264ConstrainedBaseline) !=
117 supported_profiles.end()) { 121 supported_profiles.end()) {
118 va_profile = VAProfileH264ConstrainedBaseline; 122 va_profile = VAProfileH264ConstrainedBaseline;
119 DVLOG(1) << "Falling back to constrained baseline profile."; 123 DVLOG(1) << "Falling back to constrained baseline profile.";
120 } 124 }
121 } 125 }
122 126
123 return va_profile; 127 return va_profile;
124 } 128 }
125 129
126 VASurface::VASurface(VASurfaceID va_surface_id, const ReleaseCB& release_cb) 130 VASurface::VASurface(VASurfaceID va_surface_id,
127 : va_surface_id_(va_surface_id), 131 const gfx::Size& size,
128 release_cb_(release_cb) { 132 const ReleaseCB& release_cb)
133 : va_surface_id_(va_surface_id), size_(size), release_cb_(release_cb) {
129 DCHECK(!release_cb_.is_null()); 134 DCHECK(!release_cb_.is_null());
130 } 135 }
131 136
132 VASurface::~VASurface() { 137 VASurface::~VASurface() {
133 release_cb_.Run(va_surface_id_); 138 release_cb_.Run(va_surface_id_);
134 } 139 }
135 140
136 VaapiWrapper::VaapiWrapper() 141 VaapiWrapper::VaapiWrapper()
137 : va_display_(NULL), 142 : va_display_(NULL),
138 va_config_id_(VA_INVALID_ID), 143 va_config_id_(VA_INVALID_ID),
139 va_context_id_(VA_INVALID_ID), 144 va_context_id_(VA_INVALID_ID),
140 va_initialized_(false) { 145 va_initialized_(false) {
141 } 146 }
142 147
143 VaapiWrapper::~VaapiWrapper() { 148 VaapiWrapper::~VaapiWrapper() {
144 DestroyPendingBuffers(); 149 DestroyPendingBuffers();
145 DestroyCodedBuffers(); 150 DestroyCodedBuffers();
146 DestroySurfaces(); 151 DestroySurfaces();
147 Deinitialize(); 152 Deinitialize();
148 } 153 }
149 154
150 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( 155 scoped_refptr<VaapiWrapper> VaapiWrapper::Create(
151 CodecMode mode, 156 CodecMode mode,
152 media::VideoCodecProfile profile, 157 media::VideoCodecProfile profile,
153 Display* x_display,
154 const base::Closure& report_error_to_uma_cb) { 158 const base::Closure& report_error_to_uma_cb) {
155 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 159 scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
156 160
157 if (!vaapi_wrapper->Initialize( 161 if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb))
158 mode, profile, x_display, report_error_to_uma_cb)) 162 vaapi_wrapper = NULL;
159 vaapi_wrapper.reset();
160 163
161 return vaapi_wrapper.Pass(); 164 return vaapi_wrapper;
162 } 165 }
163 166
164 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( 167 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles(
165 Display* x_display,
166 const base::Closure& report_error_to_uma_cb) { 168 const base::Closure& report_error_to_uma_cb) {
167 std::vector<media::VideoCodecProfile> supported_profiles; 169 std::vector<media::VideoCodecProfile> supported_profiles;
168 170
169 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); 171 scoped_refptr<VaapiWrapper> wrapper(new VaapiWrapper());
170 if (!wrapper->VaInitialize(x_display, report_error_to_uma_cb)) { 172 if (!wrapper->VaInitialize(report_error_to_uma_cb)) {
171 return supported_profiles; 173 return supported_profiles;
172 } 174 }
173 175
174 std::vector<VAProfile> va_profiles; 176 std::vector<VAProfile> va_profiles;
175 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) 177 if (!wrapper->GetSupportedVaProfiles(&va_profiles))
176 return supported_profiles; 178 return supported_profiles;
177 179
178 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); 180 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode);
179 for (size_t i = 0; i < arraysize(kProfileMap); i++) { 181 for (size_t i = 0; i < arraysize(kProfileMap); i++) {
180 VAProfile va_profile = 182 VAProfile va_profile =
(...skipping 14 matching lines...) Expand all
195 1, // At least support '_LOCAL_OVERLAY'. 197 1, // At least support '_LOCAL_OVERLAY'.
196 -1, // The maximum possible support 'ALL'. 198 -1, // The maximum possible support 'ALL'.
197 VA_RENDER_MODE_LOCAL_GPU, 199 VA_RENDER_MODE_LOCAL_GPU,
198 VA_DISPLAY_ATTRIB_SETTABLE}; 200 VA_DISPLAY_ATTRIB_SETTABLE};
199 201
200 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); 202 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
201 if (va_res != VA_STATUS_SUCCESS) 203 if (va_res != VA_STATUS_SUCCESS)
202 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; 204 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
203 } 205 }
204 206
205 bool VaapiWrapper::VaInitialize(Display* x_display, 207 bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) {
206 const base::Closure& report_error_to_uma_cb) {
207 static bool vaapi_functions_initialized = PostSandboxInitialization(); 208 static bool vaapi_functions_initialized = PostSandboxInitialization();
208 if (!vaapi_functions_initialized) { 209 if (!vaapi_functions_initialized) {
209 bool running_on_chromeos = false; 210 bool running_on_chromeos = false;
210 #if defined(OS_CHROMEOS) 211 #if defined(OS_CHROMEOS)
211 // When chrome runs on linux with chromeos=1, do not log error message 212 // When chrome runs on linux with chromeos=1, do not log error message
212 // without VAAPI libraries. 213 // without VAAPI libraries.
213 running_on_chromeos = base::SysInfo::IsRunningOnChromeOS(); 214 running_on_chromeos = base::SysInfo::IsRunningOnChromeOS();
214 #endif 215 #endif
215 static const char kErrorMsg[] = "Failed to initialize VAAPI libs"; 216 static const char kErrorMsg[] = "Failed to initialize VAAPI libs";
216 if (running_on_chromeos) 217 if (running_on_chromeos)
217 LOG(ERROR) << kErrorMsg; 218 LOG(ERROR) << kErrorMsg;
218 else 219 else
219 DVLOG(1) << kErrorMsg; 220 DVLOG(1) << kErrorMsg;
220 return false; 221 return false;
221 } 222 }
222 223
223 report_error_to_uma_cb_ = report_error_to_uma_cb; 224 report_error_to_uma_cb_ = report_error_to_uma_cb;
224 225
225 base::AutoLock auto_lock(va_lock_); 226 base::AutoLock auto_lock(va_lock_);
226 227
227 va_display_ = vaGetDisplay(x_display); 228 #if defined(USE_X11)
229 va_display_ = vaGetDisplay(gfx::GetXDisplay());
230 #endif // USE_X11
231
228 if (!vaDisplayIsValid(va_display_)) { 232 if (!vaDisplayIsValid(va_display_)) {
229 LOG(ERROR) << "Could not get a valid VA display"; 233 LOG(ERROR) << "Could not get a valid VA display";
230 return false; 234 return false;
231 } 235 }
232 236
233 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 237 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_);
234 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 238 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false);
235 va_initialized_ = true; 239 va_initialized_ = true;
236 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; 240 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
237 241
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 DVLOG(1) << "Unsupported value " << required_attribs[i].value 318 DVLOG(1) << "Unsupported value " << required_attribs[i].value
315 << " for attribute type " << required_attribs[i].type; 319 << " for attribute type " << required_attribs[i].type;
316 return false; 320 return false;
317 } 321 }
318 } 322 }
319 return true; 323 return true;
320 } 324 }
321 325
322 bool VaapiWrapper::Initialize(CodecMode mode, 326 bool VaapiWrapper::Initialize(CodecMode mode,
323 media::VideoCodecProfile profile, 327 media::VideoCodecProfile profile,
324 Display* x_display,
325 const base::Closure& report_error_to_uma_cb) { 328 const base::Closure& report_error_to_uma_cb) {
326 if (!VaInitialize(x_display, report_error_to_uma_cb)) 329 if (!VaInitialize(report_error_to_uma_cb))
327 return false; 330 return false;
328 std::vector<VAProfile> supported_va_profiles; 331 std::vector<VAProfile> supported_va_profiles;
329 if (!GetSupportedVaProfiles(&supported_va_profiles)) 332 if (!GetSupportedVaProfiles(&supported_va_profiles))
330 return false; 333 return false;
331 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); 334 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles);
332 if (va_profile == VAProfileNone) { 335 if (va_profile == VAProfileNone) {
333 DVLOG(1) << "Unsupported profile"; 336 DVLOG(1) << "Unsupported profile";
334 return false; 337 return false;
335 } 338 }
336 VAEntrypoint entrypoint = 339 VAEntrypoint entrypoint =
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 va_config_id_ = VA_INVALID_ID; 379 va_config_id_ = VA_INVALID_ID;
377 va_display_ = NULL; 380 va_display_ = NULL;
378 va_initialized_ = false; 381 va_initialized_ = false;
379 } 382 }
380 383
381 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { 384 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) {
382 return (major_version_ < major) || 385 return (major_version_ < major) ||
383 (major_version_ == major && minor_version_ < minor); 386 (major_version_ == major && minor_version_ < minor);
384 } 387 }
385 388
386 bool VaapiWrapper::CreateSurfaces(gfx::Size size, 389 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size,
387 size_t num_surfaces, 390 size_t num_surfaces,
388 std::vector<VASurfaceID>* va_surfaces) { 391 std::vector<VASurfaceID>* va_surfaces) {
389 base::AutoLock auto_lock(va_lock_); 392 base::AutoLock auto_lock(va_lock_);
390 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; 393 DVLOG(2) << "Creating " << num_surfaces << " surfaces";
391 394
392 DCHECK(va_surfaces->empty()); 395 DCHECK(va_surfaces->empty());
393 DCHECK(va_surface_ids_.empty()); 396 DCHECK(va_surface_ids_.empty());
394 va_surface_ids_.resize(num_surfaces); 397 va_surface_ids_.resize(num_surfaces);
395 398
396 // Allocate surfaces in driver. 399 // Allocate surfaces in driver.
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 589
587 return true; 590 return true;
588 } 591 }
589 592
590 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { 593 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
591 bool result = Execute(va_surface_id); 594 bool result = Execute(va_surface_id);
592 DestroyPendingBuffers(); 595 DestroyPendingBuffers();
593 return result; 596 return result;
594 } 597 }
595 598
596 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
597 Pixmap x_pixmap,
598 gfx::Size dest_size) {
599 base::AutoLock auto_lock(va_lock_);
600
601 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
602 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
603
604 // Put the data into an X Pixmap.
605 va_res = vaPutSurface(va_display_,
606 va_surface_id,
607 x_pixmap,
608 0, 0, dest_size.width(), dest_size.height(),
609 0, 0, dest_size.width(), dest_size.height(),
610 NULL, 0, 0);
611 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false);
612 return true;
613 }
614
615 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, 599 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id,
616 VAImage* image, 600 VAImage* image,
617 void** mem) { 601 void** mem) {
618 base::AutoLock auto_lock(va_lock_); 602 base::AutoLock auto_lock(va_lock_);
619 603
620 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); 604 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
621 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 605 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
622 606
623 // Derive a VAImage from the VASurface 607 // Derive a VAImage from the VASurface
624 va_res = vaDeriveImage(va_display_, va_surface_id, image); 608 va_res = vaDeriveImage(va_display_, va_surface_id, image);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 729 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
746 730
747 va_res = vaDestroyBuffer(va_display_, buffer_id); 731 va_res = vaDestroyBuffer(va_display_, buffer_id);
748 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 732 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
749 733
750 DCHECK(coded_buffers_.erase(buffer_id)); 734 DCHECK(coded_buffers_.erase(buffer_id));
751 735
752 return buffer_segment == NULL; 736 return buffer_segment == NULL;
753 } 737 }
754 738
739 #if defined(USE_X11)
740 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
Pawel Osciak 2014/12/20 20:46:51 Please don't move around things that don't change,
llandwerlin-old 2014/12/20 21:11:43 Acknowledged.
741 Pixmap x_pixmap,
742 gfx::Size dest_size) {
743 base::AutoLock auto_lock(va_lock_);
744
745 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
746 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
747
748 // Put the data into an X Pixmap.
749 va_res = vaPutSurface(va_display_, va_surface_id, x_pixmap, 0, 0,
750 dest_size.width(), dest_size.height(), 0, 0,
751 dest_size.width(), dest_size.height(), NULL, 0, 0);
752 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false);
753 return true;
754 }
755 #endif // USE_X11
756
755 // static 757 // static
756 bool VaapiWrapper::PostSandboxInitialization() { 758 bool VaapiWrapper::PostSandboxInitialization() {
757 StubPathMap paths; 759 StubPathMap paths;
758 paths[kModuleVa].push_back(kVaLib); 760
761 paths[kModuleVa].push_back("libva.so.1");
762
763 #if defined(USE_X11)
764 paths[kModuleVa_x11].push_back("libva-x11.so.1");
765 #endif
759 766
760 return InitializeStubs(paths); 767 return InitializeStubs(paths);
761 } 768 }
762 769
763 } // namespace content 770 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698