OLD | NEW |
---|---|
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" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 if (mode == VaapiWrapper::kEncode) { | 92 if (mode == VaapiWrapper::kEncode) { |
93 required_attribs.insert( | 93 required_attribs.insert( |
94 required_attribs.end(), | 94 required_attribs.end(), |
95 kEncodeVAConfigAttribs, | 95 kEncodeVAConfigAttribs, |
96 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); | 96 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); |
97 } | 97 } |
98 return required_attribs; | 98 return required_attribs; |
99 } | 99 } |
100 | 100 |
101 // Maps Profile enum values to VaProfile values. | 101 // Maps Profile enum values to VaProfile values. |
102 static VAProfile ProfileToVAProfile( | 102 static VAProfile ProfileToVAProfile(media::VideoCodecProfile profile) { |
103 media::VideoCodecProfile profile, | |
104 const std::vector<VAProfile>& supported_profiles) { | |
105 | |
106 VAProfile va_profile = VAProfileNone; | 103 VAProfile va_profile = VAProfileNone; |
107 for (size_t i = 0; i < arraysize(kProfileMap); i++) { | 104 for (size_t i = 0; i < arraysize(kProfileMap); i++) { |
108 if (kProfileMap[i].profile == profile) { | 105 if (kProfileMap[i].profile == profile) { |
109 va_profile = kProfileMap[i].va_profile; | 106 va_profile = kProfileMap[i].va_profile; |
110 break; | 107 break; |
111 } | 108 } |
112 } | 109 } |
110 return va_profile; | |
111 } | |
113 | 112 |
113 // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently strips | |
114 // the information whether the profile is constrained or not, so we have no | |
115 // way to know here. Try for baseline first, but if it is not supported, | |
116 // try constrained baseline and hope this is what it actually is | |
117 // (which in practice is true for a great majority of cases). | |
118 static VAProfile FallbackVaProfileIfNecessary( | |
119 VAProfile va_profile, | |
120 const std::vector<VAProfile>& supported_profiles) { | |
114 bool supported = std::find(supported_profiles.begin(), | 121 bool supported = std::find(supported_profiles.begin(), |
115 supported_profiles.end(), | 122 supported_profiles.end(), |
116 va_profile) != supported_profiles.end(); | 123 va_profile) != supported_profiles.end(); |
117 | 124 |
118 if (!supported && va_profile == VAProfileH264Baseline) { | 125 if (!supported && va_profile == VAProfileH264Baseline) { |
119 // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently strips | |
120 // the information whether the profile is constrained or not, so we have no | |
121 // way to know here. Try for baseline first, but if it is not supported, | |
122 // try constrained baseline and hope this is what it actually is | |
123 // (which in practice is true for a great majority of cases). | |
124 if (std::find(supported_profiles.begin(), | 126 if (std::find(supported_profiles.begin(), |
125 supported_profiles.end(), | 127 supported_profiles.end(), |
126 VAProfileH264ConstrainedBaseline) != | 128 VAProfileH264ConstrainedBaseline) != |
127 supported_profiles.end()) { | 129 supported_profiles.end()) { |
128 va_profile = VAProfileH264ConstrainedBaseline; | 130 va_profile = VAProfileH264ConstrainedBaseline; |
129 DVLOG(1) << "Falling back to constrained baseline profile."; | 131 DVLOG(1) << "Falling back to constrained baseline profile."; |
130 } | 132 } |
131 } | 133 } |
132 | 134 |
133 return va_profile; | 135 return va_profile; |
(...skipping 23 matching lines...) Expand all Loading... | |
157 VaapiWrapper::~VaapiWrapper() { | 159 VaapiWrapper::~VaapiWrapper() { |
158 DestroyPendingBuffers(); | 160 DestroyPendingBuffers(); |
159 DestroyCodedBuffers(); | 161 DestroyCodedBuffers(); |
160 DestroySurfaces(); | 162 DestroySurfaces(); |
161 DeinitializeVpp(); | 163 DeinitializeVpp(); |
162 Deinitialize(); | 164 Deinitialize(); |
163 } | 165 } |
164 | 166 |
165 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( | 167 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( |
166 CodecMode mode, | 168 CodecMode mode, |
167 media::VideoCodecProfile profile, | 169 VAProfile va_profile, |
168 const base::Closure& report_error_to_uma_cb) { | 170 const base::Closure& report_error_to_uma_cb) { |
169 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 171 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
170 | 172 |
171 if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb)) | 173 if (!vaapi_wrapper->Initialize(mode, va_profile, report_error_to_uma_cb)) |
172 vaapi_wrapper.reset(); | 174 return nullptr; |
173 | 175 |
174 return vaapi_wrapper.Pass(); | 176 return vaapi_wrapper.Pass(); |
175 } | 177 } |
176 | 178 |
179 scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec( | |
180 CodecMode mode, | |
181 media::VideoCodecProfile profile, | |
182 const base::Closure& report_error_to_uma_cb) { | |
183 VAProfile va_profile = ProfileToVAProfile(profile); | |
184 return Create(mode, va_profile, report_error_to_uma_cb); | |
185 } | |
186 | |
177 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( | 187 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( |
178 const base::Closure& report_error_to_uma_cb) { | 188 const base::Closure& report_error_to_uma_cb) { |
179 std::vector<media::VideoCodecProfile> supported_profiles; | 189 std::vector<media::VideoCodecProfile> supported_profiles; |
180 | 190 |
181 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); | 191 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); |
182 if (!wrapper->VaInitialize(report_error_to_uma_cb)) { | 192 if (!wrapper->VaInitialize(report_error_to_uma_cb)) { |
183 return supported_profiles; | 193 return supported_profiles; |
184 } | 194 } |
185 | 195 |
186 std::vector<VAProfile> va_profiles; | 196 std::vector<VAProfile> va_profiles; |
187 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) | 197 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) |
188 return supported_profiles; | 198 return supported_profiles; |
189 | 199 |
190 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); | 200 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); |
191 for (size_t i = 0; i < arraysize(kProfileMap); i++) { | 201 for (size_t i = 0; i < arraysize(kProfileMap); i++) { |
192 VAProfile va_profile = | 202 VAProfile va_profile = ProfileToVAProfile(kProfileMap[i].profile); |
193 ProfileToVAProfile(kProfileMap[i].profile, va_profiles); | 203 va_profile = FallbackVaProfileIfNecessary(va_profile, va_profiles); |
194 if (va_profile != VAProfileNone && | 204 if (va_profile != VAProfileNone && |
195 wrapper->IsEntrypointSupported(va_profile, VAEntrypointEncSlice) && | 205 wrapper->IsEntrypointSupported(va_profile, VAEntrypointEncSlice) && |
196 wrapper->AreAttribsSupported( | 206 wrapper->AreAttribsSupported( |
197 va_profile, VAEntrypointEncSlice, required_attribs)) { | 207 va_profile, VAEntrypointEncSlice, required_attribs)) { |
198 supported_profiles.push_back(kProfileMap[i].profile); | 208 supported_profiles.push_back(kProfileMap[i].profile); |
199 } | 209 } |
200 } | 210 } |
201 return supported_profiles; | 211 return supported_profiles; |
202 } | 212 } |
203 | 213 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 required_attribs[i].value) { | 342 required_attribs[i].value) { |
333 DVLOG(1) << "Unsupported value " << required_attribs[i].value | 343 DVLOG(1) << "Unsupported value " << required_attribs[i].value |
334 << " for attribute type " << required_attribs[i].type; | 344 << " for attribute type " << required_attribs[i].type; |
335 return false; | 345 return false; |
336 } | 346 } |
337 } | 347 } |
338 return true; | 348 return true; |
339 } | 349 } |
340 | 350 |
341 bool VaapiWrapper::Initialize(CodecMode mode, | 351 bool VaapiWrapper::Initialize(CodecMode mode, |
342 media::VideoCodecProfile profile, | 352 VAProfile va_profile, |
343 const base::Closure& report_error_to_uma_cb) { | 353 const base::Closure& report_error_to_uma_cb) { |
344 if (!VaInitialize(report_error_to_uma_cb)) | 354 if (!VaInitialize(report_error_to_uma_cb)) |
345 return false; | 355 return nullptr; |
wuchengli
2015/01/21 13:19:58
false
kcwu
2015/01/23 07:51:33
Done.
| |
346 std::vector<VAProfile> supported_va_profiles; | 356 std::vector<VAProfile> supported_va_profiles; |
347 if (!GetSupportedVaProfiles(&supported_va_profiles)) | 357 if (!GetSupportedVaProfiles(&supported_va_profiles)) |
348 return false; | 358 return nullptr; |
wuchengli
2015/01/21 13:19:58
false
kcwu
2015/01/23 07:51:33
Done.
| |
349 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); | 359 va_profile = FallbackVaProfileIfNecessary(va_profile, supported_va_profiles); |
350 if (va_profile == VAProfileNone) { | 360 if (va_profile == VAProfileNone) { |
351 DVLOG(1) << "Unsupported profile"; | 361 DVLOG(1) << "Unsupported profile"; |
352 return false; | 362 return false; |
353 } | 363 } |
354 VAEntrypoint entrypoint = | 364 VAEntrypoint entrypoint = |
355 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD); | 365 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD); |
356 if (!IsEntrypointSupported(va_profile, entrypoint)) | 366 if (!IsEntrypointSupported(va_profile, entrypoint)) |
357 return false; | 367 return false; |
358 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); | 368 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); |
359 if (!AreAttribsSupported(va_profile, entrypoint, required_attribs)) | 369 if (!AreAttribsSupported(va_profile, entrypoint, required_attribs)) |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
658 va_surface_id, | 668 va_surface_id, |
659 x_pixmap, | 669 x_pixmap, |
660 0, 0, dest_size.width(), dest_size.height(), | 670 0, 0, dest_size.width(), dest_size.height(), |
661 0, 0, dest_size.width(), dest_size.height(), | 671 0, 0, dest_size.width(), dest_size.height(), |
662 NULL, 0, 0); | 672 NULL, 0, 0); |
663 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | 673 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); |
664 return true; | 674 return true; |
665 } | 675 } |
666 #endif // USE_X11 | 676 #endif // USE_X11 |
667 | 677 |
668 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 678 bool VaapiWrapper::GetDerivedVaImage(VASurfaceID va_surface_id, |
669 VAImage* image, | 679 VAImage* image, |
670 void** mem) { | 680 void** mem) { |
671 base::AutoLock auto_lock(va_lock_); | 681 base::AutoLock auto_lock(va_lock_); |
672 | 682 |
673 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 683 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
674 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 684 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
675 | 685 |
676 // Derive a VAImage from the VASurface | 686 // Derive a VAImage from the VASurface |
677 va_res = vaDeriveImage(va_display_, va_surface_id, image); | 687 va_res = vaDeriveImage(va_display_, va_surface_id, image); |
678 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); | 688 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); |
679 if (va_res != VA_STATUS_SUCCESS) | 689 if (va_res != VA_STATUS_SUCCESS) |
680 return false; | 690 return false; |
681 | 691 |
682 // Map the VAImage into memory | 692 // Map the VAImage into memory |
683 va_res = vaMapBuffer(va_display_, image->buf, mem); | 693 va_res = vaMapBuffer(va_display_, image->buf, mem); |
684 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); | 694 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); |
685 if (va_res == VA_STATUS_SUCCESS) | 695 if (va_res == VA_STATUS_SUCCESS) |
686 return true; | 696 return true; |
687 | 697 |
688 va_res = vaDestroyImage(va_display_, image->image_id); | 698 va_res = vaDestroyImage(va_display_, image->image_id); |
689 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); | 699 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); |
690 | 700 |
691 return false; | 701 return false; |
692 } | 702 } |
693 | 703 |
694 void VaapiWrapper::ReturnVaImageForTesting(VAImage* image) { | 704 bool VaapiWrapper::GetVaImage(VASurfaceID va_surface_id, |
705 VAImageFormat* format, | |
706 const gfx::Size& size, | |
707 VAImage* image, | |
708 void** mem) { | |
709 base::AutoLock auto_lock(va_lock_); | |
710 | |
711 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
712 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
713 | |
714 va_res = | |
715 vaCreateImage(va_display_, format, size.width(), size.height(), image); | |
716 VA_SUCCESS_OR_RETURN(va_res, "vaCreateImage failed", false); | |
717 | |
718 va_res = vaGetImage(va_display_, va_surface_id, 0, 0, size.width(), | |
719 size.height(), image->image_id); | |
720 VA_LOG_ON_ERROR(va_res, "vaGetImage failed"); | |
721 | |
722 if (va_res == VA_STATUS_SUCCESS) { | |
723 // Map the VAImage into memory | |
724 va_res = vaMapBuffer(va_display_, image->buf, mem); | |
725 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); | |
726 } | |
727 | |
728 if (va_res != VA_STATUS_SUCCESS) { | |
729 va_res = vaDestroyImage(va_display_, image->image_id); | |
730 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); | |
731 return false; | |
732 } | |
733 | |
734 return true; | |
735 } | |
736 | |
737 void VaapiWrapper::ReturnVaImage(VAImage* image) { | |
695 base::AutoLock auto_lock(va_lock_); | 738 base::AutoLock auto_lock(va_lock_); |
696 | 739 |
697 VAStatus va_res = vaUnmapBuffer(va_display_, image->buf); | 740 VAStatus va_res = vaUnmapBuffer(va_display_, image->buf); |
698 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); | 741 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); |
699 | 742 |
700 va_res = vaDestroyImage(va_display_, image->image_id); | 743 va_res = vaDestroyImage(va_display_, image->image_id); |
701 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); | 744 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); |
702 } | 745 } |
703 | 746 |
704 static void DestroyVAImage(VADisplay va_display, VAImage image) { | 747 static void DestroyVAImage(VADisplay va_display, VAImage image) { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
906 #if defined(USE_X11) | 949 #if defined(USE_X11) |
907 paths[kModuleVa_x11].push_back("libva-x11.so.1"); | 950 paths[kModuleVa_x11].push_back("libva-x11.so.1"); |
908 #elif defined(USE_OZONE) | 951 #elif defined(USE_OZONE) |
909 paths[kModuleVa_drm].push_back("libva-drm.so.1"); | 952 paths[kModuleVa_drm].push_back("libva-drm.so.1"); |
910 #endif | 953 #endif |
911 | 954 |
912 return InitializeStubs(paths); | 955 return InitializeStubs(paths); |
913 } | 956 } |
914 | 957 |
915 } // namespace content | 958 } // namespace content |
OLD | NEW |