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

Side by Side Diff: media/gpu/tegra_v4l2_device.cc

Issue 2398883002: Add support for multiple V4L2 video devices of the same type. (Closed)
Patch Set: comments addressed Created 4 years, 2 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <dlfcn.h> 5 #include <dlfcn.h>
6 #include <fcntl.h> 6 #include <fcntl.h>
7 #include <linux/videodev2.h> 7 #include <linux/videodev2.h>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/posix/eintr_wrapper.h" 10 #include "base/posix/eintr_wrapper.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 TEGRAV4L2_SYM(Mmap); 49 TEGRAV4L2_SYM(Mmap);
50 TEGRAV4L2_SYM(Munmap); 50 TEGRAV4L2_SYM(Munmap);
51 TEGRAV4L2_SYM(UseEglImage); 51 TEGRAV4L2_SYM(UseEglImage);
52 52
53 #undef TEGRAV4L2_SYM 53 #undef TEGRAV4L2_SYM
54 54
55 class TegraFunctionSymbolFinder { 55 class TegraFunctionSymbolFinder {
56 public: 56 public:
57 TegraFunctionSymbolFinder() : initialized_(false) { 57 TegraFunctionSymbolFinder() : initialized_(false) {
58 if (!dlopen("/usr/lib/libtegrav4l2.so", 58 if (!dlopen("/usr/lib/libtegrav4l2.so",
59 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE)) { 59 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE))
60 DLOG(ERROR) << "Failed to load libtegrav4l2.so";
61 return; 60 return;
62 }
63 #define TEGRAV4L2_DLSYM_OR_RETURN_ON_ERROR(name) \ 61 #define TEGRAV4L2_DLSYM_OR_RETURN_ON_ERROR(name) \
64 do { \ 62 do { \
65 TegraV4L2_##name = reinterpret_cast<TegraV4L2##name>( \ 63 TegraV4L2_##name = reinterpret_cast<TegraV4L2##name>( \
66 dlsym(RTLD_DEFAULT, "TegraV4L2_" #name)); \ 64 dlsym(RTLD_DEFAULT, "TegraV4L2_" #name)); \
67 if (TegraV4L2_##name == NULL) { \ 65 if (TegraV4L2_##name == NULL) { \
68 LOG(ERROR) << "Failed to dlsym TegraV4L2_" #name; \ 66 LOG(ERROR) << "Failed to dlsym TegraV4L2_" #name; \
69 return; \ 67 return; \
70 } \ 68 } \
71 } while (0) 69 } while (0)
72 70
(...skipping 12 matching lines...) Expand all
85 83
86 bool initialized() { return initialized_; } 84 bool initialized() { return initialized_; }
87 85
88 private: 86 private:
89 bool initialized_; 87 bool initialized_;
90 }; 88 };
91 89
92 base::LazyInstance<TegraFunctionSymbolFinder> g_tegra_function_symbol_finder_ = 90 base::LazyInstance<TegraFunctionSymbolFinder> g_tegra_function_symbol_finder_ =
93 LAZY_INSTANCE_INITIALIZER; 91 LAZY_INSTANCE_INITIALIZER;
94 92
95 TegraV4L2Device::TegraV4L2Device(Type type) 93 TegraV4L2Device::TegraV4L2Device() {}
96 : V4L2Device(type), device_fd_(-1) {}
97 94
98 TegraV4L2Device::~TegraV4L2Device() { 95 TegraV4L2Device::~TegraV4L2Device() {
99 if (device_fd_ != -1) { 96 Close();
100 TegraV4L2_Close(device_fd_);
101 device_fd_ = -1;
102 }
103 } 97 }
104 98
105 int TegraV4L2Device::Ioctl(int flags, void* arg) { 99 int TegraV4L2Device::Ioctl(int flags, void* arg) {
106 return HANDLE_EINTR(TegraV4L2_Ioctl(device_fd_, flags, arg)); 100 return HANDLE_EINTR(TegraV4L2_Ioctl(device_fd_, flags, arg));
107 } 101 }
108 102
109 bool TegraV4L2Device::Poll(bool poll_device, bool* event_pending) { 103 bool TegraV4L2Device::Poll(bool poll_device, bool* event_pending) {
110 if (HANDLE_EINTR(TegraV4L2_Poll(device_fd_, poll_device, event_pending)) == 104 if (HANDLE_EINTR(TegraV4L2_Poll(device_fd_, poll_device, event_pending)) ==
111 -1) { 105 -1) {
112 LOG(ERROR) << "TegraV4L2Poll returned -1 "; 106 LOG(ERROR) << "TegraV4L2Poll returned -1 ";
(...skipping 24 matching lines...) Expand all
137 131
138 bool TegraV4L2Device::ClearDevicePollInterrupt() { 132 bool TegraV4L2Device::ClearDevicePollInterrupt() {
139 if (HANDLE_EINTR(TegraV4L2_ClearDevicePollInterrupt(device_fd_)) == -1) { 133 if (HANDLE_EINTR(TegraV4L2_ClearDevicePollInterrupt(device_fd_)) == -1) {
140 LOG(ERROR) << "Error in calling TegraV4L2ClearDevicePollInterrupt"; 134 LOG(ERROR) << "Error in calling TegraV4L2ClearDevicePollInterrupt";
141 return false; 135 return false;
142 } 136 }
143 return true; 137 return true;
144 } 138 }
145 139
146 bool TegraV4L2Device::Initialize() { 140 bool TegraV4L2Device::Initialize() {
147 const char* device_path = NULL; 141 return g_tegra_function_symbol_finder_.Get().initialized();
148 switch (type_) { 142 }
149 case kDecoder: 143
144 bool TegraV4L2Device::Open(Type type, uint32_t /* v4l2_pixfmt */) {
145 return OpenInternal(type);
146 }
147
148 bool TegraV4L2Device::OpenInternal(Type type) {
149 const char* device_path = nullptr;
150
151 switch (type) {
152 case Type::kDecoder:
150 device_path = kDecoderDevice; 153 device_path = kDecoderDevice;
151 break; 154 break;
152 case kEncoder: 155 case Type::kEncoder:
153 device_path = kEncoderDevice; 156 device_path = kEncoderDevice;
154 break; 157 break;
155 default: 158 default:
156 DVLOG(1) << "Device type " << type_ << " not supported on this platform"; 159 DVLOG(1) << "Device type " << static_cast<int>(type)
160 << " not supported on this platform";
157 return false; 161 return false;
158 } 162 }
159 163
160 if (!g_tegra_function_symbol_finder_.Get().initialized()) { 164 DCHECK_EQ(device_fd_, -1);
161 DLOG(ERROR) << "Unable to initialize functions";
162 return false;
163 }
164 device_fd_ = HANDLE_EINTR( 165 device_fd_ = HANDLE_EINTR(
165 TegraV4L2_Open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC)); 166 TegraV4L2_Open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC));
166 if (device_fd_ == -1) { 167 if (device_fd_ == -1) {
167 DLOG(ERROR) << "Unable to open device " << device_path; 168 DLOG(ERROR) << "Unable to open device " << device_path;
168 return false; 169 return false;
169 } 170 }
170 return true; 171 return true;
171 } 172 }
172 173
174 void TegraV4L2Device::Close() {
175 if (device_fd_ != -1) {
176 TegraV4L2_Close(device_fd_);
177 device_fd_ = -1;
178 }
179 }
180
173 std::vector<base::ScopedFD> TegraV4L2Device::GetDmabufsForV4L2Buffer( 181 std::vector<base::ScopedFD> TegraV4L2Device::GetDmabufsForV4L2Buffer(
174 int /* index */, 182 int /* index */,
175 size_t num_planes, 183 size_t num_planes,
176 enum v4l2_buf_type /* type */) { 184 enum v4l2_buf_type /* buf_type */) {
177 std::vector<base::ScopedFD> dmabuf_fds; 185 std::vector<base::ScopedFD> dmabuf_fds;
178 // Tegra does not actually provide dmabuf fds currently. Fill the vector with 186 // Tegra does not actually provide dmabuf fds currently. Fill the vector with
179 // invalid descriptors to prevent the caller from failing on an empty vector 187 // invalid descriptors to prevent the caller from failing on an empty vector
180 // being returned. TegraV4L2Device::CreateEGLImage() will ignore the invalid 188 // being returned. TegraV4L2Device::CreateEGLImage() will ignore the invalid
181 // descriptors and create images based on V4L2 index passed to it. 189 // descriptors and create images based on V4L2 index passed to it.
182 dmabuf_fds.resize(num_planes); 190 dmabuf_fds.resize(num_planes);
183 return dmabuf_fds; 191 return dmabuf_fds;
184 } 192 }
185 193
186 bool TegraV4L2Device::CanCreateEGLImageFrom(uint32_t v4l2_pixfmt) { 194 bool TegraV4L2Device::CanCreateEGLImageFrom(uint32_t v4l2_pixfmt) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 227
220 EGLBoolean TegraV4L2Device::DestroyEGLImage(EGLDisplay egl_display, 228 EGLBoolean TegraV4L2Device::DestroyEGLImage(EGLDisplay egl_display,
221 EGLImageKHR egl_image) { 229 EGLImageKHR egl_image) {
222 return eglDestroyImageKHR(egl_display, egl_image); 230 return eglDestroyImageKHR(egl_display, egl_image);
223 } 231 }
224 232
225 GLenum TegraV4L2Device::GetTextureTarget() { 233 GLenum TegraV4L2Device::GetTextureTarget() {
226 return GL_TEXTURE_2D; 234 return GL_TEXTURE_2D;
227 } 235 }
228 236
229 uint32_t TegraV4L2Device::PreferredInputFormat() { 237 uint32_t TegraV4L2Device::PreferredInputFormat(Type type) {
230 // TODO(posciak): We should support "dontcare" returns here once we 238 if (type == Type::kEncoder)
231 // implement proper handling (fallback, negotiation) for this in users. 239 return V4L2_PIX_FMT_YUV420M;
232 CHECK_EQ(type_, kEncoder); 240
233 return V4L2_PIX_FMT_YUV420M; 241 return 0;
242 }
243
244 std::vector<uint32_t> TegraV4L2Device::GetSupportedImageProcessorPixelformats(
245 v4l2_buf_type /* buf_type */) {
246 return std::vector<uint32_t>();
247 }
248
249 VideoDecodeAccelerator::SupportedProfiles
250 TegraV4L2Device::GetSupportedDecodeProfiles(const size_t num_formats,
251 const uint32_t pixelformats[]) {
252 if (!OpenInternal(Type::kDecoder))
253 return VideoDecodeAccelerator::SupportedProfiles();
254
255 const auto& profiles =
256 EnumerateSupportedDecodeProfiles(num_formats, pixelformats);
257
258 Close();
259 return profiles;
260 }
261
262 VideoEncodeAccelerator::SupportedProfiles
263 TegraV4L2Device::GetSupportedEncodeProfiles() {
264 if (!OpenInternal(Type::kEncoder))
265 return VideoEncodeAccelerator::SupportedProfiles();
266
267 const auto& profiles = EnumerateSupportedEncodeProfiles();
268
269 Close();
270 return profiles;
271 }
272
273 bool TegraV4L2Device::IsImageProcessingSupported() {
274 return false;
275 }
276
277 bool TegraV4L2Device::IsJpegDecodingSupported() {
278 return false;
234 } 279 }
235 280
236 } // namespace media 281 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/tegra_v4l2_device.h ('k') | media/gpu/v4l2_device.h » ('j') | media/gpu/v4l2_device.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698