Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 | 5 |
| 6 #include <fcntl.h> | 6 #include <fcntl.h> |
| 7 #include <libdrm/drm_fourcc.h> | 7 #include <libdrm/drm_fourcc.h> |
| 8 #include <linux/videodev2.h> | 8 #include <linux/videodev2.h> |
| 9 #include <poll.h> | 9 #include <poll.h> |
| 10 #include <sys/eventfd.h> | 10 #include <sys/eventfd.h> |
| 11 #include <sys/ioctl.h> | 11 #include <sys/ioctl.h> |
| 12 #include <sys/mman.h> | 12 #include <sys/mman.h> |
| 13 | 13 |
| 14 #include "base/debug/trace_event.h" | 14 #include "base/debug/trace_event.h" |
| 15 #include "base/files/scoped_file.h" | 15 #include "base/files/scoped_file.h" |
| 16 #include "base/posix/eintr_wrapper.h" | 16 #include "base/posix/eintr_wrapper.h" |
| 17 #include "content/common/gpu/media/exynos_v4l2_video_device.h" | 17 #include "content/common/gpu/media/exynos_v4l2_video_device.h" |
| 18 #include "ui/gl/gl_bindings.h" | 18 #include "ui/gl/gl_bindings.h" |
| 19 | 19 |
| 20 #ifdef USE_LIBV4L2 | |
| 21 #include <libv4l2.h> | |
|
Pawel Osciak
2014/11/19 11:05:22
Please instead "third_party/v4l-utils/lib/include/
henryhsu
2014/11/20 05:11:58
Done.
| |
| 22 #include "content/common/gpu/media/v4l2_stubs.h" | |
| 23 | |
| 24 using content_common_gpu_media::kModuleV4l2; | |
| 25 using content_common_gpu_media::InitializeStubs; | |
| 26 using content_common_gpu_media::StubPathMap; | |
| 27 | |
| 28 static const base::FilePath::CharType kV4l2Lib[] = | |
| 29 FILE_PATH_LITERAL("libv4l2.so"); | |
| 30 #else | |
| 31 #define v4l2_close close | |
| 32 #define v4l2_ioctl ioctl | |
| 33 #endif | |
| 34 | |
| 20 namespace content { | 35 namespace content { |
| 21 | 36 |
| 22 namespace { | 37 namespace { |
| 23 const char kDecoderDevice[] = "/dev/mfc-dec"; | 38 const char kDecoderDevice[] = "/dev/mfc-dec"; |
| 24 const char kEncoderDevice[] = "/dev/mfc-enc"; | 39 const char kEncoderDevice[] = "/dev/mfc-enc"; |
| 25 const char kImageProcessorDevice[] = "/dev/gsc1"; | 40 const char kImageProcessorDevice[] = "/dev/gsc1"; |
| 26 } | 41 } |
| 27 | 42 |
| 28 ExynosV4L2Device::ExynosV4L2Device(Type type) | 43 ExynosV4L2Device::ExynosV4L2Device(Type type) |
| 29 : type_(type), | 44 : type_(type), |
| 30 device_fd_(-1), | 45 device_fd_(-1), |
| 31 device_poll_interrupt_fd_(-1) {} | 46 device_poll_interrupt_fd_(-1) { |
| 47 } | |
| 32 | 48 |
| 33 ExynosV4L2Device::~ExynosV4L2Device() { | 49 ExynosV4L2Device::~ExynosV4L2Device() { |
| 34 if (device_poll_interrupt_fd_ != -1) { | 50 if (device_poll_interrupt_fd_ != -1) { |
| 35 close(device_poll_interrupt_fd_); | 51 close(device_poll_interrupt_fd_); |
| 36 device_poll_interrupt_fd_ = -1; | 52 device_poll_interrupt_fd_ = -1; |
| 37 } | 53 } |
| 38 if (device_fd_ != -1) { | 54 if (device_fd_ != -1) { |
| 39 close(device_fd_); | 55 v4l2_close(device_fd_); |
| 40 device_fd_ = -1; | 56 device_fd_ = -1; |
| 41 } | 57 } |
| 42 } | 58 } |
| 43 | 59 |
| 44 int ExynosV4L2Device::Ioctl(int request, void* arg) { | 60 int ExynosV4L2Device::Ioctl(int request, void* arg) { |
| 45 return HANDLE_EINTR(ioctl(device_fd_, request, arg)); | 61 return HANDLE_EINTR(v4l2_ioctl(device_fd_, request, arg)); |
| 46 } | 62 } |
| 47 | 63 |
| 48 bool ExynosV4L2Device::Poll(bool poll_device, bool* event_pending) { | 64 bool ExynosV4L2Device::Poll(bool poll_device, bool* event_pending) { |
| 49 struct pollfd pollfds[2]; | 65 struct pollfd pollfds[2]; |
| 50 nfds_t nfds; | 66 nfds_t nfds; |
| 51 int pollfd = -1; | 67 int pollfd = -1; |
| 52 | 68 |
| 53 pollfds[0].fd = device_poll_interrupt_fd_; | 69 pollfds[0].fd = device_poll_interrupt_fd_; |
| 54 pollfds[0].events = POLLIN | POLLERR; | 70 pollfds[0].events = POLLIN | POLLERR; |
| 55 nfds = 1; | 71 nfds = 1; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 } else { | 120 } else { |
| 105 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed"; | 121 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed"; |
| 106 return false; | 122 return false; |
| 107 } | 123 } |
| 108 } | 124 } |
| 109 return true; | 125 return true; |
| 110 } | 126 } |
| 111 | 127 |
| 112 bool ExynosV4L2Device::Initialize() { | 128 bool ExynosV4L2Device::Initialize() { |
| 113 const char* device_path = NULL; | 129 const char* device_path = NULL; |
| 130 static bool v4l2_functions_initialized = PostSandboxInitialization(); | |
| 131 if (!v4l2_functions_initialized) { | |
| 132 LOG(ERROR) << "Failed to initialize LIBV4L2 libs"; | |
| 133 return false; | |
| 134 } | |
| 135 | |
| 114 switch (type_) { | 136 switch (type_) { |
| 115 case kDecoder: | 137 case kDecoder: |
| 116 device_path = kDecoderDevice; | 138 device_path = kDecoderDevice; |
| 117 break; | 139 break; |
| 118 case kEncoder: | 140 case kEncoder: |
| 119 device_path = kEncoderDevice; | 141 device_path = kEncoderDevice; |
| 120 break; | 142 break; |
| 121 case kImageProcessor: | 143 case kImageProcessor: |
| 122 device_path = kImageProcessorDevice; | 144 device_path = kImageProcessorDevice; |
| 123 break; | 145 break; |
| 124 } | 146 } |
| 125 | 147 |
| 126 DVLOG(2) << "Initialize(): opening device: " << device_path; | 148 DVLOG(2) << "Initialize(): opening device: " << device_path; |
| 127 // Open the video device. | 149 // Open the video device. |
| 128 device_fd_ = HANDLE_EINTR(open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC)); | 150 device_fd_ = HANDLE_EINTR(open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC)); |
| 129 if (device_fd_ == -1) { | 151 if (device_fd_ == -1) { |
| 130 return false; | 152 return false; |
| 131 } | 153 } |
| 154 #ifdef USE_LIBV4L2 | |
| 155 if (HANDLE_EINTR(v4l2_fd_open(device_fd_, V4L2_DISABLE_CONVERSION)) == -1) { | |
| 156 v4l2_close(device_fd_); | |
| 157 return false; | |
| 158 } | |
| 159 #endif | |
| 132 | 160 |
| 133 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); | 161 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); |
| 134 if (device_poll_interrupt_fd_ == -1) { | 162 if (device_poll_interrupt_fd_ == -1) { |
| 135 return false; | 163 return false; |
| 136 } | 164 } |
| 137 return true; | 165 return true; |
| 138 } | 166 } |
| 139 | 167 |
| 140 EGLImageKHR ExynosV4L2Device::CreateEGLImage(EGLDisplay egl_display, | 168 EGLImageKHR ExynosV4L2Device::CreateEGLImage(EGLDisplay egl_display, |
| 141 EGLContext /* egl_context */, | 169 EGLContext /* egl_context */, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 return V4L2_PIX_FMT_NV12M; | 229 return V4L2_PIX_FMT_NV12M; |
| 202 } | 230 } |
| 203 | 231 |
| 204 uint32 ExynosV4L2Device::PreferredOutputFormat() { | 232 uint32 ExynosV4L2Device::PreferredOutputFormat() { |
| 205 // TODO(posciak): We should support "dontcare" returns here once we | 233 // TODO(posciak): We should support "dontcare" returns here once we |
| 206 // implement proper handling (fallback, negotiation) for this in users. | 234 // implement proper handling (fallback, negotiation) for this in users. |
| 207 CHECK_EQ(type_, kDecoder); | 235 CHECK_EQ(type_, kDecoder); |
| 208 return V4L2_PIX_FMT_NV12M; | 236 return V4L2_PIX_FMT_NV12M; |
| 209 } | 237 } |
| 210 | 238 |
| 239 // static | |
| 240 bool ExynosV4L2Device::PostSandboxInitialization() { | |
| 241 #ifdef USE_LIBV4L2 | |
| 242 StubPathMap paths; | |
| 243 paths[kModuleV4l2].push_back(kV4l2Lib); | |
| 244 | |
| 245 return InitializeStubs(paths); | |
| 246 #else | |
| 247 return true; | |
| 248 #endif | |
| 249 } | |
| 250 | |
| 211 } // namespace content | 251 } // namespace content |
| OLD | NEW |