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

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

Issue 730693005: Generalize V4L2 HW video codec device names (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years 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 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/generic_v4l2_video_device.h"
18 #include "ui/gl/gl_bindings.h" 18 #include "ui/gl/gl_bindings.h"
19 19
20 namespace content { 20 namespace content {
21 21
22 namespace { 22 namespace {
23 const char kDecoderDevice[] = "/dev/mfc-dec"; 23 const char kDecoderDevice[] = "/dev/video-dec";
24 const char kEncoderDevice[] = "/dev/mfc-enc"; 24 const char kEncoderDevice[] = "/dev/video-enc";
25 const char kImageProcessorDevice[] = "/dev/gsc1"; 25 const char kImageProcessorDevice[] = "/dev/gsc1";
26 } 26 }
27 27
28 ExynosV4L2Device::ExynosV4L2Device(Type type) 28 GenericV4L2Device::GenericV4L2Device(Type type)
29 : type_(type), 29 : type_(type),
30 device_fd_(-1), 30 device_fd_(-1),
31 device_poll_interrupt_fd_(-1) {} 31 device_poll_interrupt_fd_(-1) {}
32 32
33 ExynosV4L2Device::~ExynosV4L2Device() { 33 GenericV4L2Device::~GenericV4L2Device() {
34 if (device_poll_interrupt_fd_ != -1) { 34 if (device_poll_interrupt_fd_ != -1) {
35 close(device_poll_interrupt_fd_); 35 close(device_poll_interrupt_fd_);
36 device_poll_interrupt_fd_ = -1; 36 device_poll_interrupt_fd_ = -1;
37 } 37 }
38 if (device_fd_ != -1) { 38 if (device_fd_ != -1) {
39 close(device_fd_); 39 close(device_fd_);
40 device_fd_ = -1; 40 device_fd_ = -1;
41 } 41 }
42 } 42 }
43 43
44 int ExynosV4L2Device::Ioctl(int request, void* arg) { 44 int GenericV4L2Device::Ioctl(int request, void* arg) {
45 return HANDLE_EINTR(ioctl(device_fd_, request, arg)); 45 return HANDLE_EINTR(ioctl(device_fd_, request, arg));
46 } 46 }
47 47
48 bool ExynosV4L2Device::Poll(bool poll_device, bool* event_pending) { 48 bool GenericV4L2Device::Poll(bool poll_device, bool* event_pending) {
49 struct pollfd pollfds[2]; 49 struct pollfd pollfds[2];
50 nfds_t nfds; 50 nfds_t nfds;
51 int pollfd = -1; 51 int pollfd = -1;
52 52
53 pollfds[0].fd = device_poll_interrupt_fd_; 53 pollfds[0].fd = device_poll_interrupt_fd_;
54 pollfds[0].events = POLLIN | POLLERR; 54 pollfds[0].events = POLLIN | POLLERR;
55 nfds = 1; 55 nfds = 1;
56 56
57 if (poll_device) { 57 if (poll_device) {
58 DVLOG(3) << "Poll(): adding device fd to poll() set"; 58 DVLOG(3) << "Poll(): adding device fd to poll() set";
59 pollfds[nfds].fd = device_fd_; 59 pollfds[nfds].fd = device_fd_;
60 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI; 60 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI;
61 pollfd = nfds; 61 pollfd = nfds;
62 nfds++; 62 nfds++;
63 } 63 }
64 64
65 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) { 65 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) {
66 DPLOG(ERROR) << "poll() failed"; 66 DPLOG(ERROR) << "poll() failed";
67 return false; 67 return false;
68 } 68 }
69 *event_pending = (pollfd != -1 && pollfds[pollfd].revents & POLLPRI); 69 *event_pending = (pollfd != -1 && pollfds[pollfd].revents & POLLPRI);
70 return true; 70 return true;
71 } 71 }
72 72
73 void* ExynosV4L2Device::Mmap(void* addr, 73 void* GenericV4L2Device::Mmap(void* addr,
74 unsigned int len, 74 unsigned int len,
75 int prot, 75 int prot,
76 int flags, 76 int flags,
77 unsigned int offset) { 77 unsigned int offset) {
78 return mmap(addr, len, prot, flags, device_fd_, offset); 78 return mmap(addr, len, prot, flags, device_fd_, offset);
79 } 79 }
80 80
81 void ExynosV4L2Device::Munmap(void* addr, unsigned int len) { 81 void GenericV4L2Device::Munmap(void* addr, unsigned int len) {
82 munmap(addr, len); 82 munmap(addr, len);
83 } 83 }
84 84
85 bool ExynosV4L2Device::SetDevicePollInterrupt() { 85 bool GenericV4L2Device::SetDevicePollInterrupt() {
86 DVLOG(3) << "SetDevicePollInterrupt()"; 86 DVLOG(3) << "SetDevicePollInterrupt()";
87 87
88 const uint64 buf = 1; 88 const uint64 buf = 1;
89 if (HANDLE_EINTR(write(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) { 89 if (HANDLE_EINTR(write(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) {
90 DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed"; 90 DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed";
91 return false; 91 return false;
92 } 92 }
93 return true; 93 return true;
94 } 94 }
95 95
96 bool ExynosV4L2Device::ClearDevicePollInterrupt() { 96 bool GenericV4L2Device::ClearDevicePollInterrupt() {
97 DVLOG(3) << "ClearDevicePollInterrupt()"; 97 DVLOG(3) << "ClearDevicePollInterrupt()";
98 98
99 uint64 buf; 99 uint64 buf;
100 if (HANDLE_EINTR(read(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) { 100 if (HANDLE_EINTR(read(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) {
101 if (errno == EAGAIN) { 101 if (errno == EAGAIN) {
102 // No interrupt flag set, and we're reading nonblocking. Not an error. 102 // No interrupt flag set, and we're reading nonblocking. Not an error.
103 return true; 103 return true;
104 } else { 104 } else {
105 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed"; 105 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed";
106 return false; 106 return false;
107 } 107 }
108 } 108 }
109 return true; 109 return true;
110 } 110 }
111 111
112 bool ExynosV4L2Device::Initialize() { 112 bool GenericV4L2Device::Initialize() {
113 const char* device_path = NULL; 113 const char* device_path = NULL;
114 switch (type_) { 114 switch (type_) {
115 case kDecoder: 115 case kDecoder:
116 device_path = kDecoderDevice; 116 device_path = kDecoderDevice;
117 break; 117 break;
118 case kEncoder: 118 case kEncoder:
119 device_path = kEncoderDevice; 119 device_path = kEncoderDevice;
120 break; 120 break;
121 case kImageProcessor: 121 case kImageProcessor:
122 device_path = kImageProcessorDevice; 122 device_path = kImageProcessorDevice;
123 break; 123 break;
124 } 124 }
125 125
126 DVLOG(2) << "Initialize(): opening device: " << device_path; 126 DVLOG(2) << "Initialize(): opening device: " << device_path;
127 // Open the video device. 127 // Open the video device.
128 device_fd_ = HANDLE_EINTR(open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC)); 128 device_fd_ = HANDLE_EINTR(open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC));
129 if (device_fd_ == -1) { 129 if (device_fd_ == -1) {
130 return false; 130 return false;
131 } 131 }
132 132
133 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 133 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
134 if (device_poll_interrupt_fd_ == -1) { 134 if (device_poll_interrupt_fd_ == -1) {
135 return false; 135 return false;
136 } 136 }
137 return true; 137 return true;
138 } 138 }
139 139
140 EGLImageKHR ExynosV4L2Device::CreateEGLImage(EGLDisplay egl_display, 140 EGLImageKHR GenericV4L2Device::CreateEGLImage(EGLDisplay egl_display,
141 EGLContext /* egl_context */, 141 EGLContext /* egl_context */,
142 GLuint texture_id, 142 GLuint texture_id,
143 gfx::Size frame_buffer_size, 143 gfx::Size frame_buffer_size,
144 unsigned int buffer_index, 144 unsigned int buffer_index,
145 size_t planes_count) { 145 size_t planes_count) {
146 DVLOG(3) << "CreateEGLImage()"; 146 DVLOG(3) << "CreateEGLImage()";
147 147
148 scoped_ptr<base::ScopedFD[]> dmabuf_fds(new base::ScopedFD[planes_count]); 148 scoped_ptr<base::ScopedFD[]> dmabuf_fds(new base::ScopedFD[planes_count]);
149 for (size_t i = 0; i < planes_count; ++i) { 149 for (size_t i = 0; i < planes_count; ++i) {
150 // Export the DMABUF fd so we can export it as a texture. 150 // Export the DMABUF fd so we can export it as a texture.
(...skipping 29 matching lines...) Expand all
180 egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs); 180 egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs);
181 if (egl_image == EGL_NO_IMAGE_KHR) { 181 if (egl_image == EGL_NO_IMAGE_KHR) {
182 return egl_image; 182 return egl_image;
183 } 183 }
184 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id); 184 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
185 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image); 185 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image);
186 186
187 return egl_image; 187 return egl_image;
188 } 188 }
189 189
190 EGLBoolean ExynosV4L2Device::DestroyEGLImage(EGLDisplay egl_display, 190 EGLBoolean GenericV4L2Device::DestroyEGLImage(EGLDisplay egl_display,
191 EGLImageKHR egl_image) { 191 EGLImageKHR egl_image) {
192 return eglDestroyImageKHR(egl_display, egl_image); 192 return eglDestroyImageKHR(egl_display, egl_image);
193 } 193 }
194 194
195 GLenum ExynosV4L2Device::GetTextureTarget() { return GL_TEXTURE_EXTERNAL_OES; } 195 GLenum GenericV4L2Device::GetTextureTarget() { return GL_TEXTURE_EXTERNAL_OES; }
196 196
197 uint32 ExynosV4L2Device::PreferredInputFormat() { 197 uint32 GenericV4L2Device::PreferredInputFormat() {
198 // TODO(posciak): We should support "dontcare" returns here once we 198 // TODO(posciak): We should support "dontcare" returns here once we
199 // implement proper handling (fallback, negotiation) for this in users. 199 // implement proper handling (fallback, negotiation) for this in users.
200 CHECK_EQ(type_, kEncoder); 200 CHECK_EQ(type_, kEncoder);
201 return V4L2_PIX_FMT_NV12M; 201 return V4L2_PIX_FMT_NV12M;
202 } 202 }
203 203
204 uint32 ExynosV4L2Device::PreferredOutputFormat() { 204 uint32 GenericV4L2Device::PreferredOutputFormat() {
205 // TODO(posciak): We should support "dontcare" returns here once we 205 // TODO(posciak): We should support "dontcare" returns here once we
206 // implement proper handling (fallback, negotiation) for this in users. 206 // implement proper handling (fallback, negotiation) for this in users.
207 CHECK_EQ(type_, kDecoder); 207 CHECK_EQ(type_, kDecoder);
208 return V4L2_PIX_FMT_NV12M; 208 return V4L2_PIX_FMT_NV12M;
209 } 209 }
210 210
211 } // namespace content 211 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/generic_v4l2_video_device.h ('k') | content/common/gpu/media/v4l2_video_device.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698