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

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

Powered by Google App Engine
This is Rietveld 408576698