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

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

Issue 825163004: Add Vaapi support on Ozone/Freon (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Created 5 years, 12 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 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 "content/common/gpu/media/vaapi_picture.h"
17 #include "third_party/libyuv/include/libyuv.h" 17 #include "third_party/libyuv/include/libyuv.h"
18 #include "ui/gl/gl_bindings.h" 18 #include "ui/gl/gl_bindings.h"
19 #if defined(USE_X11) 19 #if defined(USE_X11)
20 #include "ui/gfx/x/x11_types.h" 20 #include "ui/gfx/x/x11_types.h"
21 #elif defined(USE_OZONE)
22 #include "third_party/libva/va/drm/va_drm.h"
23 #include "third_party/libva/va/va_drmcommon.h"
Pawel Osciak 2014/12/26 00:38:56 Needed?
llandwerlin-old 2014/12/26 02:50:02 I can probably remove from here.
24 #include "ui/ozone/public/ozone_platform.h"
25 #include "ui/ozone/public/surface_factory_ozone.h"
21 #endif // USE_X11 26 #endif // USE_X11
22 27
23 using content_common_gpu_media::kModuleVa; 28 using content_common_gpu_media::kModuleVa;
24 #if defined(USE_X11) 29 #if defined(USE_X11)
25 using content_common_gpu_media::kModuleVa_x11; 30 using content_common_gpu_media::kModuleVa_x11;
31 #elif defined(USE_OZONE)
32 using content_common_gpu_media::kModuleVa_drm;
26 #endif // USE_X11 33 #endif // USE_X11
27 using content_common_gpu_media::InitializeStubs; 34 using content_common_gpu_media::InitializeStubs;
28 using content_common_gpu_media::StubPathMap; 35 using content_common_gpu_media::StubPathMap;
29 36
30 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ 37 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \
31 do { \ 38 do { \
32 LOG(ERROR) << err_msg \ 39 LOG(ERROR) << err_msg \
33 << " VA error: " << vaErrorStr(va_error); \ 40 << " VA error: " << vaErrorStr(va_error); \
34 report_error_to_uma_cb_.Run(); \ 41 report_error_to_uma_cb_.Run(); \
35 } while (0) 42 } while (0)
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 142 }
136 143
137 VASurface::~VASurface() { 144 VASurface::~VASurface() {
138 release_cb_.Run(va_surface_id_); 145 release_cb_.Run(va_surface_id_);
139 } 146 }
140 147
141 VaapiWrapper::VaapiWrapper() 148 VaapiWrapper::VaapiWrapper()
142 : va_display_(NULL), 149 : va_display_(NULL),
143 va_config_id_(VA_INVALID_ID), 150 va_config_id_(VA_INVALID_ID),
144 va_context_id_(VA_INVALID_ID), 151 va_context_id_(VA_INVALID_ID),
145 va_initialized_(false) { 152 va_initialized_(false),
153 va_vpp_config_id_(VA_INVALID_ID),
154 va_vpp_context_id_(VA_INVALID_ID),
155 va_vpp_buffer_id_(VA_INVALID_ID) {
146 } 156 }
147 157
148 VaapiWrapper::~VaapiWrapper() { 158 VaapiWrapper::~VaapiWrapper() {
149 DestroyPendingBuffers(); 159 DestroyPendingBuffers();
150 DestroyCodedBuffers(); 160 DestroyCodedBuffers();
151 DestroySurfaces(); 161 DestroySurfaces();
162 DeinitializeVpp();
152 Deinitialize(); 163 Deinitialize();
153 } 164 }
154 165
155 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( 166 scoped_ptr<VaapiWrapper> VaapiWrapper::Create(
156 CodecMode mode, 167 CodecMode mode,
157 media::VideoCodecProfile profile, 168 media::VideoCodecProfile profile,
158 const base::Closure& report_error_to_uma_cb) { 169 const base::Closure& report_error_to_uma_cb) {
159 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 170 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
160 171
161 if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb)) 172 if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb))
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 DVLOG(1) << kErrorMsg; 231 DVLOG(1) << kErrorMsg;
221 return false; 232 return false;
222 } 233 }
223 234
224 report_error_to_uma_cb_ = report_error_to_uma_cb; 235 report_error_to_uma_cb_ = report_error_to_uma_cb;
225 236
226 base::AutoLock auto_lock(va_lock_); 237 base::AutoLock auto_lock(va_lock_);
227 238
228 #if defined(USE_X11) 239 #if defined(USE_X11)
229 va_display_ = vaGetDisplay(gfx::GetXDisplay()); 240 va_display_ = vaGetDisplay(gfx::GetXDisplay());
241 #elif defined(USE_OZONE)
242 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
Pawel Osciak 2014/12/26 00:38:56 Please check return values.
llandwerlin-old 2014/12/26 02:50:02 Same as https://codereview.chromium.org/490233002/
243 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
244
245 va_display_ = vaGetDisplayDRM(factory->GetDrmFd());
230 #endif // USE_X11 246 #endif // USE_X11
231 247
232 if (!vaDisplayIsValid(va_display_)) { 248 if (!vaDisplayIsValid(va_display_)) {
233 LOG(ERROR) << "Could not get a valid VA display"; 249 LOG(ERROR) << "Could not get a valid VA display";
234 return false; 250 return false;
235 } 251 }
236 252
237 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 253 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_);
238 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 254 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false);
239 va_initialized_ = true; 255 va_initialized_ = true;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 if (!va_surface_ids_.empty()) { 454 if (!va_surface_ids_.empty()) {
439 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], 455 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0],
440 va_surface_ids_.size()); 456 va_surface_ids_.size());
441 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); 457 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed");
442 } 458 }
443 459
444 va_surface_ids_.clear(); 460 va_surface_ids_.clear();
445 va_context_id_ = VA_INVALID_ID; 461 va_context_id_ = VA_INVALID_ID;
446 } 462 }
447 463
464 scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface(
465 unsigned int va_format,
466 const gfx::Size& size,
467 VASurfaceAttrib* va_attribs,
468 size_t num_va_attribs) {
469 base::AutoLock auto_lock(va_lock_);
470 VASurfaceID va_surface_id;
471 scoped_refptr<VASurface> va_surface;
Pawel Osciak 2014/12/26 00:38:56 Please define variables at use site.
llandwerlin-old 2014/12/26 02:50:02 Done.
472
473 VAStatus va_res =
474 vaCreateSurfaces(va_display_, va_format, size.width(), size.height(),
475 &va_surface_id, 1, va_attribs, num_va_attribs);
476 VA_SUCCESS_OR_RETURN(va_res, "Failed to create unowned VASurface",
477 va_surface);
478
479 va_surface = new VASurface(va_surface_id, size,
480 base::Bind(&VaapiWrapper::DestroyUnownedSurface,
481 make_scoped_refptr(this)));
Pawel Osciak 2014/12/26 00:38:56 We can't do this. We can't have VaapiVDA keep a sc
llandwerlin-old 2014/12/26 02:50:02 Thanks, will change to Unretained.
482
483 return va_surface;
484 }
485
486 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface) {
487 base::AutoLock auto_lock(va_lock_);
488
489 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface, 1);
490 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on output surface failed");
Pawel Osciak 2014/12/26 00:38:56 s/output//
llandwerlin-old 2014/12/26 02:50:02 Done.
491 }
492
448 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, 493 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
449 size_t size, 494 size_t size,
450 void* buffer) { 495 void* buffer) {
451 base::AutoLock auto_lock(va_lock_); 496 base::AutoLock auto_lock(va_lock_);
452 497
453 VABufferID buffer_id; 498 VABufferID buffer_id;
454 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, 499 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_,
455 va_buffer_type, size, 500 va_buffer_type, size,
456 1, buffer, &buffer_id); 501 1, buffer, &buffer_id);
457 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); 502 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false);
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 795 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
751 796
752 va_res = vaDestroyBuffer(va_display_, buffer_id); 797 va_res = vaDestroyBuffer(va_display_, buffer_id);
753 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 798 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
754 799
755 DCHECK(coded_buffers_.erase(buffer_id)); 800 DCHECK(coded_buffers_.erase(buffer_id));
756 801
757 return buffer_segment == NULL; 802 return buffer_segment == NULL;
758 } 803 }
759 804
805 bool VaapiWrapper::BlitSurface(VASurfaceID va_surface_id_src,
806 const gfx::Size& src_size,
807 VASurfaceID va_surface_id_dest,
808 const gfx::Size& dest_size) {
809 base::AutoLock auto_lock(va_lock_);
810
811 // Initialize the post processing engine if not already done.
812 if (va_vpp_buffer_id_ == VA_INVALID_ID) {
Pawel Osciak 2014/12/26 00:38:56 Maybe just do this in Initialize() ?
llandwerlin-old 2014/12/26 02:50:02 That's up to you. The reason it's done lazily at t
Pawel Osciak 2014/12/29 00:08:00 Acknowledged.
813 if (!InitializeVpp_Locked())
814 return false;
815 }
816
817 VAProcPipelineParameterBuffer* pipeline_param;
818 VA_SUCCESS_OR_RETURN(vaMapBuffer(va_display_, va_vpp_buffer_id_,
819 reinterpret_cast<void**>(&pipeline_param)),
820 "Couldn't map vpp buffer", false);
821
822 memset(pipeline_param, 0, sizeof *pipeline_param);
823
824 VARectangle input_region;
825 input_region.x = input_region.y = 0;
826 input_region.width = src_size.width();
827 input_region.height = src_size.height();
828 pipeline_param->surface_region = &input_region;
829 pipeline_param->surface = va_surface_id_src;
830 pipeline_param->surface_color_standard = VAProcColorStandardNone;
831
832 VARectangle output_region;
833 output_region.x = output_region.y = 0;
834 output_region.width = dest_size.width();
835 output_region.height = dest_size.height();
836 pipeline_param->output_region = &output_region;
837 pipeline_param->output_background_color = 0xff000000;
Pawel Osciak 2014/12/26 00:38:56 Do we have a constant we could use here?
llandwerlin-old 2014/12/26 02:50:02 Not yet. I can add one here, let me know.
838 pipeline_param->output_color_standard = VAProcColorStandardNone;
839
840 VA_SUCCESS_OR_RETURN(vaUnmapBuffer(va_display_, va_vpp_buffer_id_),
841 "Couldn't unmap vpp buffer", false);
842
843 VA_SUCCESS_OR_RETURN(
844 vaBeginPicture(va_display_, va_vpp_context_id_, va_surface_id_dest),
845 "Couldn't begin picture", false);
846
847 VA_SUCCESS_OR_RETURN(
848 vaRenderPicture(va_display_, va_vpp_context_id_, &va_vpp_buffer_id_, 1),
849 "Couldn't render picture", false);
850
851 VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_id_),
852 "Couldn't end picture", false);
853
854 return true;
855 }
856
857 bool VaapiWrapper::InitializeVpp_Locked() {
858 va_lock_.AssertAcquired();
859
860 VA_SUCCESS_OR_RETURN(
861 vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc, NULL, 0,
862 &va_vpp_config_id_),
863 "Couldn't create config", false);
864
865 // The size of the picture for the context is irrelevant in the case
866 // of the VPP, just passing 1x1.
867 VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, va_vpp_config_id_, 1, 1, 0,
868 NULL, 0, &va_vpp_context_id_),
869 "Couldn't create context", false);
870
871 VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, va_vpp_context_id_,
872 VAProcPipelineParameterBufferType,
873 sizeof(VAProcPipelineParameterBuffer), 1,
874 NULL, &va_vpp_buffer_id_),
875 "Couldn't create buffer", false);
876
877 return true;
878 }
879
880 void VaapiWrapper::DeinitializeVpp() {
881 base::AutoLock auto_lock(va_lock_);
882
883 if (va_vpp_buffer_id_ != VA_INVALID_ID) {
884 vaDestroyBuffer(va_display_, va_vpp_buffer_id_);
885 va_vpp_buffer_id_ = VA_INVALID_ID;
886 }
887 if (va_vpp_context_id_ != VA_INVALID_ID) {
888 vaDestroyContext(va_display_, va_vpp_context_id_);
889 va_vpp_context_id_ = VA_INVALID_ID;
890 }
891 if (va_vpp_config_id_ != VA_INVALID_ID) {
892 vaDestroyConfig(va_display_, va_vpp_config_id_);
893 va_vpp_config_id_ = VA_INVALID_ID;
894 }
895 }
896
760 // static 897 // static
761 bool VaapiWrapper::PostSandboxInitialization() { 898 bool VaapiWrapper::PostSandboxInitialization() {
762 StubPathMap paths; 899 StubPathMap paths;
763 900
764 paths[kModuleVa].push_back("libva.so.1"); 901 paths[kModuleVa].push_back("libva.so.1");
765 902
766 #if defined(USE_X11) 903 #if defined(USE_X11)
767 paths[kModuleVa_x11].push_back("libva-x11.so.1"); 904 paths[kModuleVa_x11].push_back("libva-x11.so.1");
905 #elif defined(USE_OZONE)
906 paths[kModuleVa_drm].push_back("libva-drm.so.1");
768 #endif 907 #endif
769 908
770 return InitializeStubs(paths); 909 return InitializeStubs(paths);
771 } 910 }
772 911
773 } // namespace content 912 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698