OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <errno.h> | 6 #include <errno.h> |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <libdrm/drm_fourcc.h> | 8 #include <libdrm/drm_fourcc.h> |
9 #include <linux/videodev2.h> | 9 #include <linux/videodev2.h> |
10 #include <poll.h> | 10 #include <poll.h> |
(...skipping 15 matching lines...) Expand all Loading... | |
26 | 26 |
27 #define NOTIFY_ERROR(x) \ | 27 #define NOTIFY_ERROR(x) \ |
28 do { \ | 28 do { \ |
29 SetDecoderState(kError); \ | 29 SetDecoderState(kError); \ |
30 DLOG(ERROR) << "calling NotifyError(): " << x; \ | 30 DLOG(ERROR) << "calling NotifyError(): " << x; \ |
31 NotifyError(x); \ | 31 NotifyError(x); \ |
32 } while (0) | 32 } while (0) |
33 | 33 |
34 #define IOCTL_OR_ERROR_RETURN(fd, type, arg) \ | 34 #define IOCTL_OR_ERROR_RETURN(fd, type, arg) \ |
35 do { \ | 35 do { \ |
36 if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) { \ | 36 if (HANDLE_EINTR(device->dev_ioctl(fd, type, arg) != 0)) { \ |
Pawel Osciak
2013/12/24 03:45:24
Please ensure device isn't NULL.
| |
37 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ | 37 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ |
38 NOTIFY_ERROR(PLATFORM_FAILURE); \ | 38 NOTIFY_ERROR(PLATFORM_FAILURE); \ |
39 return; \ | 39 return; \ |
40 } \ | 40 } \ |
41 } while (0) | 41 } while (0) |
42 | 42 |
43 #define IOCTL_OR_ERROR_RETURN_FALSE(fd, type, arg) \ | 43 #define IOCTL_OR_ERROR_RETURN_FALSE(fd, type, arg) \ |
44 do { \ | 44 do { \ |
45 if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) { \ | 45 if (HANDLE_EINTR(device->dev_ioctl(fd, type, arg) != 0)) { \ |
46 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ | 46 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ |
47 NOTIFY_ERROR(PLATFORM_FAILURE); \ | 47 NOTIFY_ERROR(PLATFORM_FAILURE); \ |
48 return false; \ | 48 return false; \ |
49 } \ | 49 } \ |
50 } while (0) | 50 } while (0) |
51 | 51 |
52 namespace { | 52 namespace { |
53 | 53 |
54 // TODO(posciak): remove once we update linux-headers. | 54 // TODO(posciak): remove once we update linux-headers. |
55 #ifndef V4L2_EVENT_RESOLUTION_CHANGE | 55 #ifndef V4L2_EVENT_RESOLUTION_CHANGE |
56 #define V4L2_EVENT_RESOLUTION_CHANGE 5 | 56 #define V4L2_EVENT_RESOLUTION_CHANGE 5 |
57 #endif | 57 #endif |
58 | 58 |
59 const char kExynosMfcDevice[] = "/dev/mfc-dec"; | 59 const char kExynosMfcDevice[] = "/dev/mfc-dec"; |
Pawel Osciak
2013/12/24 03:45:24
This should be a property of the ExynosV4L2Device
| |
60 | 60 |
61 } // anonymous namespace | 61 } // anonymous namespace |
62 | 62 |
63 struct ExynosVideoDecodeAccelerator::BitstreamBufferRef { | 63 int V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_open (const char *fd, |
Pawel Osciak
2013/12/24 03:45:24
Extract to separate file. Also style (spacing, ind
| |
64 int flags) { | |
65 return HANDLE_EINTR(open(fd,flags)); | |
66 } | |
67 | |
68 int V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_ioctl (int fd, | |
69 int flags, void *arg) { | |
70 return ioctl(fd, flags, arg); | |
Pawel Osciak
2013/12/24 03:45:24
HANDLE_EINTR?
| |
71 } | |
72 | |
73 int V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_close (int fd) { | |
74 return close(fd); | |
75 } | |
76 | |
77 int V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_poll ( | |
78 struct pollfd *fds, nfds_t nfds, int n) { | |
79 return poll(fds, nfds, n); | |
Pawel Osciak
2013/12/24 03:45:24
HANDLE_EINTR?
| |
80 } | |
81 | |
82 void* V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_mmap (void *addr, | |
83 unsigned int len, int prot, int flags, int fd, unsigned int offset) { | |
84 return mmap(addr, len, prot, flags, fd, offset); | |
85 } | |
86 | |
87 void V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_munmap (void *addr, | |
88 unsigned int len) { | |
89 munmap(addr,len); | |
90 } | |
91 | |
92 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef { | |
64 BitstreamBufferRef( | 93 BitstreamBufferRef( |
65 base::WeakPtr<Client>& client, | 94 base::WeakPtr<Client>& client, |
66 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, | 95 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, |
67 base::SharedMemory* shm, | 96 base::SharedMemory* shm, |
68 size_t size, | 97 size_t size, |
69 int32 input_id); | 98 int32 input_id); |
70 ~BitstreamBufferRef(); | 99 ~BitstreamBufferRef(); |
71 const base::WeakPtr<Client> client; | 100 const base::WeakPtr<Client> client; |
72 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy; | 101 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy; |
73 const scoped_ptr<base::SharedMemory> shm; | 102 const scoped_ptr<base::SharedMemory> shm; |
74 const size_t size; | 103 const size_t size; |
75 off_t bytes_used; | 104 off_t bytes_used; |
76 const int32 input_id; | 105 const int32 input_id; |
77 }; | 106 }; |
78 | 107 |
79 struct ExynosVideoDecodeAccelerator::PictureBufferArrayRef { | 108 struct V4L2VideoDecodeAccelerator::PictureBufferArrayRef { |
80 PictureBufferArrayRef(EGLDisplay egl_display); | 109 PictureBufferArrayRef(EGLDisplay egl_display); |
81 ~PictureBufferArrayRef(); | 110 ~PictureBufferArrayRef(); |
82 | 111 |
83 struct PictureBufferRef { | 112 struct PictureBufferRef { |
84 PictureBufferRef(EGLImageKHR egl_image, int32 picture_id) | 113 PictureBufferRef(EGLImageKHR egl_image, int32 picture_id) |
85 : egl_image(egl_image), picture_id(picture_id) {} | 114 : egl_image(egl_image), picture_id(picture_id) {} |
86 EGLImageKHR egl_image; | 115 EGLImageKHR egl_image; |
87 int32 picture_id; | 116 int32 picture_id; |
88 }; | 117 }; |
89 | 118 |
90 EGLDisplay const egl_display; | 119 EGLDisplay const egl_display; |
91 std::vector<PictureBufferRef> picture_buffers; | 120 std::vector<PictureBufferRef> picture_buffers; |
92 }; | 121 }; |
93 | 122 |
94 struct ExynosVideoDecodeAccelerator::EGLSyncKHRRef { | 123 struct V4L2VideoDecodeAccelerator::EGLSyncKHRRef { |
95 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync); | 124 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync); |
96 ~EGLSyncKHRRef(); | 125 ~EGLSyncKHRRef(); |
97 EGLDisplay const egl_display; | 126 EGLDisplay const egl_display; |
98 EGLSyncKHR egl_sync; | 127 EGLSyncKHR egl_sync; |
99 }; | 128 }; |
100 | 129 |
101 struct ExynosVideoDecodeAccelerator::PictureRecord { | 130 struct V4L2VideoDecodeAccelerator::PictureRecord { |
102 PictureRecord(bool cleared, const media::Picture& picture); | 131 PictureRecord(bool cleared, const media::Picture& picture); |
103 ~PictureRecord(); | 132 ~PictureRecord(); |
104 bool cleared; // Whether the texture is cleared and safe to render from. | 133 bool cleared; // Whether the texture is cleared and safe to render from. |
105 media::Picture picture; // The decoded picture. | 134 media::Picture picture; // The decoded picture. |
106 }; | 135 }; |
107 | 136 |
108 ExynosVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( | 137 V4L2VideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( |
109 base::WeakPtr<Client>& client, | 138 base::WeakPtr<Client>& client, |
110 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, | 139 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, |
111 base::SharedMemory* shm, size_t size, int32 input_id) | 140 base::SharedMemory* shm, size_t size, int32 input_id) |
112 : client(client), | 141 : client(client), |
113 client_message_loop_proxy(client_message_loop_proxy), | 142 client_message_loop_proxy(client_message_loop_proxy), |
114 shm(shm), | 143 shm(shm), |
115 size(size), | 144 size(size), |
116 bytes_used(0), | 145 bytes_used(0), |
117 input_id(input_id) { | 146 input_id(input_id) { |
118 } | 147 } |
119 | 148 |
120 ExynosVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { | 149 V4L2VideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { |
121 if (input_id >= 0) { | 150 if (input_id >= 0) { |
122 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind( | 151 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind( |
123 &Client::NotifyEndOfBitstreamBuffer, client, input_id)); | 152 &Client::NotifyEndOfBitstreamBuffer, client, input_id)); |
124 } | 153 } |
125 } | 154 } |
126 | 155 |
127 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef( | 156 V4L2VideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef( |
128 EGLDisplay egl_display) | 157 EGLDisplay egl_display) |
129 : egl_display(egl_display) {} | 158 : egl_display(egl_display) {} |
130 | 159 |
131 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::~PictureBufferArrayRef() { | 160 V4L2VideoDecodeAccelerator::PictureBufferArrayRef::~PictureBufferArrayRef() { |
132 for (size_t i = 0; i < picture_buffers.size(); ++i) { | 161 for (size_t i = 0; i < picture_buffers.size(); ++i) { |
133 EGLImageKHR egl_image = picture_buffers[i].egl_image; | 162 EGLImageKHR egl_image = picture_buffers[i].egl_image; |
134 if (egl_image != EGL_NO_IMAGE_KHR) | 163 if (egl_image != EGL_NO_IMAGE_KHR) |
135 eglDestroyImageKHR(egl_display, egl_image); | 164 eglDestroyImageKHR(egl_display, egl_image); |
136 } | 165 } |
137 } | 166 } |
138 | 167 |
139 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef( | 168 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef( |
140 EGLDisplay egl_display, EGLSyncKHR egl_sync) | 169 EGLDisplay egl_display, EGLSyncKHR egl_sync) |
141 : egl_display(egl_display), | 170 : egl_display(egl_display), |
142 egl_sync(egl_sync) { | 171 egl_sync(egl_sync) { |
143 } | 172 } |
144 | 173 |
145 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() { | 174 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() { |
146 if (egl_sync != EGL_NO_SYNC_KHR) | 175 if (egl_sync != EGL_NO_SYNC_KHR) |
147 eglDestroySyncKHR(egl_display, egl_sync); | 176 eglDestroySyncKHR(egl_display, egl_sync); |
148 } | 177 } |
149 | 178 |
150 ExynosVideoDecodeAccelerator::MfcInputRecord::MfcInputRecord() | 179 V4L2VideoDecodeAccelerator::MfcInputRecord::MfcInputRecord() |
151 : at_device(false), | 180 : at_device(false), |
152 address(NULL), | 181 address(NULL), |
153 length(0), | 182 length(0), |
154 bytes_used(0), | 183 bytes_used(0), |
155 input_id(-1) { | 184 input_id(-1) { |
156 } | 185 } |
157 | 186 |
158 ExynosVideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() { | 187 V4L2VideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() { |
159 } | 188 } |
160 | 189 |
161 ExynosVideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord() | 190 V4L2VideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord() |
162 : at_device(false), | 191 : at_device(false), |
163 at_client(false), | 192 at_client(false), |
164 egl_image(EGL_NO_IMAGE_KHR), | 193 egl_image(EGL_NO_IMAGE_KHR), |
165 egl_sync(EGL_NO_SYNC_KHR), | 194 egl_sync(EGL_NO_SYNC_KHR), |
166 picture_id(-1), | 195 picture_id(-1), |
167 cleared(false) { | 196 cleared(false) { |
168 for (size_t i = 0; i < arraysize(fds); ++i) | 197 for (size_t i = 0; i < arraysize(fds); ++i) |
169 fds[i] = -1; | 198 fds[i] = -1; |
170 } | 199 } |
171 | 200 |
172 ExynosVideoDecodeAccelerator::MfcOutputRecord::~MfcOutputRecord() {} | 201 V4L2VideoDecodeAccelerator::MfcOutputRecord::~MfcOutputRecord() {} |
173 | 202 |
174 ExynosVideoDecodeAccelerator::PictureRecord::PictureRecord( | 203 V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord( |
175 bool cleared, | 204 bool cleared, |
176 const media::Picture& picture) | 205 const media::Picture& picture) |
177 : cleared(cleared), picture(picture) {} | 206 : cleared(cleared), picture(picture) {} |
178 | 207 |
179 ExynosVideoDecodeAccelerator::PictureRecord::~PictureRecord() {} | 208 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} |
180 | 209 |
181 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator( | 210 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( |
182 EGLDisplay egl_display, | 211 EGLDisplay egl_display, |
183 EGLContext egl_context, | |
184 Client* client, | 212 Client* client, |
185 const base::WeakPtr<Client>& io_client, | 213 const base::WeakPtr<Client>& io_client, |
186 const base::Callback<bool(void)>& make_context_current, | 214 const base::Callback<bool(void)>& make_context_current, |
187 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) | 215 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) |
188 : child_message_loop_proxy_(base::MessageLoopProxy::current()), | 216 : child_message_loop_proxy_(base::MessageLoopProxy::current()), |
189 io_message_loop_proxy_(io_message_loop_proxy), | 217 io_message_loop_proxy_(io_message_loop_proxy), |
190 weak_this_(base::AsWeakPtr(this)), | 218 weak_this_(base::AsWeakPtr(this)), |
191 client_ptr_factory_(client), | 219 client_ptr_factory_(client), |
192 client_(client_ptr_factory_.GetWeakPtr()), | 220 client_(client_ptr_factory_.GetWeakPtr()), |
193 io_client_(io_client), | 221 io_client_(io_client), |
194 decoder_thread_("ExynosDecoderThread"), | 222 decoder_thread_("V4L2DecoderThread"), |
195 decoder_state_(kUninitialized), | 223 decoder_state_(kUninitialized), |
196 decoder_delay_bitstream_buffer_id_(-1), | 224 decoder_delay_bitstream_buffer_id_(-1), |
197 decoder_current_input_buffer_(-1), | 225 decoder_current_input_buffer_(-1), |
198 decoder_decode_buffer_tasks_scheduled_(0), | 226 decoder_decode_buffer_tasks_scheduled_(0), |
199 decoder_frames_at_client_(0), | 227 decoder_frames_at_client_(0), |
200 decoder_flushing_(false), | 228 decoder_flushing_(false), |
201 resolution_change_pending_(false), | 229 resolution_change_pending_(false), |
202 resolution_change_reset_pending_(false), | 230 resolution_change_reset_pending_(false), |
203 decoder_partial_frame_pending_(false), | 231 decoder_partial_frame_pending_(false), |
204 mfc_fd_(-1), | 232 videodec_fd_(-1), |
205 mfc_input_streamon_(false), | 233 mfc_input_streamon_(false), |
206 mfc_input_buffer_queued_count_(0), | 234 mfc_input_buffer_queued_count_(0), |
207 mfc_output_streamon_(false), | 235 mfc_output_streamon_(false), |
208 mfc_output_buffer_queued_count_(0), | 236 mfc_output_buffer_queued_count_(0), |
209 mfc_output_buffer_pixelformat_(0), | 237 mfc_output_buffer_pixelformat_(0), |
210 mfc_output_dpb_size_(0), | 238 mfc_output_dpb_size_(0), |
211 picture_clearing_count_(0), | 239 picture_clearing_count_(0), |
212 device_poll_thread_("ExynosDevicePollThread"), | 240 device_poll_thread_("V4L2DevicePollThread"), |
213 device_poll_interrupt_fd_(-1), | 241 device_poll_interrupt_fd_(-1), |
214 make_context_current_(make_context_current), | 242 make_context_current_(make_context_current), |
215 egl_display_(egl_display), | 243 egl_display_(egl_display), |
216 egl_context_(egl_context), | |
217 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {} | 244 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {} |
218 | 245 |
219 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() { | 246 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() { |
220 DCHECK(!decoder_thread_.IsRunning()); | 247 DCHECK(!decoder_thread_.IsRunning()); |
221 DCHECK(!device_poll_thread_.IsRunning()); | 248 DCHECK(!device_poll_thread_.IsRunning()); |
222 | 249 |
223 if (device_poll_interrupt_fd_ != -1) { | 250 if (device_poll_interrupt_fd_ != -1) { |
224 close(device_poll_interrupt_fd_); | 251 device->dev_close(device_poll_interrupt_fd_); |
Pawel Osciak
2013/12/24 03:45:24
What if device has never been allocated (before In
| |
225 device_poll_interrupt_fd_ = -1; | 252 device_poll_interrupt_fd_ = -1; |
226 } | 253 } |
227 if (mfc_fd_ != -1) { | 254 if (videodec_fd_ != -1) { |
228 DestroyMfcInputBuffers(); | 255 DestroyMfcInputBuffers(); |
229 DestroyMfcOutputBuffers(); | 256 DestroyMfcOutputBuffers(); |
230 close(mfc_fd_); | 257 device->dev_close(videodec_fd_); |
231 mfc_fd_ = -1; | 258 videodec_fd_ = -1; |
232 } | 259 } |
233 | 260 |
234 // These maps have members that should be manually destroyed, e.g. file | 261 // These maps have members that should be manually destroyed, e.g. file |
235 // descriptors, mmap() segments, etc. | 262 // descriptors, mmap() segments, etc. |
236 DCHECK(mfc_input_buffer_map_.empty()); | 263 DCHECK(mfc_input_buffer_map_.empty()); |
237 DCHECK(mfc_output_buffer_map_.empty()); | 264 DCHECK(mfc_output_buffer_map_.empty()); |
238 } | 265 } |
239 | 266 |
240 bool ExynosVideoDecodeAccelerator::Initialize( | 267 bool V4L2VideoDecodeAccelerator::Initialize( |
241 media::VideoCodecProfile profile) { | 268 media::VideoCodecProfile profile) { |
242 DVLOG(3) << "Initialize()"; | 269 DVLOG(3) << "Initialize()"; |
243 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 270 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
244 DCHECK_EQ(decoder_state_, kUninitialized); | 271 DCHECK_EQ(decoder_state_, kUninitialized); |
245 | 272 |
246 switch (profile) { | 273 switch (profile) { |
247 case media::H264PROFILE_BASELINE: | 274 case media::H264PROFILE_BASELINE: |
248 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; | 275 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; |
249 break; | 276 break; |
250 case media::H264PROFILE_MAIN: | 277 case media::H264PROFILE_MAIN: |
(...skipping 10 matching lines...) Expand all Loading... | |
261 return false; | 288 return false; |
262 }; | 289 }; |
263 video_profile_ = profile; | 290 video_profile_ = profile; |
264 | 291 |
265 if (egl_display_ == EGL_NO_DISPLAY) { | 292 if (egl_display_ == EGL_NO_DISPLAY) { |
266 DLOG(ERROR) << "Initialize(): could not get EGLDisplay"; | 293 DLOG(ERROR) << "Initialize(): could not get EGLDisplay"; |
267 NOTIFY_ERROR(PLATFORM_FAILURE); | 294 NOTIFY_ERROR(PLATFORM_FAILURE); |
268 return false; | 295 return false; |
269 } | 296 } |
270 | 297 |
271 if (egl_context_ == EGL_NO_CONTEXT) { | |
272 DLOG(ERROR) << "Initialize(): could not get EGLContext"; | |
273 NOTIFY_ERROR(PLATFORM_FAILURE); | |
274 return false; | |
275 } | |
276 | |
277 // We need the context to be initialized to query extensions. | 298 // We need the context to be initialized to query extensions. |
278 if (!make_context_current_.Run()) { | 299 if (!make_context_current_.Run()) { |
279 DLOG(ERROR) << "Initialize(): could not make context current"; | 300 DLOG(ERROR) << "Initialize(): could not make context current"; |
280 NOTIFY_ERROR(PLATFORM_FAILURE); | 301 NOTIFY_ERROR(PLATFORM_FAILURE); |
281 return false; | 302 return false; |
282 } | 303 } |
283 | 304 |
284 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) { | 305 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) { |
285 DLOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync"; | 306 DLOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync"; |
286 NOTIFY_ERROR(PLATFORM_FAILURE); | 307 NOTIFY_ERROR(PLATFORM_FAILURE); |
287 return false; | 308 return false; |
288 } | 309 } |
289 | 310 |
290 // Open the video devices. | 311 // Open the video devices. |
291 DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice; | 312 DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice; |
Pawel Osciak
2013/12/24 03:45:24
Please scrub Exynos from this class.
| |
292 mfc_fd_ = HANDLE_EINTR(open(kExynosMfcDevice, | 313 device = new ExynosV4L2Device; |
Pawel Osciak
2013/12/24 03:45:24
I don't see this being freed anywhere.?
In any cas
| |
293 O_RDWR | O_NONBLOCK | O_CLOEXEC)); | 314 |
294 if (mfc_fd_ == -1) { | 315 videodec_fd_ = device->dev_open(kExynosMfcDevice, |
316 O_RDWR | O_NONBLOCK | O_CLOEXEC); | |
317 | |
318 if (videodec_fd_ == -1) { | |
295 DPLOG(ERROR) << "Initialize(): could not open MFC device: " | 319 DPLOG(ERROR) << "Initialize(): could not open MFC device: " |
296 << kExynosMfcDevice; | 320 << kExynosMfcDevice; |
297 NOTIFY_ERROR(PLATFORM_FAILURE); | 321 NOTIFY_ERROR(PLATFORM_FAILURE); |
298 return false; | 322 return false; |
299 } | 323 } |
300 | 324 |
301 // Create the interrupt fd. | 325 // Create the interrupt fd. |
302 DCHECK_EQ(device_poll_interrupt_fd_, -1); | 326 DCHECK_EQ(device_poll_interrupt_fd_, -1); |
303 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); | 327 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); |
Pawel Osciak
2013/12/24 03:45:24
This could be extracted as well I think?
| |
304 if (device_poll_interrupt_fd_ == -1) { | 328 if (device_poll_interrupt_fd_ == -1) { |
305 DPLOG(ERROR) << "Initialize(): eventfd() failed"; | 329 DPLOG(ERROR) << "Initialize(): eventfd() failed"; |
306 NOTIFY_ERROR(PLATFORM_FAILURE); | 330 NOTIFY_ERROR(PLATFORM_FAILURE); |
307 return false; | 331 return false; |
308 } | 332 } |
309 | 333 |
310 // Capabilities check. | 334 // Capabilities check. |
311 struct v4l2_capability caps; | 335 struct v4l2_capability caps; |
312 const __u32 kCapsRequired = | 336 const __u32 kCapsRequired = |
313 V4L2_CAP_VIDEO_CAPTURE_MPLANE | | 337 V4L2_CAP_VIDEO_CAPTURE_MPLANE | |
314 V4L2_CAP_VIDEO_OUTPUT_MPLANE | | 338 V4L2_CAP_VIDEO_OUTPUT_MPLANE | |
315 V4L2_CAP_STREAMING; | 339 V4L2_CAP_STREAMING; |
316 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYCAP, &caps); | 340 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_QUERYCAP, &caps); |
317 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { | 341 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { |
318 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" | 342 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" |
319 ", caps check failed: 0x" << std::hex << caps.capabilities; | 343 ", caps check failed: 0x" << std::hex << caps.capabilities; |
320 NOTIFY_ERROR(PLATFORM_FAILURE); | 344 NOTIFY_ERROR(PLATFORM_FAILURE); |
321 return false; | 345 return false; |
322 } | 346 } |
323 | 347 |
324 if (!CreateMfcInputBuffers()) | 348 if (!CreateMfcInputBuffers()) |
325 return false; | 349 return false; |
326 | 350 |
327 // MFC output format has to be setup before streaming starts. | 351 // MFC output format has to be setup before streaming starts. |
328 struct v4l2_format format; | 352 struct v4l2_format format; |
329 memset(&format, 0, sizeof(format)); | 353 memset(&format, 0, sizeof(format)); |
330 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 354 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
331 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; | 355 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; |
332 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format); | 356 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_S_FMT, &format); |
333 | 357 |
334 // Subscribe to the resolution change event. | 358 // Subscribe to the resolution change event. |
335 struct v4l2_event_subscription sub; | 359 struct v4l2_event_subscription sub; |
336 memset(&sub, 0, sizeof(sub)); | 360 memset(&sub, 0, sizeof(sub)); |
337 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; | 361 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; |
338 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub); | 362 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub); |
339 | 363 |
340 // Initialize format-specific bits. | 364 // Initialize format-specific bits. |
341 if (video_profile_ >= media::H264PROFILE_MIN && | 365 if (video_profile_ >= media::H264PROFILE_MIN && |
342 video_profile_ <= media::H264PROFILE_MAX) { | 366 video_profile_ <= media::H264PROFILE_MAX) { |
343 decoder_h264_parser_.reset(new content::H264Parser()); | 367 decoder_h264_parser_.reset(new content::H264Parser()); |
344 } | 368 } |
345 | 369 |
346 if (!decoder_thread_.Start()) { | 370 if (!decoder_thread_.Start()) { |
347 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; | 371 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; |
348 NOTIFY_ERROR(PLATFORM_FAILURE); | 372 NOTIFY_ERROR(PLATFORM_FAILURE); |
349 return false; | 373 return false; |
350 } | 374 } |
351 | 375 |
352 SetDecoderState(kInitialized); | 376 SetDecoderState(kInitialized); |
353 | 377 |
354 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 378 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
355 &Client::NotifyInitializeDone, client_)); | 379 &Client::NotifyInitializeDone, client_)); |
356 return true; | 380 return true; |
357 } | 381 } |
358 | 382 |
359 void ExynosVideoDecodeAccelerator::Decode( | 383 void V4L2VideoDecodeAccelerator::Decode( |
360 const media::BitstreamBuffer& bitstream_buffer) { | 384 const media::BitstreamBuffer& bitstream_buffer) { |
361 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() | 385 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() |
362 << ", size=" << bitstream_buffer.size(); | 386 << ", size=" << bitstream_buffer.size(); |
363 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 387 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
364 | 388 |
365 // DecodeTask() will take care of running a DecodeBufferTask(). | 389 // DecodeTask() will take care of running a DecodeBufferTask(). |
366 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 390 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
367 &ExynosVideoDecodeAccelerator::DecodeTask, base::Unretained(this), | 391 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this), |
368 bitstream_buffer)); | 392 bitstream_buffer)); |
369 } | 393 } |
370 | 394 |
371 void ExynosVideoDecodeAccelerator::AssignPictureBuffers( | 395 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( |
372 const std::vector<media::PictureBuffer>& buffers) { | 396 const std::vector<media::PictureBuffer>& buffers) { |
373 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); | 397 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); |
374 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 398 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
375 | 399 |
376 if (buffers.size() != mfc_output_buffer_map_.size()) { | 400 if (buffers.size() != mfc_output_buffer_map_.size()) { |
377 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" | 401 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" |
378 " buffers. (Got " << buffers.size() | 402 " buffers. (Got " << buffers.size() |
379 << ", requested " << mfc_output_buffer_map_.size() << ")"; | 403 << ", requested " << mfc_output_buffer_map_.size() << ")"; |
380 NOTIFY_ERROR(INVALID_ARGUMENT); | 404 NOTIFY_ERROR(INVALID_ARGUMENT); |
381 return; | 405 return; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 return; | 440 return; |
417 } | 441 } |
418 | 442 |
419 glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id()); | 443 glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id()); |
420 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image); | 444 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image); |
421 picture_buffers_ref->picture_buffers.push_back( | 445 picture_buffers_ref->picture_buffers.push_back( |
422 PictureBufferArrayRef::PictureBufferRef(egl_image, buffers[i].id())); | 446 PictureBufferArrayRef::PictureBufferRef(egl_image, buffers[i].id())); |
423 } | 447 } |
424 decoder_thread_.message_loop()->PostTask( | 448 decoder_thread_.message_loop()->PostTask( |
425 FROM_HERE, | 449 FROM_HERE, |
426 base::Bind(&ExynosVideoDecodeAccelerator::AssignPictureBuffersTask, | 450 base::Bind(&V4L2VideoDecodeAccelerator::AssignPictureBuffersTask, |
427 base::Unretained(this), | 451 base::Unretained(this), |
428 base::Passed(&picture_buffers_ref))); | 452 base::Passed(&picture_buffers_ref))); |
429 } | 453 } |
430 | 454 |
431 void ExynosVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { | 455 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { |
432 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id; | 456 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id; |
433 // Must be run on child thread, as we'll insert a sync in the EGL context. | 457 // Must be run on child thread, as we'll insert a sync in the EGL context. |
434 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 458 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
435 | 459 |
436 if (!make_context_current_.Run()) { | 460 if (!make_context_current_.Run()) { |
437 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current"; | 461 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current"; |
438 NOTIFY_ERROR(PLATFORM_FAILURE); | 462 NOTIFY_ERROR(PLATFORM_FAILURE); |
439 return; | 463 return; |
440 } | 464 } |
441 | 465 |
442 EGLSyncKHR egl_sync = | 466 EGLSyncKHR egl_sync = |
443 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); | 467 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); |
444 if (egl_sync == EGL_NO_SYNC_KHR) { | 468 if (egl_sync == EGL_NO_SYNC_KHR) { |
445 DLOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed"; | 469 DLOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed"; |
446 NOTIFY_ERROR(PLATFORM_FAILURE); | 470 NOTIFY_ERROR(PLATFORM_FAILURE); |
447 return; | 471 return; |
448 } | 472 } |
449 | 473 |
450 scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef( | 474 scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef( |
451 egl_display_, egl_sync)); | 475 egl_display_, egl_sync)); |
452 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 476 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
453 &ExynosVideoDecodeAccelerator::ReusePictureBufferTask, | 477 &V4L2VideoDecodeAccelerator::ReusePictureBufferTask, |
454 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref))); | 478 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref))); |
455 } | 479 } |
456 | 480 |
457 void ExynosVideoDecodeAccelerator::Flush() { | 481 void V4L2VideoDecodeAccelerator::Flush() { |
458 DVLOG(3) << "Flush()"; | 482 DVLOG(3) << "Flush()"; |
459 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 483 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
460 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 484 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
461 &ExynosVideoDecodeAccelerator::FlushTask, base::Unretained(this))); | 485 &V4L2VideoDecodeAccelerator::FlushTask, base::Unretained(this))); |
462 } | 486 } |
463 | 487 |
464 void ExynosVideoDecodeAccelerator::Reset() { | 488 void V4L2VideoDecodeAccelerator::Reset() { |
465 DVLOG(3) << "Reset()"; | 489 DVLOG(3) << "Reset()"; |
466 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 490 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
467 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 491 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
468 &ExynosVideoDecodeAccelerator::ResetTask, base::Unretained(this))); | 492 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this))); |
469 } | 493 } |
470 | 494 |
471 void ExynosVideoDecodeAccelerator::Destroy() { | 495 void V4L2VideoDecodeAccelerator::Destroy() { |
472 DVLOG(3) << "Destroy()"; | 496 DVLOG(3) << "Destroy()"; |
473 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 497 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
474 | 498 |
475 // We're destroying; cancel all callbacks. | 499 // We're destroying; cancel all callbacks. |
476 client_ptr_factory_.InvalidateWeakPtrs(); | 500 client_ptr_factory_.InvalidateWeakPtrs(); |
477 | 501 |
478 // If the decoder thread is running, destroy using posted task. | 502 // If the decoder thread is running, destroy using posted task. |
479 if (decoder_thread_.IsRunning()) { | 503 if (decoder_thread_.IsRunning()) { |
480 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 504 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
481 &ExynosVideoDecodeAccelerator::DestroyTask, base::Unretained(this))); | 505 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this))); |
482 // DestroyTask() will cause the decoder_thread_ to flush all tasks. | 506 // DestroyTask() will cause the decoder_thread_ to flush all tasks. |
483 decoder_thread_.Stop(); | 507 decoder_thread_.Stop(); |
484 } else { | 508 } else { |
485 // Otherwise, call the destroy task directly. | 509 // Otherwise, call the destroy task directly. |
486 DestroyTask(); | 510 DestroyTask(); |
487 } | 511 } |
488 | 512 |
489 // Set to kError state just in case. | 513 // Set to kError state just in case. |
490 SetDecoderState(kError); | 514 SetDecoderState(kError); |
491 | 515 |
492 delete this; | 516 delete this; |
493 } | 517 } |
494 | 518 |
495 bool ExynosVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } | 519 bool V4L2VideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } |
496 | 520 |
497 void ExynosVideoDecodeAccelerator::DecodeTask( | 521 void V4L2VideoDecodeAccelerator::DecodeTask( |
498 const media::BitstreamBuffer& bitstream_buffer) { | 522 const media::BitstreamBuffer& bitstream_buffer) { |
499 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); | 523 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); |
500 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 524 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
501 DCHECK_NE(decoder_state_, kUninitialized); | 525 DCHECK_NE(decoder_state_, kUninitialized); |
502 TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id", | 526 TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id", |
503 bitstream_buffer.id()); | 527 bitstream_buffer.id()); |
504 | 528 |
505 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( | 529 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( |
506 io_client_, io_message_loop_proxy_, | 530 io_client_, io_message_loop_proxy_, |
507 new base::SharedMemory(bitstream_buffer.handle(), true), | 531 new base::SharedMemory(bitstream_buffer.handle(), true), |
(...skipping 17 matching lines...) Expand all Loading... | |
525 DVLOG(2) << "DecodeTask(): early out: kError state"; | 549 DVLOG(2) << "DecodeTask(): early out: kError state"; |
526 return; | 550 return; |
527 } | 551 } |
528 | 552 |
529 decoder_input_queue_.push( | 553 decoder_input_queue_.push( |
530 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); | 554 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); |
531 decoder_decode_buffer_tasks_scheduled_++; | 555 decoder_decode_buffer_tasks_scheduled_++; |
532 DecodeBufferTask(); | 556 DecodeBufferTask(); |
533 } | 557 } |
534 | 558 |
535 void ExynosVideoDecodeAccelerator::DecodeBufferTask() { | 559 void V4L2VideoDecodeAccelerator::DecodeBufferTask() { |
536 DVLOG(3) << "DecodeBufferTask()"; | 560 DVLOG(3) << "DecodeBufferTask()"; |
537 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 561 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
538 DCHECK_NE(decoder_state_, kUninitialized); | 562 DCHECK_NE(decoder_state_, kUninitialized); |
539 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask"); | 563 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask"); |
540 | 564 |
541 decoder_decode_buffer_tasks_scheduled_--; | 565 decoder_decode_buffer_tasks_scheduled_--; |
542 | 566 |
543 if (decoder_state_ == kResetting) { | 567 if (decoder_state_ == kResetting) { |
544 DVLOG(2) << "DecodeBufferTask(): early out: kResetting state"; | 568 DVLOG(2) << "DecodeBufferTask(): early out: kResetting state"; |
545 return; | 569 return; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
646 // Our current bitstream buffer is done; return it. | 670 // Our current bitstream buffer is done; return it. |
647 int32 input_id = decoder_current_bitstream_buffer_->input_id; | 671 int32 input_id = decoder_current_bitstream_buffer_->input_id; |
648 DVLOG(3) << "DecodeBufferTask(): finished input_id=" << input_id; | 672 DVLOG(3) << "DecodeBufferTask(): finished input_id=" << input_id; |
649 // BitstreamBufferRef destructor calls NotifyEndOfBitstreamBuffer(). | 673 // BitstreamBufferRef destructor calls NotifyEndOfBitstreamBuffer(). |
650 decoder_current_bitstream_buffer_.reset(); | 674 decoder_current_bitstream_buffer_.reset(); |
651 } | 675 } |
652 ScheduleDecodeBufferTaskIfNeeded(); | 676 ScheduleDecodeBufferTaskIfNeeded(); |
653 } | 677 } |
654 } | 678 } |
655 | 679 |
656 bool ExynosVideoDecodeAccelerator::AdvanceFrameFragment( | 680 bool V4L2VideoDecodeAccelerator::AdvanceFrameFragment( |
657 const uint8* data, | 681 const uint8* data, |
658 size_t size, | 682 size_t size, |
659 size_t* endpos) { | 683 size_t* endpos) { |
660 if (video_profile_ >= media::H264PROFILE_MIN && | 684 if (video_profile_ >= media::H264PROFILE_MIN && |
661 video_profile_ <= media::H264PROFILE_MAX) { | 685 video_profile_ <= media::H264PROFILE_MAX) { |
662 // For H264, we need to feed HW one frame at a time. This is going to take | 686 // For H264, we need to feed HW one frame at a time. This is going to take |
663 // some parsing of our input stream. | 687 // some parsing of our input stream. |
664 decoder_h264_parser_->SetStream(data, size); | 688 decoder_h264_parser_->SetStream(data, size); |
665 content::H264NALU nalu; | 689 content::H264NALU nalu; |
666 content::H264Parser::Result result; | 690 content::H264Parser::Result result; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
726 DCHECK_GE(video_profile_, media::VP8PROFILE_MIN); | 750 DCHECK_GE(video_profile_, media::VP8PROFILE_MIN); |
727 DCHECK_LE(video_profile_, media::VP8PROFILE_MAX); | 751 DCHECK_LE(video_profile_, media::VP8PROFILE_MAX); |
728 // For VP8, we can just dump the entire buffer. No fragmentation needed, | 752 // For VP8, we can just dump the entire buffer. No fragmentation needed, |
729 // and we never return a partial frame. | 753 // and we never return a partial frame. |
730 *endpos = size; | 754 *endpos = size; |
731 decoder_partial_frame_pending_ = false; | 755 decoder_partial_frame_pending_ = false; |
732 return true; | 756 return true; |
733 } | 757 } |
734 } | 758 } |
735 | 759 |
736 void ExynosVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { | 760 void V4L2VideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { |
737 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 761 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
738 | 762 |
739 // If we're behind on tasks, schedule another one. | 763 // If we're behind on tasks, schedule another one. |
740 int buffers_to_decode = decoder_input_queue_.size(); | 764 int buffers_to_decode = decoder_input_queue_.size(); |
741 if (decoder_current_bitstream_buffer_ != NULL) | 765 if (decoder_current_bitstream_buffer_ != NULL) |
742 buffers_to_decode++; | 766 buffers_to_decode++; |
743 if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) { | 767 if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) { |
744 decoder_decode_buffer_tasks_scheduled_++; | 768 decoder_decode_buffer_tasks_scheduled_++; |
745 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 769 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
746 &ExynosVideoDecodeAccelerator::DecodeBufferTask, | 770 &V4L2VideoDecodeAccelerator::DecodeBufferTask, |
747 base::Unretained(this))); | 771 base::Unretained(this))); |
748 } | 772 } |
749 } | 773 } |
750 | 774 |
751 bool ExynosVideoDecodeAccelerator::DecodeBufferInitial( | 775 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( |
752 const void* data, size_t size, size_t* endpos) { | 776 const void* data, size_t size, size_t* endpos) { |
753 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; | 777 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; |
754 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 778 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
755 DCHECK_NE(decoder_state_, kUninitialized); | 779 DCHECK_NE(decoder_state_, kUninitialized); |
756 DCHECK_NE(decoder_state_, kDecoding); | 780 DCHECK_NE(decoder_state_, kDecoding); |
757 DCHECK(!device_poll_thread_.IsRunning()); | 781 DCHECK(!device_poll_thread_.IsRunning()); |
758 // Initial decode. We haven't been able to get output stream format info yet. | 782 // Initial decode. We haven't been able to get output stream format info yet. |
759 // Get it, and start decoding. | 783 // Get it, and start decoding. |
760 | 784 |
761 // Copy in and send to HW. | 785 // Copy in and send to HW. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
802 | 826 |
803 // StartDevicePoll will raise the error if there is one. | 827 // StartDevicePoll will raise the error if there is one. |
804 if (!StartDevicePoll()) | 828 if (!StartDevicePoll()) |
805 return false; | 829 return false; |
806 | 830 |
807 decoder_state_ = kDecoding; | 831 decoder_state_ = kDecoding; |
808 ScheduleDecodeBufferTaskIfNeeded(); | 832 ScheduleDecodeBufferTaskIfNeeded(); |
809 return true; | 833 return true; |
810 } | 834 } |
811 | 835 |
812 bool ExynosVideoDecodeAccelerator::DecodeBufferContinue( | 836 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue( |
813 const void* data, size_t size) { | 837 const void* data, size_t size) { |
814 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; | 838 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; |
815 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 839 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
816 DCHECK_EQ(decoder_state_, kDecoding); | 840 DCHECK_EQ(decoder_state_, kDecoding); |
817 | 841 |
818 // Both of these calls will set kError state if they fail. | 842 // Both of these calls will set kError state if they fail. |
819 // Only flush the frame if it's complete. | 843 // Only flush the frame if it's complete. |
820 return (AppendToInputFrame(data, size) && | 844 return (AppendToInputFrame(data, size) && |
821 (decoder_partial_frame_pending_ || FlushInputFrame())); | 845 (decoder_partial_frame_pending_ || FlushInputFrame())); |
822 } | 846 } |
823 | 847 |
824 bool ExynosVideoDecodeAccelerator::AppendToInputFrame( | 848 bool V4L2VideoDecodeAccelerator::AppendToInputFrame( |
825 const void* data, size_t size) { | 849 const void* data, size_t size) { |
826 DVLOG(3) << "AppendToInputFrame()"; | 850 DVLOG(3) << "AppendToInputFrame()"; |
827 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 851 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
828 DCHECK_NE(decoder_state_, kUninitialized); | 852 DCHECK_NE(decoder_state_, kUninitialized); |
829 DCHECK_NE(decoder_state_, kResetting); | 853 DCHECK_NE(decoder_state_, kResetting); |
830 DCHECK_NE(decoder_state_, kError); | 854 DCHECK_NE(decoder_state_, kError); |
831 // This routine can handle data == NULL and size == 0, which occurs when | 855 // This routine can handle data == NULL and size == 0, which occurs when |
832 // we queue an empty buffer for the purposes of flushing the pipe. | 856 // we queue an empty buffer for the purposes of flushing the pipe. |
833 | 857 |
834 // Flush if we're too big | 858 // Flush if we're too big |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
881 } | 905 } |
882 memcpy( | 906 memcpy( |
883 reinterpret_cast<uint8*>(input_record.address) + input_record.bytes_used, | 907 reinterpret_cast<uint8*>(input_record.address) + input_record.bytes_used, |
884 data, | 908 data, |
885 size); | 909 size); |
886 input_record.bytes_used += size; | 910 input_record.bytes_used += size; |
887 | 911 |
888 return true; | 912 return true; |
889 } | 913 } |
890 | 914 |
891 bool ExynosVideoDecodeAccelerator::FlushInputFrame() { | 915 bool V4L2VideoDecodeAccelerator::FlushInputFrame() { |
892 DVLOG(3) << "FlushInputFrame()"; | 916 DVLOG(3) << "FlushInputFrame()"; |
893 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 917 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
894 DCHECK_NE(decoder_state_, kUninitialized); | 918 DCHECK_NE(decoder_state_, kUninitialized); |
895 DCHECK_NE(decoder_state_, kResetting); | 919 DCHECK_NE(decoder_state_, kResetting); |
896 DCHECK_NE(decoder_state_, kError); | 920 DCHECK_NE(decoder_state_, kError); |
897 | 921 |
898 if (decoder_current_input_buffer_ == -1) | 922 if (decoder_current_input_buffer_ == -1) |
899 return true; | 923 return true; |
900 | 924 |
901 MfcInputRecord& input_record = | 925 MfcInputRecord& input_record = |
(...skipping 17 matching lines...) Expand all Loading... | |
919 mfc_input_ready_queue_.push(decoder_current_input_buffer_); | 943 mfc_input_ready_queue_.push(decoder_current_input_buffer_); |
920 decoder_current_input_buffer_ = -1; | 944 decoder_current_input_buffer_ = -1; |
921 DVLOG(3) << "FlushInputFrame(): submitting input_id=" | 945 DVLOG(3) << "FlushInputFrame(): submitting input_id=" |
922 << input_record.input_id; | 946 << input_record.input_id; |
923 // Kick the MFC once since there's new available input for it. | 947 // Kick the MFC once since there's new available input for it. |
924 EnqueueMfc(); | 948 EnqueueMfc(); |
925 | 949 |
926 return (decoder_state_ != kError); | 950 return (decoder_state_ != kError); |
927 } | 951 } |
928 | 952 |
929 void ExynosVideoDecodeAccelerator::AssignPictureBuffersTask( | 953 void V4L2VideoDecodeAccelerator::AssignPictureBuffersTask( |
930 scoped_ptr<PictureBufferArrayRef> pic_buffers) { | 954 scoped_ptr<PictureBufferArrayRef> pic_buffers) { |
931 DVLOG(3) << "AssignPictureBuffersTask()"; | 955 DVLOG(3) << "AssignPictureBuffersTask()"; |
932 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 956 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
933 DCHECK_NE(decoder_state_, kUninitialized); | 957 DCHECK_NE(decoder_state_, kUninitialized); |
934 TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask"); | 958 TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask"); |
935 | 959 |
936 // We run AssignPictureBuffersTask even if we're in kResetting. | 960 // We run AssignPictureBuffersTask even if we're in kResetting. |
937 if (decoder_state_ == kError) { | 961 if (decoder_state_ == kError) { |
938 DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state"; | 962 DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state"; |
939 return; | 963 return; |
(...skipping 19 matching lines...) Expand all Loading... | |
959 } | 983 } |
960 pic_buffers->picture_buffers.clear(); | 984 pic_buffers->picture_buffers.clear(); |
961 | 985 |
962 // We got buffers! Kick the MFC. | 986 // We got buffers! Kick the MFC. |
963 EnqueueMfc(); | 987 EnqueueMfc(); |
964 | 988 |
965 if (decoder_state_ == kChangingResolution) | 989 if (decoder_state_ == kChangingResolution) |
966 ResumeAfterResolutionChange(); | 990 ResumeAfterResolutionChange(); |
967 } | 991 } |
968 | 992 |
969 void ExynosVideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) { | 993 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) { |
970 DVLOG(3) << "ServiceDeviceTask()"; | 994 DVLOG(3) << "ServiceDeviceTask()"; |
971 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 995 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
972 DCHECK_NE(decoder_state_, kUninitialized); | 996 DCHECK_NE(decoder_state_, kUninitialized); |
973 DCHECK_NE(decoder_state_, kInitialized); | 997 DCHECK_NE(decoder_state_, kInitialized); |
974 DCHECK_NE(decoder_state_, kAfterReset); | 998 DCHECK_NE(decoder_state_, kAfterReset); |
975 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask"); | 999 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask"); |
976 | 1000 |
977 if (decoder_state_ == kResetting) { | 1001 if (decoder_state_ == kResetting) { |
978 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; | 1002 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; |
979 return; | 1003 return; |
980 } else if (decoder_state_ == kError) { | 1004 } else if (decoder_state_ == kError) { |
981 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; | 1005 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; |
982 return; | 1006 return; |
983 } else if (decoder_state_ == kChangingResolution) { | 1007 } else if (decoder_state_ == kChangingResolution) { |
984 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; | 1008 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; |
985 return; | 1009 return; |
986 } | 1010 } |
987 | 1011 |
988 if (mfc_event_pending) | 1012 if (mfc_event_pending) |
989 DequeueMfcEvents(); | 1013 DequeueMfcEvents(); |
990 DequeueMfc(); | 1014 DequeueMfc(); |
991 EnqueueMfc(); | 1015 EnqueueMfc(); |
992 | 1016 |
993 // Clear the interrupt fd. | 1017 // Clear the interrupt fd. |
994 if (!ClearDevicePollInterrupt()) | 1018 if (!device->ClearDevicePollInterrupt(device_poll_interrupt_fd_)) { |
1019 NOTIFY_ERROR(PLATFORM_FAILURE); | |
995 return; | 1020 return; |
1021 } | |
996 | 1022 |
997 unsigned int poll_fds = 0; | 1023 unsigned int poll_fds = 0; |
998 // Add MFC fd, if we should poll on it. | 1024 // Add MFC fd, if we should poll on it. |
999 // MFC can be polled as soon as either input or output buffers are queued. | 1025 // MFC can be polled as soon as either input or output buffers are queued. |
1000 if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0) | 1026 if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0) |
1001 poll_fds |= kPollMfc; | 1027 poll_fds |= kPollMfc; |
1002 | 1028 |
1003 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), | 1029 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), |
1004 // so either: | 1030 // so either: |
1005 // * device_poll_thread_ is running normally | 1031 // * device_poll_thread_ is running normally |
1006 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() | 1032 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() |
1007 // shut it down, in which case we're either in kResetting or kError states | 1033 // shut it down, in which case we're either in kResetting or kError states |
1008 // respectively, and we should have early-outed already. | 1034 // respectively, and we should have early-outed already. |
1009 DCHECK(device_poll_thread_.message_loop()); | 1035 DCHECK(device_poll_thread_.message_loop()); |
1010 // Queue the DevicePollTask() now. | 1036 // Queue the DevicePollTask() now. |
1011 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1037 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
1012 &ExynosVideoDecodeAccelerator::DevicePollTask, | 1038 &V4L2VideoDecodeAccelerator::DevicePollTask, |
1013 base::Unretained(this), | 1039 base::Unretained(this), |
1014 poll_fds)); | 1040 poll_fds)); |
1015 | 1041 |
1016 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" | 1042 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" |
1017 << decoder_input_queue_.size() << "->" | 1043 << decoder_input_queue_.size() << "->" |
1018 << mfc_input_ready_queue_.size() << "] => MFC[" | 1044 << mfc_input_ready_queue_.size() << "] => MFC[" |
1019 << mfc_free_input_buffers_.size() << "+" | 1045 << mfc_free_input_buffers_.size() << "+" |
1020 << mfc_input_buffer_queued_count_ << "/" | 1046 << mfc_input_buffer_queued_count_ << "/" |
1021 << mfc_input_buffer_map_.size() << "->" | 1047 << mfc_input_buffer_map_.size() << "->" |
1022 << mfc_free_output_buffers_.size() << "+" | 1048 << mfc_free_output_buffers_.size() << "+" |
1023 << mfc_output_buffer_queued_count_ << "/" | 1049 << mfc_output_buffer_queued_count_ << "/" |
1024 << mfc_output_buffer_map_.size() << "] => VDA[" | 1050 << mfc_output_buffer_map_.size() << "] => VDA[" |
1025 << decoder_frames_at_client_ << "]"; | 1051 << decoder_frames_at_client_ << "]"; |
1026 | 1052 |
1027 ScheduleDecodeBufferTaskIfNeeded(); | 1053 ScheduleDecodeBufferTaskIfNeeded(); |
1028 StartResolutionChangeIfNeeded(); | 1054 StartResolutionChangeIfNeeded(); |
1029 } | 1055 } |
1030 | 1056 |
1031 void ExynosVideoDecodeAccelerator::EnqueueMfc() { | 1057 void V4L2VideoDecodeAccelerator::EnqueueMfc() { |
1032 DVLOG(3) << "EnqueueMfc()"; | 1058 DVLOG(3) << "EnqueueMfc()"; |
1033 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1059 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1034 DCHECK_NE(decoder_state_, kUninitialized); | 1060 DCHECK_NE(decoder_state_, kUninitialized); |
1035 TRACE_EVENT0("Video Decoder", "EVDA::EnqueueMfc"); | 1061 TRACE_EVENT0("Video Decoder", "EVDA::EnqueueMfc"); |
1036 | 1062 |
1037 // Drain the pipe of completed decode buffers. | 1063 // Drain the pipe of completed decode buffers. |
1038 const int old_mfc_inputs_queued = mfc_input_buffer_queued_count_; | 1064 const int old_mfc_inputs_queued = mfc_input_buffer_queued_count_; |
1039 while (!mfc_input_ready_queue_.empty()) { | 1065 while (!mfc_input_ready_queue_.empty()) { |
1040 if (!EnqueueMfcInputRecord()) | 1066 if (!EnqueueMfcInputRecord()) |
1041 return; | 1067 return; |
1042 } | 1068 } |
1043 if (old_mfc_inputs_queued == 0 && mfc_input_buffer_queued_count_ != 0) { | 1069 if (old_mfc_inputs_queued == 0 && mfc_input_buffer_queued_count_ != 0) { |
1044 // We just started up a previously empty queue. | 1070 // We just started up a previously empty queue. |
1045 // Queue state changed; signal interrupt. | 1071 // Queue state changed; signal interrupt. |
1046 if (!SetDevicePollInterrupt()) | 1072 if (!device->SetDevicePollInterrupt(device_poll_interrupt_fd_)) { |
1073 NOTIFY_ERROR(PLATFORM_FAILURE); | |
1047 return; | 1074 return; |
1075 } | |
1048 // Start VIDIOC_STREAMON if we haven't yet. | 1076 // Start VIDIOC_STREAMON if we haven't yet. |
1049 if (!mfc_input_streamon_) { | 1077 if (!mfc_input_streamon_) { |
1050 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1078 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1051 IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type); | 1079 IOCTL_OR_ERROR_RETURN(videodec_fd_, VIDIOC_STREAMON, &type); |
1052 mfc_input_streamon_ = true; | 1080 mfc_input_streamon_ = true; |
1053 } | 1081 } |
1054 } | 1082 } |
1055 | 1083 |
1056 // Enqueue all the MFC outputs we can. | 1084 // Enqueue all the MFC outputs we can. |
1057 const int old_mfc_outputs_queued = mfc_output_buffer_queued_count_; | 1085 const int old_mfc_outputs_queued = mfc_output_buffer_queued_count_; |
1058 while (!mfc_free_output_buffers_.empty()) { | 1086 while (!mfc_free_output_buffers_.empty()) { |
1059 if (!EnqueueMfcOutputRecord()) | 1087 if (!EnqueueMfcOutputRecord()) |
1060 return; | 1088 return; |
1061 } | 1089 } |
1062 if (old_mfc_outputs_queued == 0 && mfc_output_buffer_queued_count_ != 0) { | 1090 if (old_mfc_outputs_queued == 0 && mfc_output_buffer_queued_count_ != 0) { |
1063 // We just started up a previously empty queue. | 1091 // We just started up a previously empty queue. |
1064 // Queue state changed; signal interrupt. | 1092 // Queue state changed; signal interrupt. |
1065 if (!SetDevicePollInterrupt()) | 1093 if (!device->SetDevicePollInterrupt(device_poll_interrupt_fd_)) { |
1094 NOTIFY_ERROR(PLATFORM_FAILURE); | |
1066 return; | 1095 return; |
1096 } | |
1067 // Start VIDIOC_STREAMON if we haven't yet. | 1097 // Start VIDIOC_STREAMON if we haven't yet. |
1068 if (!mfc_output_streamon_) { | 1098 if (!mfc_output_streamon_) { |
1069 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1099 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1070 IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type); | 1100 IOCTL_OR_ERROR_RETURN(videodec_fd_, VIDIOC_STREAMON, &type); |
1071 mfc_output_streamon_ = true; | 1101 mfc_output_streamon_ = true; |
1072 } | 1102 } |
1073 } | 1103 } |
1074 } | 1104 } |
1075 | 1105 |
1076 void ExynosVideoDecodeAccelerator::DequeueMfcEvents() { | 1106 void V4L2VideoDecodeAccelerator::DequeueMfcEvents() { |
1077 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1107 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1078 DCHECK_NE(decoder_state_, kUninitialized); | 1108 DCHECK_NE(decoder_state_, kUninitialized); |
1079 DVLOG(3) << "DequeueMfcEvents()"; | 1109 DVLOG(3) << "DequeueMfcEvents()"; |
1080 | 1110 |
1081 struct v4l2_event ev; | 1111 struct v4l2_event ev; |
1082 memset(&ev, 0, sizeof(ev)); | 1112 memset(&ev, 0, sizeof(ev)); |
1083 | 1113 |
1084 while (ioctl(mfc_fd_, VIDIOC_DQEVENT, &ev) == 0) { | 1114 while (device->dev_ioctl(videodec_fd_, VIDIOC_DQEVENT, &ev) == 0) { |
1085 if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) { | 1115 if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) { |
1086 DVLOG(3) << "DequeueMfcEvents(): got resolution change event."; | 1116 DVLOG(3) << "DequeueMfcEvents(): got resolution change event."; |
1087 DCHECK(!resolution_change_pending_); | 1117 DCHECK(!resolution_change_pending_); |
1088 resolution_change_pending_ = true; | 1118 resolution_change_pending_ = true; |
1089 } else { | 1119 } else { |
1090 DLOG(FATAL) << "DequeueMfcEvents(): got an event (" << ev.type | 1120 DLOG(FATAL) << "DequeueMfcEvents(): got an event (" << ev.type |
1091 << ") we haven't subscribed to."; | 1121 << ") we haven't subscribed to."; |
1092 } | 1122 } |
1093 } | 1123 } |
1094 } | 1124 } |
1095 | 1125 |
1096 void ExynosVideoDecodeAccelerator::DequeueMfc() { | 1126 void V4L2VideoDecodeAccelerator::DequeueMfc() { |
1097 DVLOG(3) << "DequeueMfc()"; | 1127 DVLOG(3) << "DequeueMfc()"; |
1098 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1128 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1099 DCHECK_NE(decoder_state_, kUninitialized); | 1129 DCHECK_NE(decoder_state_, kUninitialized); |
1100 TRACE_EVENT0("Video Decoder", "EVDA::DequeueMfc"); | 1130 TRACE_EVENT0("Video Decoder", "EVDA::DequeueMfc"); |
1101 | 1131 |
1102 // Dequeue completed MFC input (VIDEO_OUTPUT) buffers, and recycle to the free | 1132 // Dequeue completed MFC input (VIDEO_OUTPUT) buffers, and recycle to the free |
1103 // list. | 1133 // list. |
1104 struct v4l2_buffer dqbuf; | 1134 struct v4l2_buffer dqbuf; |
1105 struct v4l2_plane planes[2]; | 1135 struct v4l2_plane planes[2]; |
1106 while (mfc_input_buffer_queued_count_ > 0) { | 1136 while (mfc_input_buffer_queued_count_ > 0) { |
1107 DCHECK(mfc_input_streamon_); | 1137 DCHECK(mfc_input_streamon_); |
1108 memset(&dqbuf, 0, sizeof(dqbuf)); | 1138 memset(&dqbuf, 0, sizeof(dqbuf)); |
1109 memset(planes, 0, sizeof(planes)); | 1139 memset(planes, 0, sizeof(planes)); |
1110 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1140 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1111 dqbuf.memory = V4L2_MEMORY_MMAP; | 1141 dqbuf.memory = V4L2_MEMORY_MMAP; |
1112 dqbuf.m.planes = planes; | 1142 dqbuf.m.planes = planes; |
1113 dqbuf.length = 1; | 1143 dqbuf.length = 1; |
1114 if (ioctl(mfc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) { | 1144 if (device->dev_ioctl(videodec_fd_, VIDIOC_DQBUF, &dqbuf) != 0) { |
1115 if (errno == EAGAIN) { | 1145 if (errno == EAGAIN) { |
1116 // EAGAIN if we're just out of buffers to dequeue. | 1146 // EAGAIN if we're just out of buffers to dequeue. |
1117 break; | 1147 break; |
1118 } | 1148 } |
1119 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF"; | 1149 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF"; |
1120 NOTIFY_ERROR(PLATFORM_FAILURE); | 1150 NOTIFY_ERROR(PLATFORM_FAILURE); |
1121 return; | 1151 return; |
1122 } | 1152 } |
1123 MfcInputRecord& input_record = mfc_input_buffer_map_[dqbuf.index]; | 1153 MfcInputRecord& input_record = mfc_input_buffer_map_[dqbuf.index]; |
1124 DCHECK(input_record.at_device); | 1154 DCHECK(input_record.at_device); |
1125 mfc_free_input_buffers_.push_back(dqbuf.index); | 1155 mfc_free_input_buffers_.push_back(dqbuf.index); |
1126 input_record.at_device = false; | 1156 input_record.at_device = false; |
1127 input_record.bytes_used = 0; | 1157 input_record.bytes_used = 0; |
1128 input_record.input_id = -1; | 1158 input_record.input_id = -1; |
1129 mfc_input_buffer_queued_count_--; | 1159 mfc_input_buffer_queued_count_--; |
1130 } | 1160 } |
1131 | 1161 |
1132 // Dequeue completed MFC output (VIDEO_CAPTURE) buffers, and queue to the | 1162 // Dequeue completed MFC output (VIDEO_CAPTURE) buffers, and queue to the |
1133 // completed queue. | 1163 // completed queue. |
1134 while (mfc_output_buffer_queued_count_ > 0) { | 1164 while (mfc_output_buffer_queued_count_ > 0) { |
1135 DCHECK(mfc_output_streamon_); | 1165 DCHECK(mfc_output_streamon_); |
1136 memset(&dqbuf, 0, sizeof(dqbuf)); | 1166 memset(&dqbuf, 0, sizeof(dqbuf)); |
1137 memset(planes, 0, sizeof(planes)); | 1167 memset(planes, 0, sizeof(planes)); |
1138 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1168 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1139 dqbuf.memory = V4L2_MEMORY_MMAP; | 1169 dqbuf.memory = V4L2_MEMORY_MMAP; |
1140 dqbuf.m.planes = planes; | 1170 dqbuf.m.planes = planes; |
1141 dqbuf.length = 2; | 1171 dqbuf.length = 2; |
1142 if (ioctl(mfc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) { | 1172 if (device->dev_ioctl(videodec_fd_, VIDIOC_DQBUF, &dqbuf) != 0) { |
1143 if (errno == EAGAIN) { | 1173 if (errno == EAGAIN) { |
1144 // EAGAIN if we're just out of buffers to dequeue. | 1174 // EAGAIN if we're just out of buffers to dequeue. |
1145 break; | 1175 break; |
1146 } | 1176 } |
1147 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF"; | 1177 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF"; |
1148 NOTIFY_ERROR(PLATFORM_FAILURE); | 1178 NOTIFY_ERROR(PLATFORM_FAILURE); |
1149 return; | 1179 return; |
1150 } | 1180 } |
1151 MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index]; | 1181 MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index]; |
1152 DCHECK(output_record.at_device); | 1182 DCHECK(output_record.at_device); |
(...skipping 16 matching lines...) Expand all Loading... | |
1169 SendPictureReady(); | 1199 SendPictureReady(); |
1170 output_record.cleared = true; | 1200 output_record.cleared = true; |
1171 decoder_frames_at_client_++; | 1201 decoder_frames_at_client_++; |
1172 } | 1202 } |
1173 mfc_output_buffer_queued_count_--; | 1203 mfc_output_buffer_queued_count_--; |
1174 } | 1204 } |
1175 | 1205 |
1176 NotifyFlushDoneIfNeeded(); | 1206 NotifyFlushDoneIfNeeded(); |
1177 } | 1207 } |
1178 | 1208 |
1179 bool ExynosVideoDecodeAccelerator::EnqueueMfcInputRecord() { | 1209 bool V4L2VideoDecodeAccelerator::EnqueueMfcInputRecord() { |
1180 DVLOG(3) << "EnqueueMfcInputRecord()"; | 1210 DVLOG(3) << "EnqueueMfcInputRecord()"; |
1181 DCHECK(!mfc_input_ready_queue_.empty()); | 1211 DCHECK(!mfc_input_ready_queue_.empty()); |
1182 | 1212 |
1183 // Enqueue a MFC input (VIDEO_OUTPUT) buffer. | 1213 // Enqueue a MFC input (VIDEO_OUTPUT) buffer. |
1184 const int buffer = mfc_input_ready_queue_.front(); | 1214 const int buffer = mfc_input_ready_queue_.front(); |
1185 MfcInputRecord& input_record = mfc_input_buffer_map_[buffer]; | 1215 MfcInputRecord& input_record = mfc_input_buffer_map_[buffer]; |
1186 DCHECK(!input_record.at_device); | 1216 DCHECK(!input_record.at_device); |
1187 struct v4l2_buffer qbuf; | 1217 struct v4l2_buffer qbuf; |
1188 struct v4l2_plane qbuf_plane; | 1218 struct v4l2_plane qbuf_plane; |
1189 memset(&qbuf, 0, sizeof(qbuf)); | 1219 memset(&qbuf, 0, sizeof(qbuf)); |
1190 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); | 1220 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); |
1191 qbuf.index = buffer; | 1221 qbuf.index = buffer; |
1192 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1222 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1193 qbuf.timestamp.tv_sec = input_record.input_id; | 1223 qbuf.timestamp.tv_sec = input_record.input_id; |
1194 qbuf.memory = V4L2_MEMORY_MMAP; | 1224 qbuf.memory = V4L2_MEMORY_MMAP; |
1195 qbuf.m.planes = &qbuf_plane; | 1225 qbuf.m.planes = &qbuf_plane; |
1196 qbuf.m.planes[0].bytesused = input_record.bytes_used; | 1226 qbuf.m.planes[0].bytesused = input_record.bytes_used; |
1197 qbuf.length = 1; | 1227 qbuf.length = 1; |
1198 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf); | 1228 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_QBUF, &qbuf); |
1199 mfc_input_ready_queue_.pop(); | 1229 mfc_input_ready_queue_.pop(); |
1200 input_record.at_device = true; | 1230 input_record.at_device = true; |
1201 mfc_input_buffer_queued_count_++; | 1231 mfc_input_buffer_queued_count_++; |
1202 DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id=" | 1232 DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id=" |
1203 << input_record.input_id; | 1233 << input_record.input_id; |
1204 return true; | 1234 return true; |
1205 } | 1235 } |
1206 | 1236 |
1207 bool ExynosVideoDecodeAccelerator::EnqueueMfcOutputRecord() { | 1237 bool V4L2VideoDecodeAccelerator::EnqueueMfcOutputRecord() { |
1208 DVLOG(3) << "EnqueueMfcOutputRecord()"; | 1238 DVLOG(3) << "EnqueueMfcOutputRecord()"; |
1209 DCHECK(!mfc_free_output_buffers_.empty()); | 1239 DCHECK(!mfc_free_output_buffers_.empty()); |
1210 | 1240 |
1211 // Enqueue a MFC output (VIDEO_CAPTURE) buffer. | 1241 // Enqueue a MFC output (VIDEO_CAPTURE) buffer. |
1212 const int buffer = mfc_free_output_buffers_.front(); | 1242 const int buffer = mfc_free_output_buffers_.front(); |
1213 MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer]; | 1243 MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer]; |
1214 DCHECK(!output_record.at_device); | 1244 DCHECK(!output_record.at_device); |
1215 DCHECK(!output_record.at_client); | 1245 DCHECK(!output_record.at_client); |
1216 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR); | 1246 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR); |
1217 DCHECK_NE(output_record.picture_id, -1); | 1247 DCHECK_NE(output_record.picture_id, -1); |
(...skipping 10 matching lines...) Expand all Loading... | |
1228 } | 1258 } |
1229 struct v4l2_buffer qbuf; | 1259 struct v4l2_buffer qbuf; |
1230 struct v4l2_plane qbuf_planes[arraysize(output_record.fds)]; | 1260 struct v4l2_plane qbuf_planes[arraysize(output_record.fds)]; |
1231 memset(&qbuf, 0, sizeof(qbuf)); | 1261 memset(&qbuf, 0, sizeof(qbuf)); |
1232 memset(qbuf_planes, 0, sizeof(qbuf_planes)); | 1262 memset(qbuf_planes, 0, sizeof(qbuf_planes)); |
1233 qbuf.index = buffer; | 1263 qbuf.index = buffer; |
1234 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1264 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1235 qbuf.memory = V4L2_MEMORY_MMAP; | 1265 qbuf.memory = V4L2_MEMORY_MMAP; |
1236 qbuf.m.planes = qbuf_planes; | 1266 qbuf.m.planes = qbuf_planes; |
1237 qbuf.length = arraysize(output_record.fds); | 1267 qbuf.length = arraysize(output_record.fds); |
1238 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf); | 1268 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_QBUF, &qbuf); |
1239 mfc_free_output_buffers_.pop(); | 1269 mfc_free_output_buffers_.pop(); |
1240 output_record.at_device = true; | 1270 output_record.at_device = true; |
1241 mfc_output_buffer_queued_count_++; | 1271 mfc_output_buffer_queued_count_++; |
1242 return true; | 1272 return true; |
1243 } | 1273 } |
1244 | 1274 |
1245 void ExynosVideoDecodeAccelerator::ReusePictureBufferTask( | 1275 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask( |
1246 int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) { | 1276 int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) { |
1247 DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id=" | 1277 DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id=" |
1248 << picture_buffer_id; | 1278 << picture_buffer_id; |
1249 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1279 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1250 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask"); | 1280 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask"); |
1251 | 1281 |
1252 // We run ReusePictureBufferTask even if we're in kResetting. | 1282 // We run ReusePictureBufferTask even if we're in kResetting. |
1253 if (decoder_state_ == kError) { | 1283 if (decoder_state_ == kError) { |
1254 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state"; | 1284 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state"; |
1255 return; | 1285 return; |
(...skipping 26 matching lines...) Expand all Loading... | |
1282 output_record.at_client = false; | 1312 output_record.at_client = false; |
1283 output_record.egl_sync = egl_sync_ref->egl_sync; | 1313 output_record.egl_sync = egl_sync_ref->egl_sync; |
1284 mfc_free_output_buffers_.push(index); | 1314 mfc_free_output_buffers_.push(index); |
1285 decoder_frames_at_client_--; | 1315 decoder_frames_at_client_--; |
1286 // Take ownership of the EGLSync. | 1316 // Take ownership of the EGLSync. |
1287 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR; | 1317 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR; |
1288 // We got a buffer back, so kick the MFC. | 1318 // We got a buffer back, so kick the MFC. |
1289 EnqueueMfc(); | 1319 EnqueueMfc(); |
1290 } | 1320 } |
1291 | 1321 |
1292 void ExynosVideoDecodeAccelerator::FlushTask() { | 1322 void V4L2VideoDecodeAccelerator::FlushTask() { |
1293 DVLOG(3) << "FlushTask()"; | 1323 DVLOG(3) << "FlushTask()"; |
1294 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1324 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1295 TRACE_EVENT0("Video Decoder", "EVDA::FlushTask"); | 1325 TRACE_EVENT0("Video Decoder", "EVDA::FlushTask"); |
1296 | 1326 |
1297 // Flush outstanding buffers. | 1327 // Flush outstanding buffers. |
1298 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) { | 1328 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) { |
1299 // There's nothing in the pipe, so return done immediately. | 1329 // There's nothing in the pipe, so return done immediately. |
1300 DVLOG(3) << "FlushTask(): returning flush"; | 1330 DVLOG(3) << "FlushTask(): returning flush"; |
1301 child_message_loop_proxy_->PostTask( | 1331 child_message_loop_proxy_->PostTask( |
1302 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); | 1332 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); |
1303 return; | 1333 return; |
1304 } else if (decoder_state_ == kError) { | 1334 } else if (decoder_state_ == kError) { |
1305 DVLOG(2) << "FlushTask(): early out: kError state"; | 1335 DVLOG(2) << "FlushTask(): early out: kError state"; |
1306 return; | 1336 return; |
1307 } | 1337 } |
1308 | 1338 |
1309 // We don't support stacked flushing. | 1339 // We don't support stacked flushing. |
1310 DCHECK(!decoder_flushing_); | 1340 DCHECK(!decoder_flushing_); |
1311 | 1341 |
1312 // Queue up an empty buffer -- this triggers the flush. | 1342 // Queue up an empty buffer -- this triggers the flush. |
1313 decoder_input_queue_.push( | 1343 decoder_input_queue_.push( |
1314 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( | 1344 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( |
1315 io_client_, io_message_loop_proxy_, NULL, 0, kFlushBufferId))); | 1345 io_client_, io_message_loop_proxy_, NULL, 0, kFlushBufferId))); |
1316 decoder_flushing_ = true; | 1346 decoder_flushing_ = true; |
1317 SendPictureReady(); // Send all pending PictureReady. | 1347 SendPictureReady(); // Send all pending PictureReady. |
1318 | 1348 |
1319 ScheduleDecodeBufferTaskIfNeeded(); | 1349 ScheduleDecodeBufferTaskIfNeeded(); |
1320 } | 1350 } |
1321 | 1351 |
1322 void ExynosVideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { | 1352 void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { |
1323 if (!decoder_flushing_) | 1353 if (!decoder_flushing_) |
1324 return; | 1354 return; |
1325 | 1355 |
1326 // Pipeline is empty when: | 1356 // Pipeline is empty when: |
1327 // * Decoder input queue is empty of non-delayed buffers. | 1357 // * Decoder input queue is empty of non-delayed buffers. |
1328 // * There is no currently filling input buffer. | 1358 // * There is no currently filling input buffer. |
1329 // * MFC input holding queue is empty. | 1359 // * MFC input holding queue is empty. |
1330 // * All MFC input (VIDEO_OUTPUT) buffers are returned. | 1360 // * All MFC input (VIDEO_OUTPUT) buffers are returned. |
1331 if (!decoder_input_queue_.empty()) { | 1361 if (!decoder_input_queue_.empty()) { |
1332 if (decoder_input_queue_.front()->input_id != | 1362 if (decoder_input_queue_.front()->input_id != |
(...skipping 23 matching lines...) Expand all Loading... | |
1356 decoder_delay_bitstream_buffer_id_ = -1; | 1386 decoder_delay_bitstream_buffer_id_ = -1; |
1357 decoder_flushing_ = false; | 1387 decoder_flushing_ = false; |
1358 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush"; | 1388 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush"; |
1359 child_message_loop_proxy_->PostTask( | 1389 child_message_loop_proxy_->PostTask( |
1360 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); | 1390 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); |
1361 | 1391 |
1362 // While we were flushing, we early-outed DecodeBufferTask()s. | 1392 // While we were flushing, we early-outed DecodeBufferTask()s. |
1363 ScheduleDecodeBufferTaskIfNeeded(); | 1393 ScheduleDecodeBufferTaskIfNeeded(); |
1364 } | 1394 } |
1365 | 1395 |
1366 void ExynosVideoDecodeAccelerator::ResetTask() { | 1396 void V4L2VideoDecodeAccelerator::ResetTask() { |
1367 DVLOG(3) << "ResetTask()"; | 1397 DVLOG(3) << "ResetTask()"; |
1368 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1398 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1369 TRACE_EVENT0("Video Decoder", "EVDA::ResetTask"); | 1399 TRACE_EVENT0("Video Decoder", "EVDA::ResetTask"); |
1370 | 1400 |
1371 if (decoder_state_ == kError) { | 1401 if (decoder_state_ == kError) { |
1372 DVLOG(2) << "ResetTask(): early out: kError state"; | 1402 DVLOG(2) << "ResetTask(): early out: kError state"; |
1373 return; | 1403 return; |
1374 } | 1404 } |
1375 | 1405 |
1376 // If we are in the middle of switching resolutions, postpone reset until | 1406 // If we are in the middle of switching resolutions, postpone reset until |
(...skipping 20 matching lines...) Expand all Loading... | |
1397 | 1427 |
1398 // If we were flushing, we'll never return any more BitstreamBuffers or | 1428 // If we were flushing, we'll never return any more BitstreamBuffers or |
1399 // PictureBuffers; they have all been dropped and returned by now. | 1429 // PictureBuffers; they have all been dropped and returned by now. |
1400 NotifyFlushDoneIfNeeded(); | 1430 NotifyFlushDoneIfNeeded(); |
1401 | 1431 |
1402 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening | 1432 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening |
1403 // jobs will early-out in the kResetting state. | 1433 // jobs will early-out in the kResetting state. |
1404 decoder_state_ = kResetting; | 1434 decoder_state_ = kResetting; |
1405 SendPictureReady(); // Send all pending PictureReady. | 1435 SendPictureReady(); // Send all pending PictureReady. |
1406 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1436 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
1407 &ExynosVideoDecodeAccelerator::ResetDoneTask, base::Unretained(this))); | 1437 &V4L2VideoDecodeAccelerator::ResetDoneTask, base::Unretained(this))); |
1408 } | 1438 } |
1409 | 1439 |
1410 void ExynosVideoDecodeAccelerator::ResetDoneTask() { | 1440 void V4L2VideoDecodeAccelerator::ResetDoneTask() { |
1411 DVLOG(3) << "ResetDoneTask()"; | 1441 DVLOG(3) << "ResetDoneTask()"; |
1412 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1442 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1413 TRACE_EVENT0("Video Decoder", "EVDA::ResetDoneTask"); | 1443 TRACE_EVENT0("Video Decoder", "EVDA::ResetDoneTask"); |
1414 | 1444 |
1415 if (decoder_state_ == kError) { | 1445 if (decoder_state_ == kError) { |
1416 DVLOG(2) << "ResetDoneTask(): early out: kError state"; | 1446 DVLOG(2) << "ResetDoneTask(): early out: kError state"; |
1417 return; | 1447 return; |
1418 } | 1448 } |
1419 | 1449 |
1420 // We might have received a resolution change event while we were waiting | 1450 // We might have received a resolution change event while we were waiting |
(...skipping 13 matching lines...) Expand all Loading... | |
1434 decoder_state_ = kAfterReset; | 1464 decoder_state_ = kAfterReset; |
1435 decoder_partial_frame_pending_ = false; | 1465 decoder_partial_frame_pending_ = false; |
1436 decoder_delay_bitstream_buffer_id_ = -1; | 1466 decoder_delay_bitstream_buffer_id_ = -1; |
1437 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 1467 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
1438 &Client::NotifyResetDone, client_)); | 1468 &Client::NotifyResetDone, client_)); |
1439 | 1469 |
1440 // While we were resetting, we early-outed DecodeBufferTask()s. | 1470 // While we were resetting, we early-outed DecodeBufferTask()s. |
1441 ScheduleDecodeBufferTaskIfNeeded(); | 1471 ScheduleDecodeBufferTaskIfNeeded(); |
1442 } | 1472 } |
1443 | 1473 |
1444 void ExynosVideoDecodeAccelerator::DestroyTask() { | 1474 void V4L2VideoDecodeAccelerator::DestroyTask() { |
1445 DVLOG(3) << "DestroyTask()"; | 1475 DVLOG(3) << "DestroyTask()"; |
1446 TRACE_EVENT0("Video Decoder", "EVDA::DestroyTask"); | 1476 TRACE_EVENT0("Video Decoder", "EVDA::DestroyTask"); |
1447 | 1477 |
1448 // DestroyTask() should run regardless of decoder_state_. | 1478 // DestroyTask() should run regardless of decoder_state_. |
1449 | 1479 |
1450 // Stop streaming and the device_poll_thread_. | 1480 // Stop streaming and the device_poll_thread_. |
1451 StopDevicePoll(false); | 1481 StopDevicePoll(false); |
1452 | 1482 |
1453 decoder_current_bitstream_buffer_.reset(); | 1483 decoder_current_bitstream_buffer_.reset(); |
1454 decoder_current_input_buffer_ = -1; | 1484 decoder_current_input_buffer_ = -1; |
1455 decoder_decode_buffer_tasks_scheduled_ = 0; | 1485 decoder_decode_buffer_tasks_scheduled_ = 0; |
1456 decoder_frames_at_client_ = 0; | 1486 decoder_frames_at_client_ = 0; |
1457 while (!decoder_input_queue_.empty()) | 1487 while (!decoder_input_queue_.empty()) |
1458 decoder_input_queue_.pop(); | 1488 decoder_input_queue_.pop(); |
1459 decoder_flushing_ = false; | 1489 decoder_flushing_ = false; |
1460 | 1490 |
1461 // Set our state to kError. Just in case. | 1491 // Set our state to kError. Just in case. |
1462 decoder_state_ = kError; | 1492 decoder_state_ = kError; |
1463 } | 1493 } |
1464 | 1494 |
1465 bool ExynosVideoDecodeAccelerator::StartDevicePoll() { | 1495 bool V4L2VideoDecodeAccelerator::StartDevicePoll() { |
1466 DVLOG(3) << "StartDevicePoll()"; | 1496 DVLOG(3) << "StartDevicePoll()"; |
1467 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1497 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1468 DCHECK(!device_poll_thread_.IsRunning()); | 1498 DCHECK(!device_poll_thread_.IsRunning()); |
1469 | 1499 |
1470 // Start up the device poll thread and schedule its first DevicePollTask(). | 1500 // Start up the device poll thread and schedule its first DevicePollTask(). |
1471 if (!device_poll_thread_.Start()) { | 1501 if (!device_poll_thread_.Start()) { |
1472 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; | 1502 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; |
1473 NOTIFY_ERROR(PLATFORM_FAILURE); | 1503 NOTIFY_ERROR(PLATFORM_FAILURE); |
1474 return false; | 1504 return false; |
1475 } | 1505 } |
1476 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1506 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
1477 &ExynosVideoDecodeAccelerator::DevicePollTask, | 1507 &V4L2VideoDecodeAccelerator::DevicePollTask, |
1478 base::Unretained(this), | 1508 base::Unretained(this), |
1479 0)); | 1509 0)); |
1480 | 1510 |
1481 return true; | 1511 return true; |
1482 } | 1512 } |
1483 | 1513 |
1484 bool ExynosVideoDecodeAccelerator::StopDevicePoll(bool keep_mfc_input_state) { | 1514 bool V4L2VideoDecodeAccelerator::StopDevicePoll(bool keep_mfc_input_state) { |
1485 DVLOG(3) << "StopDevicePoll()"; | 1515 DVLOG(3) << "StopDevicePoll()"; |
1486 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1516 if (decoder_thread_.IsRunning()) |
1517 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
1487 | 1518 |
1488 // Signal the DevicePollTask() to stop, and stop the device poll thread. | 1519 // Signal the DevicePollTask() to stop, and stop the device poll thread. |
1489 if (!SetDevicePollInterrupt()) | 1520 if (!device->SetDevicePollInterrupt(device_poll_interrupt_fd_)) { |
1521 NOTIFY_ERROR(PLATFORM_FAILURE); | |
1490 return false; | 1522 return false; |
1523 } | |
1491 device_poll_thread_.Stop(); | 1524 device_poll_thread_.Stop(); |
1492 // Clear the interrupt now, to be sure. | 1525 // Clear the interrupt now, to be sure. |
1493 if (!ClearDevicePollInterrupt()) | 1526 if (!device->ClearDevicePollInterrupt(device_poll_interrupt_fd_)) { |
1527 NOTIFY_ERROR(PLATFORM_FAILURE); | |
1494 return false; | 1528 return false; |
1529 } | |
1495 | 1530 |
1496 // Stop streaming. | 1531 // Stop streaming. |
1497 if (!keep_mfc_input_state) { | 1532 if (!keep_mfc_input_state) { |
1498 if (mfc_input_streamon_) { | 1533 if (mfc_input_streamon_) { |
1499 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1534 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1500 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); | 1535 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_STREAMOFF, &type); |
1501 } | 1536 } |
1502 mfc_input_streamon_ = false; | 1537 mfc_input_streamon_ = false; |
1503 } | 1538 } |
1504 if (mfc_output_streamon_) { | 1539 if (mfc_output_streamon_) { |
1505 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1540 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1506 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); | 1541 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_STREAMOFF, &type); |
1507 } | 1542 } |
1508 mfc_output_streamon_ = false; | 1543 mfc_output_streamon_ = false; |
1509 | 1544 |
1510 // Reset all our accounting info. | 1545 // Reset all our accounting info. |
1511 if (!keep_mfc_input_state) { | 1546 if (!keep_mfc_input_state) { |
1512 while (!mfc_input_ready_queue_.empty()) | 1547 while (!mfc_input_ready_queue_.empty()) |
1513 mfc_input_ready_queue_.pop(); | 1548 mfc_input_ready_queue_.pop(); |
1514 mfc_free_input_buffers_.clear(); | 1549 mfc_free_input_buffers_.clear(); |
1515 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { | 1550 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { |
1516 mfc_free_input_buffers_.push_back(i); | 1551 mfc_free_input_buffers_.push_back(i); |
(...skipping 13 matching lines...) Expand all Loading... | |
1530 mfc_free_output_buffers_.push(i); | 1565 mfc_free_output_buffers_.push(i); |
1531 mfc_output_buffer_map_[i].at_device = false; | 1566 mfc_output_buffer_map_[i].at_device = false; |
1532 } | 1567 } |
1533 } | 1568 } |
1534 mfc_output_buffer_queued_count_ = 0; | 1569 mfc_output_buffer_queued_count_ = 0; |
1535 | 1570 |
1536 DVLOG(3) << "StopDevicePoll(): device poll stopped"; | 1571 DVLOG(3) << "StopDevicePoll(): device poll stopped"; |
1537 return true; | 1572 return true; |
1538 } | 1573 } |
1539 | 1574 |
1540 bool ExynosVideoDecodeAccelerator::SetDevicePollInterrupt() { | 1575 bool V4L2VideoDecodeAccelerator:: ExynosV4L2Device :: SetDevicePollInterrupt(int fd) { |
Pawel Osciak
2013/12/24 03:45:24
Please keep methods of one class together (althoug
| |
1541 DVLOG(3) << "SetDevicePollInterrupt()"; | 1576 DVLOG(3) << "SetDevicePollInterrupt()"; |
1542 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
1543 | 1577 |
1544 const uint64 buf = 1; | 1578 const uint64 buf = 1; |
1545 if (HANDLE_EINTR(write(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) { | 1579 if (HANDLE_EINTR(write(fd, &buf, sizeof(buf))) == -1) { |
1546 DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed"; | 1580 DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed"; |
1547 NOTIFY_ERROR(PLATFORM_FAILURE); | |
1548 return false; | 1581 return false; |
1549 } | 1582 } |
1550 return true; | 1583 return true; |
1551 } | 1584 } |
1552 | 1585 |
1553 bool ExynosVideoDecodeAccelerator::ClearDevicePollInterrupt() { | 1586 bool V4L2VideoDecodeAccelerator:: ExynosV4L2Device :: ClearDevicePollInterrupt(i nt fd) { |
1554 DVLOG(3) << "ClearDevicePollInterrupt()"; | 1587 DVLOG(3) << "ClearDevicePollInterrupt()"; |
1555 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
1556 | 1588 |
1557 uint64 buf; | 1589 uint64 buf; |
1558 if (HANDLE_EINTR(read(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) { | 1590 if (HANDLE_EINTR(read(fd, &buf, sizeof(buf))) == -1) { |
1559 if (errno == EAGAIN) { | 1591 if (errno == EAGAIN) { |
1560 // No interrupt flag set, and we're reading nonblocking. Not an error. | 1592 // No interrupt flag set, and we're reading nonblocking. Not an error. |
1561 return true; | 1593 return true; |
1562 } else { | 1594 } else { |
1563 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed"; | 1595 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed"; |
1564 NOTIFY_ERROR(PLATFORM_FAILURE); | |
1565 return false; | 1596 return false; |
1566 } | 1597 } |
1567 } | 1598 } |
1568 return true; | 1599 return true; |
1569 } | 1600 } |
1570 | 1601 |
1571 void ExynosVideoDecodeAccelerator::StartResolutionChangeIfNeeded() { | 1602 void V4L2VideoDecodeAccelerator::StartResolutionChangeIfNeeded() { |
1572 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1603 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1573 DCHECK_EQ(decoder_state_, kDecoding); | 1604 DCHECK_EQ(decoder_state_, kDecoding); |
1574 | 1605 |
1575 if (!resolution_change_pending_) | 1606 if (!resolution_change_pending_) |
1576 return; | 1607 return; |
1577 | 1608 |
1578 DVLOG(3) << "No more work, initiate resolution change"; | 1609 DVLOG(3) << "No more work, initiate resolution change"; |
1579 | 1610 |
1580 // Keep MFC input queue. | 1611 // Keep MFC input queue. |
1581 if (!StopDevicePoll(true)) | 1612 if (!StopDevicePoll(true)) |
1582 return; | 1613 return; |
1583 | 1614 |
1584 decoder_state_ = kChangingResolution; | 1615 decoder_state_ = kChangingResolution; |
1585 DCHECK(resolution_change_pending_); | 1616 DCHECK(resolution_change_pending_); |
1586 resolution_change_pending_ = false; | 1617 resolution_change_pending_ = false; |
1587 | 1618 |
1588 // Post a task to clean up buffers on child thread. This will also ensure | 1619 // Post a task to clean up buffers on child thread. This will also ensure |
1589 // that we won't accept ReusePictureBuffer() anymore after that. | 1620 // that we won't accept ReusePictureBuffer() anymore after that. |
1590 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 1621 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
1591 &ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers, | 1622 &V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers, |
1592 weak_this_)); | 1623 weak_this_)); |
1593 } | 1624 } |
1594 | 1625 |
1595 void ExynosVideoDecodeAccelerator::FinishResolutionChange() { | 1626 void V4L2VideoDecodeAccelerator::FinishResolutionChange() { |
1596 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1627 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1597 DVLOG(3) << "FinishResolutionChange()"; | 1628 DVLOG(3) << "FinishResolutionChange()"; |
1598 | 1629 |
1599 if (decoder_state_ == kError) { | 1630 if (decoder_state_ == kError) { |
1600 DVLOG(2) << "FinishResolutionChange(): early out: kError state"; | 1631 DVLOG(2) << "FinishResolutionChange(): early out: kError state"; |
1601 return; | 1632 return; |
1602 } | 1633 } |
1603 | 1634 |
1604 struct v4l2_format format; | 1635 struct v4l2_format format; |
1605 bool again; | 1636 bool again; |
1606 bool ret = GetFormatInfo(&format, &again); | 1637 bool ret = GetFormatInfo(&format, &again); |
1607 if (!ret || again) { | 1638 if (!ret || again) { |
1608 DVLOG(3) << "Couldn't get format information after resolution change"; | 1639 DVLOG(3) << "Couldn't get format information after resolution change"; |
1609 NOTIFY_ERROR(PLATFORM_FAILURE); | 1640 NOTIFY_ERROR(PLATFORM_FAILURE); |
1610 return; | 1641 return; |
1611 } | 1642 } |
1612 | 1643 |
1613 if (!CreateBuffersForFormat(format)) { | 1644 if (!CreateBuffersForFormat(format)) { |
1614 DVLOG(3) << "Couldn't reallocate buffers after resolution change"; | 1645 DVLOG(3) << "Couldn't reallocate buffers after resolution change"; |
1615 NOTIFY_ERROR(PLATFORM_FAILURE); | 1646 NOTIFY_ERROR(PLATFORM_FAILURE); |
1616 return; | 1647 return; |
1617 } | 1648 } |
1618 | 1649 |
1619 // From here we stay in kChangingResolution and wait for | 1650 // From here we stay in kChangingResolution and wait for |
1620 // AssignPictureBuffers() before we can resume. | 1651 // AssignPictureBuffers() before we can resume. |
1621 } | 1652 } |
1622 | 1653 |
1623 void ExynosVideoDecodeAccelerator::ResumeAfterResolutionChange() { | 1654 void V4L2VideoDecodeAccelerator::ResumeAfterResolutionChange() { |
1624 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1655 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1625 DVLOG(3) << "ResumeAfterResolutionChange()"; | 1656 DVLOG(3) << "ResumeAfterResolutionChange()"; |
1626 | 1657 |
1627 decoder_state_ = kDecoding; | 1658 decoder_state_ = kDecoding; |
1628 | 1659 |
1629 if (resolution_change_reset_pending_) { | 1660 if (resolution_change_reset_pending_) { |
1630 resolution_change_reset_pending_ = false; | 1661 resolution_change_reset_pending_ = false; |
1631 ResetTask(); | 1662 ResetTask(); |
1632 return; | 1663 return; |
1633 } | 1664 } |
1634 | 1665 |
1635 if (!StartDevicePoll()) | 1666 if (!StartDevicePoll()) |
1636 return; | 1667 return; |
1637 | 1668 |
1638 EnqueueMfc(); | 1669 EnqueueMfc(); |
1639 ScheduleDecodeBufferTaskIfNeeded(); | 1670 ScheduleDecodeBufferTaskIfNeeded(); |
1640 } | 1671 } |
1641 | 1672 |
1642 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) { | 1673 void V4L2VideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) { |
1643 DVLOG(3) << "DevicePollTask()"; | 1674 DVLOG(3) << "DevicePollTask()"; |
1644 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); | 1675 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); |
1645 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask"); | 1676 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask"); |
1646 | 1677 |
1647 // This routine just polls the set of device fds, and schedules a | 1678 // This routine just polls the set of device fds, and schedules a |
1648 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur. | 1679 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur. |
1649 // Other threads may notify this task to return early by writing to | 1680 // Other threads may notify this task to return early by writing to |
1650 // device_poll_interrupt_fd_. | 1681 // device_poll_interrupt_fd_. |
1651 struct pollfd pollfds[3]; | 1682 struct pollfd pollfds[3]; |
1652 nfds_t nfds; | 1683 nfds_t nfds; |
1653 int mfc_pollfd = -1; | 1684 int mfc_pollfd = -1; |
1654 | 1685 |
1655 // Add device_poll_interrupt_fd_; | 1686 // Add device_poll_interrupt_fd_; |
1656 pollfds[0].fd = device_poll_interrupt_fd_; | 1687 pollfds[0].fd = device_poll_interrupt_fd_; |
1657 pollfds[0].events = POLLIN | POLLERR; | 1688 pollfds[0].events = POLLIN | POLLERR; |
1658 nfds = 1; | 1689 nfds = 1; |
1659 | 1690 |
1660 if (poll_fds & kPollMfc) { | 1691 if (poll_fds & kPollMfc) { |
1661 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set"; | 1692 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set"; |
1662 pollfds[nfds].fd = mfc_fd_; | 1693 pollfds[nfds].fd = videodec_fd_; |
1663 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI; | 1694 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI; |
1664 mfc_pollfd = nfds; | 1695 mfc_pollfd = nfds; |
1665 nfds++; | 1696 nfds++; |
1666 } | 1697 } |
1667 | 1698 |
1668 // Poll it! | 1699 // Poll it! |
1669 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) { | 1700 if (HANDLE_EINTR(device->dev_poll(pollfds, nfds, -1)) == -1) { |
1670 DPLOG(ERROR) << "DevicePollTask(): poll() failed"; | 1701 DPLOG(ERROR) << "DevicePollTask(): poll() failed"; |
1671 NOTIFY_ERROR(PLATFORM_FAILURE); | 1702 NOTIFY_ERROR(PLATFORM_FAILURE); |
1672 return; | 1703 return; |
1673 } | 1704 } |
1674 | 1705 |
1675 bool mfc_event_pending = (mfc_pollfd != -1 && | 1706 bool mfc_event_pending = (mfc_pollfd != -1 && |
1676 pollfds[mfc_pollfd].revents & POLLPRI); | 1707 pollfds[mfc_pollfd].revents & POLLPRI); |
1677 | 1708 |
1678 // All processing should happen on ServiceDeviceTask(), since we shouldn't | 1709 // All processing should happen on ServiceDeviceTask(), since we shouldn't |
1679 // touch decoder state from this thread. | 1710 // touch decoder state from this thread. |
1680 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1711 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
1681 &ExynosVideoDecodeAccelerator::ServiceDeviceTask, | 1712 &V4L2VideoDecodeAccelerator::ServiceDeviceTask, |
1682 base::Unretained(this), mfc_event_pending)); | 1713 base::Unretained(this), mfc_event_pending)); |
1683 } | 1714 } |
1684 | 1715 |
1685 void ExynosVideoDecodeAccelerator::NotifyError(Error error) { | 1716 void V4L2VideoDecodeAccelerator::NotifyError(Error error) { |
1686 DVLOG(2) << "NotifyError()"; | 1717 DVLOG(2) << "NotifyError()"; |
1687 | 1718 |
1688 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { | 1719 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { |
1689 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 1720 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
1690 &ExynosVideoDecodeAccelerator::NotifyError, weak_this_, error)); | 1721 &V4L2VideoDecodeAccelerator::NotifyError, weak_this_, error)); |
1691 return; | 1722 return; |
1692 } | 1723 } |
1693 | 1724 |
1694 if (client_) { | 1725 if (client_) { |
1695 client_->NotifyError(error); | 1726 client_->NotifyError(error); |
1696 client_ptr_factory_.InvalidateWeakPtrs(); | 1727 client_ptr_factory_.InvalidateWeakPtrs(); |
1697 } | 1728 } |
1698 } | 1729 } |
1699 | 1730 |
1700 void ExynosVideoDecodeAccelerator::SetDecoderState(State state) { | 1731 void V4L2VideoDecodeAccelerator::SetDecoderState(State state) { |
1701 DVLOG(3) << "SetDecoderState(): state=" << state; | 1732 DVLOG(3) << "SetDecoderState(): state=" << state; |
1702 | 1733 |
1703 // We can touch decoder_state_ only if this is the decoder thread or the | 1734 // We can touch decoder_state_ only if this is the decoder thread or the |
1704 // decoder thread isn't running. | 1735 // decoder thread isn't running. |
1705 if (decoder_thread_.message_loop() != NULL && | 1736 if (decoder_thread_.message_loop() != NULL && |
1706 decoder_thread_.message_loop() != base::MessageLoop::current()) { | 1737 decoder_thread_.message_loop() != base::MessageLoop::current()) { |
1707 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1738 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
1708 &ExynosVideoDecodeAccelerator::SetDecoderState, | 1739 &V4L2VideoDecodeAccelerator::SetDecoderState, |
1709 base::Unretained(this), state)); | 1740 base::Unretained(this), state)); |
1710 } else { | 1741 } else { |
1711 decoder_state_ = state; | 1742 decoder_state_ = state; |
1712 } | 1743 } |
1713 } | 1744 } |
1714 | 1745 |
1715 bool ExynosVideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format, | 1746 bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format, |
1716 bool* again) { | 1747 bool* again) { |
1717 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1748 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1718 | 1749 |
1719 *again = false; | 1750 *again = false; |
1720 memset(format, 0, sizeof(*format)); | 1751 memset(format, 0, sizeof(*format)); |
1721 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1752 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1722 if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_G_FMT, format)) != 0) { | 1753 if (HANDLE_EINTR(device->dev_ioctl(videodec_fd_, VIDIOC_G_FMT, format)) != 0) { |
1723 if (errno == EINVAL) { | 1754 if (errno == EINVAL) { |
1724 // EINVAL means we haven't seen sufficient stream to decode the format. | 1755 // EINVAL means we haven't seen sufficient stream to decode the format. |
1725 *again = true; | 1756 *again = true; |
1726 return true; | 1757 return true; |
1727 } else { | 1758 } else { |
1728 DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT"; | 1759 DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT"; |
1729 NOTIFY_ERROR(PLATFORM_FAILURE); | 1760 NOTIFY_ERROR(PLATFORM_FAILURE); |
1730 return false; | 1761 return false; |
1731 } | 1762 } |
1732 } | 1763 } |
1733 | 1764 |
1734 return true; | 1765 return true; |
1735 } | 1766 } |
1736 | 1767 |
1737 bool ExynosVideoDecodeAccelerator::CreateBuffersForFormat( | 1768 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( |
1738 const struct v4l2_format& format) { | 1769 const struct v4l2_format& format) { |
1739 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1770 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1740 CHECK_EQ(format.fmt.pix_mp.num_planes, 2); | 1771 CHECK_EQ(format.fmt.pix_mp.num_planes, 2); |
1741 frame_buffer_size_.SetSize( | 1772 frame_buffer_size_.SetSize( |
1742 format.fmt.pix_mp.width, format.fmt.pix_mp.height); | 1773 format.fmt.pix_mp.width, format.fmt.pix_mp.height); |
1743 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat; | 1774 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat; |
1744 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12M); | 1775 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12M); |
1745 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " | 1776 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " |
1746 << frame_buffer_size_.ToString(); | 1777 << frame_buffer_size_.ToString(); |
1747 | 1778 |
1748 if (!CreateMfcOutputBuffers()) | 1779 if (!CreateMfcOutputBuffers()) |
1749 return false; | 1780 return false; |
1750 | 1781 |
1751 return true; | 1782 return true; |
1752 } | 1783 } |
1753 | 1784 |
1754 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() { | 1785 bool V4L2VideoDecodeAccelerator::CreateMfcInputBuffers() { |
1755 DVLOG(3) << "CreateMfcInputBuffers()"; | 1786 DVLOG(3) << "CreateMfcInputBuffers()"; |
1756 // We always run this as we prepare to initialize. | 1787 // We always run this as we prepare to initialize. |
1757 DCHECK_EQ(decoder_state_, kUninitialized); | 1788 DCHECK_EQ(decoder_state_, kUninitialized); |
1758 DCHECK(!mfc_input_streamon_); | 1789 DCHECK(!mfc_input_streamon_); |
1759 DCHECK(mfc_input_buffer_map_.empty()); | 1790 DCHECK(mfc_input_buffer_map_.empty()); |
1760 | 1791 |
1761 __u32 pixelformat = 0; | 1792 __u32 pixelformat = 0; |
1762 if (video_profile_ >= media::H264PROFILE_MIN && | 1793 if (video_profile_ >= media::H264PROFILE_MIN && |
1763 video_profile_ <= media::H264PROFILE_MAX) { | 1794 video_profile_ <= media::H264PROFILE_MAX) { |
1764 pixelformat = V4L2_PIX_FMT_H264; | 1795 pixelformat = V4L2_PIX_FMT_H264; |
1765 } else if (video_profile_ >= media::VP8PROFILE_MIN && | 1796 } else if (video_profile_ >= media::VP8PROFILE_MIN && |
1766 video_profile_ <= media::VP8PROFILE_MAX) { | 1797 video_profile_ <= media::VP8PROFILE_MAX) { |
1767 pixelformat = V4L2_PIX_FMT_VP8; | 1798 pixelformat = V4L2_PIX_FMT_VP8; |
1768 } else { | 1799 } else { |
1769 NOTREACHED(); | 1800 NOTREACHED(); |
1770 } | 1801 } |
1771 | 1802 |
1772 struct v4l2_format format; | 1803 struct v4l2_format format; |
1773 memset(&format, 0, sizeof(format)); | 1804 memset(&format, 0, sizeof(format)); |
1774 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1805 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1775 format.fmt.pix_mp.pixelformat = pixelformat; | 1806 format.fmt.pix_mp.pixelformat = pixelformat; |
1776 format.fmt.pix_mp.plane_fmt[0].sizeimage = kMfcInputBufferMaxSize; | 1807 format.fmt.pix_mp.plane_fmt[0].sizeimage = kMfcInputBufferMaxSize; |
1777 format.fmt.pix_mp.num_planes = 1; | 1808 format.fmt.pix_mp.num_planes = 1; |
1778 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format); | 1809 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_S_FMT, &format); |
1779 | 1810 |
1780 struct v4l2_requestbuffers reqbufs; | 1811 struct v4l2_requestbuffers reqbufs; |
1781 memset(&reqbufs, 0, sizeof(reqbufs)); | 1812 memset(&reqbufs, 0, sizeof(reqbufs)); |
1782 reqbufs.count = kMfcInputBufferCount; | 1813 reqbufs.count = kMfcInputBufferCount; |
1783 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1814 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1784 reqbufs.memory = V4L2_MEMORY_MMAP; | 1815 reqbufs.memory = V4L2_MEMORY_MMAP; |
1785 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs); | 1816 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_REQBUFS, &reqbufs); |
1786 mfc_input_buffer_map_.resize(reqbufs.count); | 1817 mfc_input_buffer_map_.resize(reqbufs.count); |
1787 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { | 1818 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { |
1788 mfc_free_input_buffers_.push_back(i); | 1819 mfc_free_input_buffers_.push_back(i); |
1789 | 1820 |
1790 // Query for the MEMORY_MMAP pointer. | 1821 // Query for the MEMORY_MMAP pointer. |
1791 struct v4l2_plane planes[1]; | 1822 struct v4l2_plane planes[1]; |
1792 struct v4l2_buffer buffer; | 1823 struct v4l2_buffer buffer; |
1793 memset(&buffer, 0, sizeof(buffer)); | 1824 memset(&buffer, 0, sizeof(buffer)); |
1794 memset(planes, 0, sizeof(planes)); | 1825 memset(planes, 0, sizeof(planes)); |
1795 buffer.index = i; | 1826 buffer.index = i; |
1796 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1827 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1797 buffer.memory = V4L2_MEMORY_MMAP; | 1828 buffer.memory = V4L2_MEMORY_MMAP; |
1798 buffer.m.planes = planes; | 1829 buffer.m.planes = planes; |
1799 buffer.length = 1; | 1830 buffer.length = 1; |
1800 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYBUF, &buffer); | 1831 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_QUERYBUF, &buffer); |
1801 void* address = mmap(NULL, buffer.m.planes[0].length, | 1832 void* address = device->dev_mmap(NULL, buffer.m.planes[0].length, |
1802 PROT_READ | PROT_WRITE, MAP_SHARED, mfc_fd_, | 1833 PROT_READ | PROT_WRITE, MAP_SHARED, videodec_fd_, |
1803 buffer.m.planes[0].m.mem_offset); | 1834 buffer.m.planes[0].m.mem_offset); |
1804 if (address == MAP_FAILED) { | 1835 if (address == MAP_FAILED) { |
1805 DPLOG(ERROR) << "CreateMfcInputBuffers(): mmap() failed"; | 1836 DPLOG(ERROR) << "CreateMfcInputBuffers(): mmap() failed"; |
1806 return false; | 1837 return false; |
1807 } | 1838 } |
1808 mfc_input_buffer_map_[i].address = address; | 1839 mfc_input_buffer_map_[i].address = address; |
1809 mfc_input_buffer_map_[i].length = buffer.m.planes[0].length; | 1840 mfc_input_buffer_map_[i].length = buffer.m.planes[0].length; |
1810 } | 1841 } |
1811 | 1842 |
1812 return true; | 1843 return true; |
1813 } | 1844 } |
1814 | 1845 |
1815 bool ExynosVideoDecodeAccelerator::CreateMfcOutputBuffers() { | 1846 bool V4L2VideoDecodeAccelerator::CreateMfcOutputBuffers() { |
1816 DVLOG(3) << "CreateMfcOutputBuffers()"; | 1847 DVLOG(3) << "CreateMfcOutputBuffers()"; |
1817 DCHECK(decoder_state_ == kInitialized || | 1848 DCHECK(decoder_state_ == kInitialized || |
1818 decoder_state_ == kChangingResolution); | 1849 decoder_state_ == kChangingResolution); |
1819 DCHECK(!mfc_output_streamon_); | 1850 DCHECK(!mfc_output_streamon_); |
1820 DCHECK(mfc_output_buffer_map_.empty()); | 1851 DCHECK(mfc_output_buffer_map_.empty()); |
1821 | 1852 |
1822 // Number of MFC output buffers we need. | 1853 // Number of MFC output buffers we need. |
1823 struct v4l2_control ctrl; | 1854 struct v4l2_control ctrl; |
1824 memset(&ctrl, 0, sizeof(ctrl)); | 1855 memset(&ctrl, 0, sizeof(ctrl)); |
1825 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; | 1856 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; |
1826 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_G_CTRL, &ctrl); | 1857 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_G_CTRL, &ctrl); |
1827 mfc_output_dpb_size_ = ctrl.value; | 1858 mfc_output_dpb_size_ = ctrl.value; |
1828 | 1859 |
1829 // Output format setup in Initialize(). | 1860 // Output format setup in Initialize(). |
1830 | 1861 |
1831 // Allocate the output buffers. | 1862 // Allocate the output buffers. |
1832 struct v4l2_requestbuffers reqbufs; | 1863 struct v4l2_requestbuffers reqbufs; |
1833 memset(&reqbufs, 0, sizeof(reqbufs)); | 1864 memset(&reqbufs, 0, sizeof(reqbufs)); |
1834 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount; | 1865 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount; |
1835 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1866 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1836 reqbufs.memory = V4L2_MEMORY_MMAP; | 1867 reqbufs.memory = V4L2_MEMORY_MMAP; |
1837 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs); | 1868 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_REQBUFS, &reqbufs); |
1838 | 1869 |
1839 // Create DMABUFs from output buffers. | 1870 // Create DMABUFs from output buffers. |
1840 mfc_output_buffer_map_.resize(reqbufs.count); | 1871 mfc_output_buffer_map_.resize(reqbufs.count); |
1841 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { | 1872 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { |
1842 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; | 1873 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; |
1843 for (size_t j = 0; j < arraysize(output_record.fds); ++j) { | 1874 for (size_t j = 0; j < arraysize(output_record.fds); ++j) { |
1844 // Export the DMABUF fd so we can export it as a texture. | 1875 // Export the DMABUF fd so we can export it as a texture. |
1845 struct v4l2_exportbuffer expbuf; | 1876 struct v4l2_exportbuffer expbuf; |
1846 memset(&expbuf, 0, sizeof(expbuf)); | 1877 memset(&expbuf, 0, sizeof(expbuf)); |
1847 expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1878 expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1848 expbuf.index = i; | 1879 expbuf.index = i; |
1849 expbuf.plane = j; | 1880 expbuf.plane = j; |
1850 expbuf.flags = O_CLOEXEC; | 1881 expbuf.flags = O_CLOEXEC; |
1851 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_EXPBUF, &expbuf); | 1882 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_EXPBUF, &expbuf); |
1852 output_record.fds[j] = expbuf.fd; | 1883 output_record.fds[j] = expbuf.fd; |
1853 } | 1884 } |
1854 } | 1885 } |
1855 | 1886 |
1856 DVLOG(3) << "CreateMfcOutputBuffers(): ProvidePictureBuffers(): " | 1887 DVLOG(3) << "CreateMfcOutputBuffers(): ProvidePictureBuffers(): " |
1857 << "buffer_count=" << mfc_output_buffer_map_.size() | 1888 << "buffer_count=" << mfc_output_buffer_map_.size() |
1858 << ", width=" << frame_buffer_size_.width() | 1889 << ", width=" << frame_buffer_size_.width() |
1859 << ", height=" << frame_buffer_size_.height(); | 1890 << ", height=" << frame_buffer_size_.height(); |
1860 child_message_loop_proxy_->PostTask(FROM_HERE, | 1891 child_message_loop_proxy_->PostTask(FROM_HERE, |
1861 base::Bind(&Client::ProvidePictureBuffers, | 1892 base::Bind(&Client::ProvidePictureBuffers, |
1862 client_, | 1893 client_, |
1863 mfc_output_buffer_map_.size(), | 1894 mfc_output_buffer_map_.size(), |
1864 frame_buffer_size_, | 1895 frame_buffer_size_, |
1865 GL_TEXTURE_EXTERNAL_OES)); | 1896 GL_TEXTURE_EXTERNAL_OES)); |
1866 | 1897 |
1867 return true; | 1898 return true; |
1868 } | 1899 } |
1869 | 1900 |
1870 void ExynosVideoDecodeAccelerator::DestroyMfcInputBuffers() { | 1901 void V4L2VideoDecodeAccelerator::DestroyMfcInputBuffers() { |
1871 DVLOG(3) << "DestroyMfcInputBuffers()"; | 1902 DVLOG(3) << "DestroyMfcInputBuffers()"; |
1872 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 1903 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
1873 DCHECK(!mfc_input_streamon_); | 1904 DCHECK(!mfc_input_streamon_); |
1874 | 1905 |
1875 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { | 1906 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { |
1876 if (mfc_input_buffer_map_[i].address != NULL) { | 1907 if (mfc_input_buffer_map_[i].address != NULL) { |
1877 munmap(mfc_input_buffer_map_[i].address, | 1908 device->dev_munmap(mfc_input_buffer_map_[i].address, |
1878 mfc_input_buffer_map_[i].length); | 1909 mfc_input_buffer_map_[i].length); |
1879 } | 1910 } |
1880 } | 1911 } |
1881 | 1912 |
1882 struct v4l2_requestbuffers reqbufs; | 1913 struct v4l2_requestbuffers reqbufs; |
1883 memset(&reqbufs, 0, sizeof(reqbufs)); | 1914 memset(&reqbufs, 0, sizeof(reqbufs)); |
1884 reqbufs.count = 0; | 1915 reqbufs.count = 0; |
1885 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1916 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
1886 reqbufs.memory = V4L2_MEMORY_MMAP; | 1917 reqbufs.memory = V4L2_MEMORY_MMAP; |
1887 if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) | 1918 if (device->dev_ioctl(videodec_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) |
1888 DPLOG(ERROR) << "DestroyMfcInputBuffers(): ioctl() failed: VIDIOC_REQBUFS"; | 1919 DPLOG(ERROR) << "DestroyMfcInputBuffers(): ioctl() failed: VIDIOC_REQBUFS"; |
1889 | 1920 |
1890 mfc_input_buffer_map_.clear(); | 1921 mfc_input_buffer_map_.clear(); |
1891 mfc_free_input_buffers_.clear(); | 1922 mfc_free_input_buffers_.clear(); |
1892 } | 1923 } |
1893 | 1924 |
1894 void ExynosVideoDecodeAccelerator::DestroyMfcOutputBuffers() { | 1925 void V4L2VideoDecodeAccelerator::DestroyMfcOutputBuffers() { |
1895 DVLOG(3) << "DestroyMfcOutputBuffers()"; | 1926 DVLOG(3) << "DestroyMfcOutputBuffers()"; |
1896 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 1927 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
1897 DCHECK(!mfc_output_streamon_); | 1928 DCHECK(!mfc_output_streamon_); |
1898 | 1929 |
1899 if (mfc_output_buffer_map_.size() != 0) { | 1930 if (mfc_output_buffer_map_.size() != 0) { |
1931 // TODO(sheu, posciak): Making the context current should not be required | |
1932 // anymore. Remove it and verify (crbug.com/327869). | |
1900 if (!make_context_current_.Run()) { | 1933 if (!make_context_current_.Run()) { |
1901 DLOG(ERROR) << "DestroyMfcOutputBuffers(): " | 1934 DLOG(ERROR) << "DestroyMfcOutputBuffers(): " |
1902 << "could not make context current"; | 1935 << "could not make context current"; |
1903 } else { | 1936 } else { |
1904 size_t i = 0; | 1937 size_t i = 0; |
1905 do { | 1938 do { |
1906 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; | 1939 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; |
1907 for (size_t j = 0; j < arraysize(output_record.fds); ++j) { | 1940 for (size_t j = 0; j < arraysize(output_record.fds); ++j) { |
1908 if (output_record.fds[j] != -1) | 1941 if (output_record.fds[j] != -1) |
1909 close(output_record.fds[j]); | 1942 device->dev_close(output_record.fds[j]); |
1910 if (output_record.egl_image != EGL_NO_IMAGE_KHR) | 1943 if (output_record.egl_image != EGL_NO_IMAGE_KHR) |
1911 eglDestroyImageKHR(egl_display_, output_record.egl_image); | 1944 eglDestroyImageKHR(egl_display_, output_record.egl_image); |
1912 if (output_record.egl_sync != EGL_NO_SYNC_KHR) | 1945 if (output_record.egl_sync != EGL_NO_SYNC_KHR) |
1913 eglDestroySyncKHR(egl_display_, output_record.egl_sync); | 1946 eglDestroySyncKHR(egl_display_, output_record.egl_sync); |
1914 } | 1947 } |
1915 DVLOG(1) << "DestroyMfcOutputBuffers(): dismissing PictureBuffer id=" | 1948 DVLOG(1) << "DestroyMfcOutputBuffers(): dismissing PictureBuffer id=" |
1916 << output_record.picture_id; | 1949 << output_record.picture_id; |
1917 child_message_loop_proxy_->PostTask( | 1950 child_message_loop_proxy_->PostTask( |
1918 FROM_HERE, | 1951 FROM_HERE, |
1919 base::Bind(&Client::DismissPictureBuffer, | 1952 base::Bind(&Client::DismissPictureBuffer, |
1920 client_, | 1953 client_, |
1921 output_record.picture_id)); | 1954 output_record.picture_id)); |
1922 i++; | 1955 i++; |
1923 } while (i < mfc_output_buffer_map_.size()); | 1956 } while (i < mfc_output_buffer_map_.size()); |
1924 } | 1957 } |
1925 } | 1958 } |
1926 | 1959 |
1927 struct v4l2_requestbuffers reqbufs; | 1960 struct v4l2_requestbuffers reqbufs; |
1928 memset(&reqbufs, 0, sizeof(reqbufs)); | 1961 memset(&reqbufs, 0, sizeof(reqbufs)); |
1929 reqbufs.count = 0; | 1962 reqbufs.count = 0; |
1930 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1963 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
1931 reqbufs.memory = V4L2_MEMORY_MMAP; | 1964 reqbufs.memory = V4L2_MEMORY_MMAP; |
1932 if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) | 1965 if (device->dev_ioctl(videodec_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) |
1933 DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS"; | 1966 DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS"; |
1934 | 1967 |
1935 mfc_output_buffer_map_.clear(); | 1968 mfc_output_buffer_map_.clear(); |
1936 while (!mfc_free_output_buffers_.empty()) | 1969 while (!mfc_free_output_buffers_.empty()) |
1937 mfc_free_output_buffers_.pop(); | 1970 mfc_free_output_buffers_.pop(); |
1938 } | 1971 } |
1939 | 1972 |
1940 void ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers() { | 1973 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() { |
1941 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); | 1974 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); |
1942 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; | 1975 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; |
1943 | 1976 |
1944 DestroyMfcOutputBuffers(); | 1977 DestroyMfcOutputBuffers(); |
1945 | 1978 |
1946 // Finish resolution change on decoder thread. | 1979 // Finish resolution change on decoder thread. |
1947 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1980 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
1948 &ExynosVideoDecodeAccelerator::FinishResolutionChange, | 1981 &V4L2VideoDecodeAccelerator::FinishResolutionChange, |
1949 base::Unretained(this))); | 1982 base::Unretained(this))); |
1950 } | 1983 } |
1951 | 1984 |
1952 void ExynosVideoDecodeAccelerator::SendPictureReady() { | 1985 void V4L2VideoDecodeAccelerator::SendPictureReady() { |
1953 DVLOG(3) << "SendPictureReady()"; | 1986 DVLOG(3) << "SendPictureReady()"; |
1954 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1987 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1955 bool resetting_or_flushing = | 1988 bool resetting_or_flushing = |
1956 (decoder_state_ == kResetting || decoder_flushing_); | 1989 (decoder_state_ == kResetting || decoder_flushing_); |
1957 while (pending_picture_ready_.size() > 0) { | 1990 while (pending_picture_ready_.size() > 0) { |
1958 bool cleared = pending_picture_ready_.front().cleared; | 1991 bool cleared = pending_picture_ready_.front().cleared; |
1959 const media::Picture& picture = pending_picture_ready_.front().picture; | 1992 const media::Picture& picture = pending_picture_ready_.front().picture; |
1960 if (cleared && picture_clearing_count_ == 0) { | 1993 if (cleared && picture_clearing_count_ == 0) { |
1961 // This picture is cleared. Post it to IO thread to reduce latency. This | 1994 // This picture is cleared. Post it to IO thread to reduce latency. This |
1962 // should be the case after all pictures are cleared at the beginning. | 1995 // should be the case after all pictures are cleared at the beginning. |
1963 io_message_loop_proxy_->PostTask( | 1996 io_message_loop_proxy_->PostTask( |
1964 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); | 1997 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); |
1965 pending_picture_ready_.pop(); | 1998 pending_picture_ready_.pop(); |
1966 } else if (!cleared || resetting_or_flushing) { | 1999 } else if (!cleared || resetting_or_flushing) { |
1967 DVLOG(3) << "SendPictureReady()" | 2000 DVLOG(3) << "SendPictureReady()" |
1968 << ". cleared=" << pending_picture_ready_.front().cleared | 2001 << ". cleared=" << pending_picture_ready_.front().cleared |
1969 << ", decoder_state_=" << decoder_state_ | 2002 << ", decoder_state_=" << decoder_state_ |
1970 << ", decoder_flushing_=" << decoder_flushing_ | 2003 << ", decoder_flushing_=" << decoder_flushing_ |
1971 << ", picture_clearing_count_=" << picture_clearing_count_; | 2004 << ", picture_clearing_count_=" << picture_clearing_count_; |
1972 // If the picture is not cleared, post it to the child thread because it | 2005 // If the picture is not cleared, post it to the child thread because it |
1973 // has to be cleared in the child thread. A picture only needs to be | 2006 // has to be cleared in the child thread. A picture only needs to be |
1974 // cleared once. If the decoder is resetting or flushing, send all | 2007 // cleared once. If the decoder is resetting or flushing, send all |
1975 // pictures to ensure PictureReady arrive before reset or flush done. | 2008 // pictures to ensure PictureReady arrive before reset or flush done. |
1976 child_message_loop_proxy_->PostTaskAndReply( | 2009 child_message_loop_proxy_->PostTaskAndReply( |
1977 FROM_HERE, | 2010 FROM_HERE, |
1978 base::Bind(&Client::PictureReady, client_, picture), | 2011 base::Bind(&Client::PictureReady, client_, picture), |
1979 // Unretained is safe. If Client::PictureReady gets to run, |this| is | 2012 // Unretained is safe. If Client::PictureReady gets to run, |this| is |
1980 // alive. Destroy() will wait the decode thread to finish. | 2013 // alive. Destroy() will wait the decode thread to finish. |
1981 base::Bind(&ExynosVideoDecodeAccelerator::PictureCleared, | 2014 base::Bind(&V4L2VideoDecodeAccelerator::PictureCleared, |
1982 base::Unretained(this))); | 2015 base::Unretained(this))); |
1983 picture_clearing_count_++; | 2016 picture_clearing_count_++; |
1984 pending_picture_ready_.pop(); | 2017 pending_picture_ready_.pop(); |
1985 } else { | 2018 } else { |
1986 // This picture is cleared. But some pictures are about to be cleared on | 2019 // This picture is cleared. But some pictures are about to be cleared on |
1987 // the child thread. To preserve the order, do not send this until those | 2020 // the child thread. To preserve the order, do not send this until those |
1988 // pictures are cleared. | 2021 // pictures are cleared. |
1989 break; | 2022 break; |
1990 } | 2023 } |
1991 } | 2024 } |
1992 } | 2025 } |
1993 | 2026 |
1994 void ExynosVideoDecodeAccelerator::PictureCleared() { | 2027 void V4L2VideoDecodeAccelerator::PictureCleared() { |
1995 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 2028 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
1996 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 2029 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
1997 DCHECK_GT(picture_clearing_count_, 0); | 2030 DCHECK_GT(picture_clearing_count_, 0); |
1998 picture_clearing_count_--; | 2031 picture_clearing_count_--; |
1999 SendPictureReady(); | 2032 SendPictureReady(); |
2000 } | 2033 } |
2001 | 2034 |
2002 } // namespace content | 2035 } // namespace content |
OLD | NEW |