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

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

Issue 23526070: Remove GSC usage from ExynosVideoDecodeAccelerator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: 11845b4b crop fix, rebase. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (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 <linux/videodev2.h> 9 #include <linux/videodev2.h>
9 #include <poll.h> 10 #include <poll.h>
10 #include <sys/eventfd.h> 11 #include <sys/eventfd.h>
11 #include <sys/ioctl.h> 12 #include <sys/ioctl.h>
12 #include <sys/mman.h> 13 #include <sys/mman.h>
13 14
14 #include "base/bind.h" 15 #include "base/bind.h"
15 #include "base/debug/trace_event.h" 16 #include "base/debug/trace_event.h"
16 #include "base/memory/shared_memory.h" 17 #include "base/memory/shared_memory.h"
17 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 } while (0) 50 } while (0)
50 51
51 namespace { 52 namespace {
52 53
53 // TODO(posciak): remove once we update linux-headers. 54 // TODO(posciak): remove once we update linux-headers.
54 #ifndef V4L2_EVENT_RESOLUTION_CHANGE 55 #ifndef V4L2_EVENT_RESOLUTION_CHANGE
55 #define V4L2_EVENT_RESOLUTION_CHANGE 5 56 #define V4L2_EVENT_RESOLUTION_CHANGE 5
56 #endif 57 #endif
57 58
58 const char kExynosMfcDevice[] = "/dev/mfc-dec"; 59 const char kExynosMfcDevice[] = "/dev/mfc-dec";
59 const char kExynosGscDevice[] = "/dev/gsc1";
60 const char kMaliDriver[] = "libmali.so";
61 60
62 typedef EGLBoolean (*MaliEglImageGetBufferExtPhandleFunc)(EGLImageKHR, EGLint*,
63 void*);
64
65 void* libmali_handle = NULL;
66 MaliEglImageGetBufferExtPhandleFunc
67 mali_egl_image_get_buffer_ext_phandle = NULL;
68 } // anonymous namespace 61 } // anonymous namespace
69 62
70 struct ExynosVideoDecodeAccelerator::BitstreamBufferRef { 63 struct ExynosVideoDecodeAccelerator::BitstreamBufferRef {
71 BitstreamBufferRef( 64 BitstreamBufferRef(
72 base::WeakPtr<Client>& client, 65 base::WeakPtr<Client>& client,
73 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, 66 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy,
74 base::SharedMemory* shm, 67 base::SharedMemory* shm,
75 size_t size, 68 size_t size,
76 int32 input_id); 69 int32 input_id);
77 ~BitstreamBufferRef(); 70 ~BitstreamBufferRef();
78 const base::WeakPtr<Client> client; 71 const base::WeakPtr<Client> client;
79 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy; 72 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy;
80 const scoped_ptr<base::SharedMemory> shm; 73 const scoped_ptr<base::SharedMemory> shm;
81 const size_t size; 74 const size_t size;
82 off_t bytes_used; 75 off_t bytes_used;
83 const int32 input_id; 76 const int32 input_id;
84 }; 77 };
85 78
86 struct ExynosVideoDecodeAccelerator::PictureBufferArrayRef { 79 struct ExynosVideoDecodeAccelerator::PictureBufferArrayRef {
87 PictureBufferArrayRef(EGLDisplay egl_display, size_t count); 80 PictureBufferArrayRef(EGLDisplay egl_display);
88 ~PictureBufferArrayRef(); 81 ~PictureBufferArrayRef();
89 82
90 struct PictureBufferRef { 83 struct PictureBufferRef {
84 PictureBufferRef(EGLImageKHR egl_image, int32 picture_id)
85 : egl_image(egl_image), picture_id(picture_id) {}
91 EGLImageKHR egl_image; 86 EGLImageKHR egl_image;
92 int egl_image_fd; 87 int32 picture_id;
93 int32 client_id;
94 }; 88 };
95 89
96 EGLDisplay const egl_display; 90 EGLDisplay const egl_display;
97 std::vector<PictureBufferRef> picture_buffers; 91 std::vector<PictureBufferRef> picture_buffers;
98 }; 92 };
99 93
100 struct ExynosVideoDecodeAccelerator::EGLSyncKHRRef { 94 struct ExynosVideoDecodeAccelerator::EGLSyncKHRRef {
101 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync); 95 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync);
102 ~EGLSyncKHRRef(); 96 ~EGLSyncKHRRef();
103 EGLDisplay const egl_display; 97 EGLDisplay const egl_display;
(...skipping 20 matching lines...) Expand all
124 } 118 }
125 119
126 ExynosVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { 120 ExynosVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() {
127 if (input_id >= 0) { 121 if (input_id >= 0) {
128 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind( 122 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind(
129 &Client::NotifyEndOfBitstreamBuffer, client, input_id)); 123 &Client::NotifyEndOfBitstreamBuffer, client, input_id));
130 } 124 }
131 } 125 }
132 126
133 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef( 127 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef(
134 EGLDisplay egl_display, size_t count) 128 EGLDisplay egl_display)
135 : egl_display(egl_display), 129 : egl_display(egl_display) {}
136 picture_buffers(count) { 130
131 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::~PictureBufferArrayRef() {
137 for (size_t i = 0; i < picture_buffers.size(); ++i) { 132 for (size_t i = 0; i < picture_buffers.size(); ++i) {
138 PictureBufferRef& buffer = picture_buffers[i]; 133 EGLImageKHR egl_image = picture_buffers[i].egl_image;
139 buffer.egl_image = EGL_NO_IMAGE_KHR; 134 if (egl_image != EGL_NO_IMAGE_KHR)
140 buffer.egl_image_fd = -1; 135 eglDestroyImageKHR(egl_display, egl_image);
141 buffer.client_id = -1;
142 } 136 }
143 } 137 }
144 138
145 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::~PictureBufferArrayRef() {
146 for (size_t i = 0; i < picture_buffers.size(); ++i) {
147 PictureBufferRef& buffer = picture_buffers[i];
148 if (buffer.egl_image != EGL_NO_IMAGE_KHR)
149 eglDestroyImageKHR(egl_display, buffer.egl_image);
150 if (buffer.egl_image_fd != -1)
151 HANDLE_EINTR(close(buffer.egl_image_fd));
152 }
153 }
154
155 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef( 139 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef(
156 EGLDisplay egl_display, EGLSyncKHR egl_sync) 140 EGLDisplay egl_display, EGLSyncKHR egl_sync)
157 : egl_display(egl_display), 141 : egl_display(egl_display),
158 egl_sync(egl_sync) { 142 egl_sync(egl_sync) {
159 } 143 }
160 144
161 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() { 145 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() {
162 if (egl_sync != EGL_NO_SYNC_KHR) 146 if (egl_sync != EGL_NO_SYNC_KHR)
163 eglDestroySyncKHR(egl_display, egl_sync); 147 eglDestroySyncKHR(egl_display, egl_sync);
164 } 148 }
165 149
166 ExynosVideoDecodeAccelerator::MfcInputRecord::MfcInputRecord() 150 ExynosVideoDecodeAccelerator::MfcInputRecord::MfcInputRecord()
167 : at_device(false), 151 : at_device(false),
168 address(NULL), 152 address(NULL),
169 length(0), 153 length(0),
170 bytes_used(0), 154 bytes_used(0),
171 input_id(-1) { 155 input_id(-1) {
172 } 156 }
173 157
174 ExynosVideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() { 158 ExynosVideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() {
175 } 159 }
176 160
177 ExynosVideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord() 161 ExynosVideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord()
178 : at_device(false), 162 : at_device(false),
179 input_id(-1) {
180 bytes_used[0] = 0;
181 bytes_used[1] = 0;
182 address[0] = NULL;
183 address[1] = NULL;
184 length[0] = 0;
185 length[1] = 0;
186 }
187
188 ExynosVideoDecodeAccelerator::MfcOutputRecord::~MfcOutputRecord() {
189 }
190
191 ExynosVideoDecodeAccelerator::GscInputRecord::GscInputRecord()
192 : at_device(false),
193 mfc_output(-1) {
194 }
195
196 ExynosVideoDecodeAccelerator::GscInputRecord::~GscInputRecord() {
197 }
198
199 ExynosVideoDecodeAccelerator::GscOutputRecord::GscOutputRecord()
200 : at_device(false),
201 at_client(false), 163 at_client(false),
202 fd(-1),
203 egl_image(EGL_NO_IMAGE_KHR), 164 egl_image(EGL_NO_IMAGE_KHR),
204 egl_sync(EGL_NO_SYNC_KHR), 165 egl_sync(EGL_NO_SYNC_KHR),
205 picture_id(-1), 166 picture_id(-1),
206 cleared(false) {} 167 cleared(false) {
168 for (size_t i = 0; i < arraysize(fds); ++i)
169 fds[i] = -1;
170 }
207 171
208 ExynosVideoDecodeAccelerator::GscOutputRecord::~GscOutputRecord() { 172 ExynosVideoDecodeAccelerator::MfcOutputRecord::~MfcOutputRecord() {}
209 }
210 173
211 ExynosVideoDecodeAccelerator::PictureRecord::PictureRecord( 174 ExynosVideoDecodeAccelerator::PictureRecord::PictureRecord(
212 bool cleared, 175 bool cleared,
213 const media::Picture& picture) 176 const media::Picture& picture)
214 : cleared(cleared), picture(picture) {} 177 : cleared(cleared), picture(picture) {}
215 178
216 ExynosVideoDecodeAccelerator::PictureRecord::~PictureRecord() {} 179 ExynosVideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
217 180
218 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator( 181 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator(
219 EGLDisplay egl_display, 182 EGLDisplay egl_display,
(...skipping 18 matching lines...) Expand all
238 resolution_change_pending_(false), 201 resolution_change_pending_(false),
239 resolution_change_reset_pending_(false), 202 resolution_change_reset_pending_(false),
240 decoder_partial_frame_pending_(false), 203 decoder_partial_frame_pending_(false),
241 mfc_fd_(-1), 204 mfc_fd_(-1),
242 mfc_input_streamon_(false), 205 mfc_input_streamon_(false),
243 mfc_input_buffer_queued_count_(0), 206 mfc_input_buffer_queued_count_(0),
244 mfc_output_streamon_(false), 207 mfc_output_streamon_(false),
245 mfc_output_buffer_queued_count_(0), 208 mfc_output_buffer_queued_count_(0),
246 mfc_output_buffer_pixelformat_(0), 209 mfc_output_buffer_pixelformat_(0),
247 mfc_output_dpb_size_(0), 210 mfc_output_dpb_size_(0),
248 gsc_fd_(-1),
249 gsc_input_streamon_(false),
250 gsc_input_buffer_queued_count_(0),
251 gsc_output_streamon_(false),
252 gsc_output_buffer_queued_count_(0),
253 picture_clearing_count_(0), 211 picture_clearing_count_(0),
254 device_poll_thread_("ExynosDevicePollThread"), 212 device_poll_thread_("ExynosDevicePollThread"),
255 device_poll_interrupt_fd_(-1), 213 device_poll_interrupt_fd_(-1),
256 make_context_current_(make_context_current), 214 make_context_current_(make_context_current),
257 egl_display_(egl_display), 215 egl_display_(egl_display),
258 egl_context_(egl_context), 216 egl_context_(egl_context),
259 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {} 217 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {}
260 218
261 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() { 219 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() {
262 DCHECK(!decoder_thread_.IsRunning()); 220 DCHECK(!decoder_thread_.IsRunning());
263 DCHECK(!device_poll_thread_.IsRunning()); 221 DCHECK(!device_poll_thread_.IsRunning());
264 222
265 if (device_poll_interrupt_fd_ != -1) { 223 if (device_poll_interrupt_fd_ != -1) {
266 HANDLE_EINTR(close(device_poll_interrupt_fd_)); 224 HANDLE_EINTR(close(device_poll_interrupt_fd_));
267 device_poll_interrupt_fd_ = -1; 225 device_poll_interrupt_fd_ = -1;
268 } 226 }
269 if (gsc_fd_ != -1) {
270 DestroyGscInputBuffers();
271 DestroyGscOutputBuffers();
272 HANDLE_EINTR(close(gsc_fd_));
273 gsc_fd_ = -1;
274 }
275 if (mfc_fd_ != -1) { 227 if (mfc_fd_ != -1) {
276 DestroyMfcInputBuffers(); 228 DestroyMfcInputBuffers();
277 DestroyMfcOutputBuffers(); 229 DestroyMfcOutputBuffers();
278 HANDLE_EINTR(close(mfc_fd_)); 230 HANDLE_EINTR(close(mfc_fd_));
279 mfc_fd_ = -1; 231 mfc_fd_ = -1;
280 } 232 }
281 233
282 // These maps have members that should be manually destroyed, e.g. file 234 // These maps have members that should be manually destroyed, e.g. file
283 // descriptors, mmap() segments, etc. 235 // descriptors, mmap() segments, etc.
284 DCHECK(mfc_input_buffer_map_.empty()); 236 DCHECK(mfc_input_buffer_map_.empty());
285 DCHECK(mfc_output_buffer_map_.empty()); 237 DCHECK(mfc_output_buffer_map_.empty());
286 DCHECK(gsc_input_buffer_map_.empty());
287 DCHECK(gsc_output_buffer_map_.empty());
288 } 238 }
289 239
290 bool ExynosVideoDecodeAccelerator::Initialize( 240 bool ExynosVideoDecodeAccelerator::Initialize(
291 media::VideoCodecProfile profile) { 241 media::VideoCodecProfile profile) {
292 DVLOG(3) << "Initialize()"; 242 DVLOG(3) << "Initialize()";
293 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 243 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
294 DCHECK_EQ(decoder_state_, kUninitialized); 244 DCHECK_EQ(decoder_state_, kUninitialized);
295 245
296 switch (profile) { 246 switch (profile) {
297 case media::H264PROFILE_BASELINE: 247 case media::H264PROFILE_BASELINE:
298 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; 248 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE";
299 break; 249 break;
300 case media::H264PROFILE_MAIN: 250 case media::H264PROFILE_MAIN:
301 DVLOG(2) << "Initialize(): profile H264PROFILE_MAIN"; 251 DVLOG(2) << "Initialize(): profile H264PROFILE_MAIN";
302 break; 252 break;
303 case media::H264PROFILE_HIGH: 253 case media::H264PROFILE_HIGH:
304 DVLOG(2) << "Initialize(): profile H264PROFILE_HIGH"; 254 DVLOG(2) << "Initialize(): profile H264PROFILE_HIGH";
305 break; 255 break;
306 case media::VP8PROFILE_MAIN: 256 case media::VP8PROFILE_MAIN:
307 DVLOG(2) << "Initialize(): profile VP8PROFILE_MAIN"; 257 DVLOG(2) << "Initialize(): profile VP8PROFILE_MAIN";
308 break; 258 break;
309 default: 259 default:
310 DLOG(ERROR) << "Initialize(): unsupported profile=" << profile; 260 DLOG(ERROR) << "Initialize(): unsupported profile=" << profile;
311 return false; 261 return false;
312 }; 262 };
313 video_profile_ = profile; 263 video_profile_ = profile;
314 264
315 static bool sandbox_initialized = PostSandboxInitialization();
316 if (!sandbox_initialized) {
317 DLOG(ERROR) << "Initialize(): PostSandboxInitialization() failed";
318 NOTIFY_ERROR(PLATFORM_FAILURE);
319 return false;
320 }
321
322 if (egl_display_ == EGL_NO_DISPLAY) { 265 if (egl_display_ == EGL_NO_DISPLAY) {
323 DLOG(ERROR) << "Initialize(): could not get EGLDisplay"; 266 DLOG(ERROR) << "Initialize(): could not get EGLDisplay";
324 NOTIFY_ERROR(PLATFORM_FAILURE); 267 NOTIFY_ERROR(PLATFORM_FAILURE);
325 return false; 268 return false;
326 } 269 }
327 270
328 if (egl_context_ == EGL_NO_CONTEXT) { 271 if (egl_context_ == EGL_NO_CONTEXT) {
329 DLOG(ERROR) << "Initialize(): could not get EGLContext"; 272 DLOG(ERROR) << "Initialize(): could not get EGLContext";
330 NOTIFY_ERROR(PLATFORM_FAILURE); 273 NOTIFY_ERROR(PLATFORM_FAILURE);
331 return false; 274 return false;
(...skipping 15 matching lines...) Expand all
347 // Open the video devices. 290 // Open the video devices.
348 DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice; 291 DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice;
349 mfc_fd_ = HANDLE_EINTR(open(kExynosMfcDevice, 292 mfc_fd_ = HANDLE_EINTR(open(kExynosMfcDevice,
350 O_RDWR | O_NONBLOCK | O_CLOEXEC)); 293 O_RDWR | O_NONBLOCK | O_CLOEXEC));
351 if (mfc_fd_ == -1) { 294 if (mfc_fd_ == -1) {
352 DPLOG(ERROR) << "Initialize(): could not open MFC device: " 295 DPLOG(ERROR) << "Initialize(): could not open MFC device: "
353 << kExynosMfcDevice; 296 << kExynosMfcDevice;
354 NOTIFY_ERROR(PLATFORM_FAILURE); 297 NOTIFY_ERROR(PLATFORM_FAILURE);
355 return false; 298 return false;
356 } 299 }
357 DVLOG(2) << "Initialize(): opening GSC device: " << kExynosGscDevice;
358 gsc_fd_ = HANDLE_EINTR(open(kExynosGscDevice,
359 O_RDWR | O_NONBLOCK | O_CLOEXEC));
360 if (gsc_fd_ == -1) {
361 DPLOG(ERROR) << "Initialize(): could not open GSC device: "
362 << kExynosGscDevice;
363 NOTIFY_ERROR(PLATFORM_FAILURE);
364 return false;
365 }
366 300
367 // Create the interrupt fd. 301 // Create the interrupt fd.
368 DCHECK_EQ(device_poll_interrupt_fd_, -1); 302 DCHECK_EQ(device_poll_interrupt_fd_, -1);
369 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 303 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
370 if (device_poll_interrupt_fd_ == -1) { 304 if (device_poll_interrupt_fd_ == -1) {
371 DPLOG(ERROR) << "Initialize(): eventfd() failed"; 305 DPLOG(ERROR) << "Initialize(): eventfd() failed";
372 NOTIFY_ERROR(PLATFORM_FAILURE); 306 NOTIFY_ERROR(PLATFORM_FAILURE);
373 return false; 307 return false;
374 } 308 }
375 309
376 // Capabilities check. 310 // Capabilities check.
377 struct v4l2_capability caps; 311 struct v4l2_capability caps;
378 const __u32 kCapsRequired = 312 const __u32 kCapsRequired =
379 V4L2_CAP_VIDEO_CAPTURE_MPLANE | 313 V4L2_CAP_VIDEO_CAPTURE_MPLANE |
380 V4L2_CAP_VIDEO_OUTPUT_MPLANE | 314 V4L2_CAP_VIDEO_OUTPUT_MPLANE |
381 V4L2_CAP_STREAMING; 315 V4L2_CAP_STREAMING;
382 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYCAP, &caps); 316 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYCAP, &caps);
383 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 317 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
384 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" 318 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
385 ", caps check failed: 0x" << std::hex << caps.capabilities; 319 ", caps check failed: 0x" << std::hex << caps.capabilities;
386 NOTIFY_ERROR(PLATFORM_FAILURE); 320 NOTIFY_ERROR(PLATFORM_FAILURE);
387 return false; 321 return false;
388 } 322 }
389 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QUERYCAP, &caps);
390 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
391 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
392 ", caps check failed: 0x" << std::hex << caps.capabilities;
393 NOTIFY_ERROR(PLATFORM_FAILURE);
394 return false;
395 }
396 323
397 if (!CreateMfcInputBuffers()) 324 if (!CreateMfcInputBuffers())
398 return false; 325 return false;
399 326
400 // MFC output format has to be setup before streaming starts. 327 // MFC output format has to be setup before streaming starts.
401 struct v4l2_format format; 328 struct v4l2_format format;
402 memset(&format, 0, sizeof(format)); 329 memset(&format, 0, sizeof(format));
403 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 330 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
404 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; 331 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
405 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format); 332 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format);
406 333
407 // Subscribe to the resolution change event. 334 // Subscribe to the resolution change event.
408 struct v4l2_event_subscription sub; 335 struct v4l2_event_subscription sub;
409 memset(&sub, 0, sizeof(sub)); 336 memset(&sub, 0, sizeof(sub));
410 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; 337 sub.type = V4L2_EVENT_RESOLUTION_CHANGE;
411 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub); 338 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub);
412 339
413 // Initialize format-specific bits. 340 // Initialize format-specific bits.
414 if (video_profile_ >= media::H264PROFILE_MIN && 341 if (video_profile_ >= media::H264PROFILE_MIN &&
(...skipping 24 matching lines...) Expand all
439 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 366 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
440 &ExynosVideoDecodeAccelerator::DecodeTask, base::Unretained(this), 367 &ExynosVideoDecodeAccelerator::DecodeTask, base::Unretained(this),
441 bitstream_buffer)); 368 bitstream_buffer));
442 } 369 }
443 370
444 void ExynosVideoDecodeAccelerator::AssignPictureBuffers( 371 void ExynosVideoDecodeAccelerator::AssignPictureBuffers(
445 const std::vector<media::PictureBuffer>& buffers) { 372 const std::vector<media::PictureBuffer>& buffers) {
446 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); 373 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
447 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 374 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
448 375
449 if (buffers.size() != gsc_output_buffer_map_.size()) { 376 if (buffers.size() != mfc_output_buffer_map_.size()) {
450 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" 377 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
451 " buffers. (Got " << buffers.size() << ", requested " << 378 " buffers. (Got " << buffers.size()
452 gsc_output_buffer_map_.size() << ")"; 379 << ", requested " << mfc_output_buffer_map_.size() << ")";
453 NOTIFY_ERROR(INVALID_ARGUMENT); 380 NOTIFY_ERROR(INVALID_ARGUMENT);
454 return; 381 return;
455 } 382 }
456 383
457 if (!make_context_current_.Run()) { 384 if (!make_context_current_.Run()) {
458 DLOG(ERROR) << "AssignPictureBuffers(): could not make context current"; 385 DLOG(ERROR) << "AssignPictureBuffers(): could not make context current";
459 NOTIFY_ERROR(PLATFORM_FAILURE); 386 NOTIFY_ERROR(PLATFORM_FAILURE);
460 return; 387 return;
461 } 388 }
462 389
463 scoped_ptr<PictureBufferArrayRef> pic_buffers_ref( 390 scoped_ptr<PictureBufferArrayRef> picture_buffers_ref(
464 new PictureBufferArrayRef(egl_display_, buffers.size())); 391 new PictureBufferArrayRef(egl_display_));
465 392 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0);
466 const static EGLint kImageAttrs[] = { 393 EGLint attrs[] = {
467 EGL_IMAGE_PRESERVED_KHR, 0, 394 EGL_WIDTH, 0, EGL_HEIGHT, 0,
468 EGL_NONE, 395 EGL_LINUX_DRM_FOURCC_EXT, 0, EGL_DMA_BUF_PLANE0_FD_EXT, 0,
469 }; 396 EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
470 Display* x_display = base::MessagePumpForUI::GetDefaultXDisplay(); 397 EGL_DMA_BUF_PLANE1_FD_EXT, 0, EGL_DMA_BUF_PLANE1_OFFSET_EXT, 0,
471 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_2D, 0); 398 EGL_DMA_BUF_PLANE1_PITCH_EXT, 0, EGL_NONE, };
472 for (size_t i = 0; i < pic_buffers_ref->picture_buffers.size(); ++i) { 399 attrs[1] = frame_buffer_size_.width();
400 attrs[3] = frame_buffer_size_.height();
401 attrs[5] = DRM_FORMAT_NV12;
402 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
473 DCHECK(buffers[i].size() == frame_buffer_size_); 403 DCHECK(buffers[i].size() == frame_buffer_size_);
474 PictureBufferArrayRef::PictureBufferRef& buffer = 404 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
475 pic_buffers_ref->picture_buffers[i]; 405 attrs[7] = output_record.fds[0];
476 // Create the X pixmap and then create an EGLImageKHR from it, so we can 406 attrs[9] = 0;
477 // get dma_buf backing. 407 attrs[11] = frame_buffer_size_.width();
478 Pixmap pixmap = XCreatePixmap(x_display, 408 attrs[13] = output_record.fds[1];
479 RootWindow(x_display, 0), 409 attrs[15] = 0;
480 frame_buffer_size_.width(), 410 attrs[17] = frame_buffer_size_.width();
481 frame_buffer_size_.height(),
482 32);
483 if (!pixmap) {
484 DLOG(ERROR) << "AssignPictureBuffers(): could not create X pixmap";
485 NOTIFY_ERROR(PLATFORM_FAILURE);
486 return;
487 }
488 glBindTexture(GL_TEXTURE_2D, buffers[i].texture_id());
489 EGLImageKHR egl_image = eglCreateImageKHR( 411 EGLImageKHR egl_image = eglCreateImageKHR(
490 egl_display_, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, 412 egl_display_, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs);
491 (EGLClientBuffer)pixmap, kImageAttrs);
492 // We can free the X pixmap immediately -- according to the
493 // EGL_KHR_image_base spec, the backing storage does not go away until the
494 // last referencing EGLImage is destroyed.
495 XFreePixmap(x_display, pixmap);
496 if (egl_image == EGL_NO_IMAGE_KHR) { 413 if (egl_image == EGL_NO_IMAGE_KHR) {
497 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; 414 DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR";
498 NOTIFY_ERROR(PLATFORM_FAILURE); 415 NOTIFY_ERROR(PLATFORM_FAILURE);
499 return; 416 return;
500 } 417 }
501 buffer.egl_image = egl_image; 418
502 int fd; 419 glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id());
503 if (!mali_egl_image_get_buffer_ext_phandle(buffer.egl_image, NULL, &fd)) { 420 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image);
504 DLOG(ERROR) << "AssignPictureBuffers(): " 421 picture_buffers_ref->picture_buffers.push_back(
505 << "could not get EGLImageKHR dmabuf fd"; 422 PictureBufferArrayRef::PictureBufferRef(egl_image, buffers[i].id()));
506 NOTIFY_ERROR(PLATFORM_FAILURE);
507 return;
508 }
509 buffer.egl_image_fd = fd;
510 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image);
511 buffer.client_id = buffers[i].id();
512 } 423 }
513 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 424 decoder_thread_.message_loop()->PostTask(
514 &ExynosVideoDecodeAccelerator::AssignPictureBuffersTask, 425 FROM_HERE,
515 base::Unretained(this), base::Passed(&pic_buffers_ref))); 426 base::Bind(&ExynosVideoDecodeAccelerator::AssignPictureBuffersTask,
427 base::Unretained(this),
428 base::Passed(&picture_buffers_ref)));
516 } 429 }
517 430
518 void ExynosVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { 431 void ExynosVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
519 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id; 432 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id;
520 // Must be run on child thread, as we'll insert a sync in the EGL context. 433 // Must be run on child thread, as we'll insert a sync in the EGL context.
521 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 434 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
522 435
523 if (!make_context_current_.Run()) { 436 if (!make_context_current_.Run()) {
524 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current"; 437 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current";
525 NOTIFY_ERROR(PLATFORM_FAILURE); 438 NOTIFY_ERROR(PLATFORM_FAILURE);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 } 487 }
575 488
576 // Set to kError state just in case. 489 // Set to kError state just in case.
577 SetDecoderState(kError); 490 SetDecoderState(kError);
578 491
579 delete this; 492 delete this;
580 } 493 }
581 494
582 bool ExynosVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } 495 bool ExynosVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; }
583 496
584 // static
585 void ExynosVideoDecodeAccelerator::PreSandboxInitialization() {
586 DVLOG(3) << "PreSandboxInitialization()";
587 dlerror();
588
589 libmali_handle = dlopen(kMaliDriver, RTLD_LAZY | RTLD_LOCAL);
590 if (libmali_handle == NULL) {
591 DPLOG(ERROR) << "failed to dlopen() " << kMaliDriver << ": " << dlerror();
592 }
593 }
594
595 // static
596 bool ExynosVideoDecodeAccelerator::PostSandboxInitialization() {
597 DVLOG(3) << "PostSandboxInitialization()";
598 if (libmali_handle == NULL) {
599 DLOG(ERROR) << "PostSandboxInitialization(): no " << kMaliDriver
600 << " driver handle";
601 return false;
602 }
603
604 dlerror();
605 mali_egl_image_get_buffer_ext_phandle =
606 reinterpret_cast<MaliEglImageGetBufferExtPhandleFunc>(
607 dlsym(libmali_handle, "mali_egl_image_get_buffer_ext_phandle"));
608 if (mali_egl_image_get_buffer_ext_phandle == NULL) {
609 DPLOG(ERROR) << "PostSandboxInitialization(): failed to dlsym() "
610 << "mali_egl_image_get_buffer_ext_phandle: " << dlerror();
611 return false;
612 }
613
614 return true;
615 }
616
617 void ExynosVideoDecodeAccelerator::DecodeTask( 497 void ExynosVideoDecodeAccelerator::DecodeTask(
618 const media::BitstreamBuffer& bitstream_buffer) { 498 const media::BitstreamBuffer& bitstream_buffer) {
619 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); 499 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id();
620 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 500 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
621 DCHECK_NE(decoder_state_, kUninitialized); 501 DCHECK_NE(decoder_state_, kUninitialized);
622 TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id", 502 TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id",
623 bitstream_buffer.id()); 503 bitstream_buffer.id());
624 504
625 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 505 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
626 io_client_, io_message_loop_proxy_, 506 io_client_, io_message_loop_proxy_,
(...skipping 12 matching lines...) Expand all
639 // we're here, we know that this DecodeTask() was scheduled by a Decode() 519 // we're here, we know that this DecodeTask() was scheduled by a Decode()
640 // call that came after (in the client thread) the Reset() or Flush() call; 520 // call that came after (in the client thread) the Reset() or Flush() call;
641 // thus set up the delay if necessary. 521 // thus set up the delay if necessary.
642 if (decoder_delay_bitstream_buffer_id_ == -1) 522 if (decoder_delay_bitstream_buffer_id_ == -1)
643 decoder_delay_bitstream_buffer_id_ = bitstream_record->input_id; 523 decoder_delay_bitstream_buffer_id_ = bitstream_record->input_id;
644 } else if (decoder_state_ == kError) { 524 } else if (decoder_state_ == kError) {
645 DVLOG(2) << "DecodeTask(): early out: kError state"; 525 DVLOG(2) << "DecodeTask(): early out: kError state";
646 return; 526 return;
647 } 527 }
648 528
649 decoder_input_queue_.push_back( 529 decoder_input_queue_.push(
650 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); 530 linked_ptr<BitstreamBufferRef>(bitstream_record.release()));
651 decoder_decode_buffer_tasks_scheduled_++; 531 decoder_decode_buffer_tasks_scheduled_++;
652 DecodeBufferTask(); 532 DecodeBufferTask();
653 } 533 }
654 534
655 void ExynosVideoDecodeAccelerator::DecodeBufferTask() { 535 void ExynosVideoDecodeAccelerator::DecodeBufferTask() {
656 DVLOG(3) << "DecodeBufferTask()"; 536 DVLOG(3) << "DecodeBufferTask()";
657 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 537 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
658 DCHECK_NE(decoder_state_, kUninitialized); 538 DCHECK_NE(decoder_state_, kUninitialized);
659 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask"); 539 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask");
(...skipping 17 matching lines...) Expand all
677 return; 557 return;
678 } 558 }
679 linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front(); 559 linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front();
680 if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) { 560 if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) {
681 // We're asked to delay decoding on this and subsequent buffers. 561 // We're asked to delay decoding on this and subsequent buffers.
682 return; 562 return;
683 } 563 }
684 564
685 // Setup to use the next buffer. 565 // Setup to use the next buffer.
686 decoder_current_bitstream_buffer_.reset(buffer_ref.release()); 566 decoder_current_bitstream_buffer_.reset(buffer_ref.release());
687 decoder_input_queue_.pop_front(); 567 decoder_input_queue_.pop();
688 DVLOG(3) << "DecodeBufferTask(): reading input_id=" 568 DVLOG(3) << "DecodeBufferTask(): reading input_id="
689 << decoder_current_bitstream_buffer_->input_id 569 << decoder_current_bitstream_buffer_->input_id
690 << ", addr=" << (decoder_current_bitstream_buffer_->shm ? 570 << ", addr=" << (decoder_current_bitstream_buffer_->shm ?
691 decoder_current_bitstream_buffer_->shm->memory() : 571 decoder_current_bitstream_buffer_->shm->memory() :
692 NULL) 572 NULL)
693 << ", size=" << decoder_current_bitstream_buffer_->size; 573 << ", size=" << decoder_current_bitstream_buffer_->size;
694 } 574 }
695 bool schedule_task = false; 575 bool schedule_task = false;
696 const size_t size = decoder_current_bitstream_buffer_->size; 576 const size_t size = decoder_current_bitstream_buffer_->size;
697 size_t decoded_size = 0; 577 size_t decoded_size = 0;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 // buffer was prompted by a flush buffer, and should be queued even when 909 // buffer was prompted by a flush buffer, and should be queued even when
1030 // empty. 910 // empty.
1031 if (input_record.input_id >= 0 && input_record.bytes_used == 0) { 911 if (input_record.input_id >= 0 && input_record.bytes_used == 0) {
1032 input_record.input_id = -1; 912 input_record.input_id = -1;
1033 mfc_free_input_buffers_.push_back(decoder_current_input_buffer_); 913 mfc_free_input_buffers_.push_back(decoder_current_input_buffer_);
1034 decoder_current_input_buffer_ = -1; 914 decoder_current_input_buffer_ = -1;
1035 return true; 915 return true;
1036 } 916 }
1037 917
1038 // Queue it to MFC. 918 // Queue it to MFC.
1039 mfc_input_ready_queue_.push_back(decoder_current_input_buffer_); 919 mfc_input_ready_queue_.push(decoder_current_input_buffer_);
1040 decoder_current_input_buffer_ = -1; 920 decoder_current_input_buffer_ = -1;
1041 DVLOG(3) << "FlushInputFrame(): submitting input_id=" 921 DVLOG(3) << "FlushInputFrame(): submitting input_id="
1042 << input_record.input_id; 922 << input_record.input_id;
1043 // Kick the MFC once since there's new available input for it. 923 // Kick the MFC once since there's new available input for it.
1044 EnqueueMfc(); 924 EnqueueMfc();
1045 925
1046 return (decoder_state_ != kError); 926 return (decoder_state_ != kError);
1047 } 927 }
1048 928
1049 void ExynosVideoDecodeAccelerator::AssignPictureBuffersTask( 929 void ExynosVideoDecodeAccelerator::AssignPictureBuffersTask(
1050 scoped_ptr<PictureBufferArrayRef> pic_buffers) { 930 scoped_ptr<PictureBufferArrayRef> pic_buffers) {
1051 DVLOG(3) << "AssignPictureBuffersTask()"; 931 DVLOG(3) << "AssignPictureBuffersTask()";
1052 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 932 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1053 DCHECK_NE(decoder_state_, kUninitialized); 933 DCHECK_NE(decoder_state_, kUninitialized);
1054 TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask"); 934 TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask");
1055 935
1056 // We run AssignPictureBuffersTask even if we're in kResetting. 936 // We run AssignPictureBuffersTask even if we're in kResetting.
1057 if (decoder_state_ == kError) { 937 if (decoder_state_ == kError) {
1058 DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state"; 938 DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state";
1059 return; 939 return;
1060 } 940 }
1061 941
1062 DCHECK_EQ(pic_buffers->picture_buffers.size(), gsc_output_buffer_map_.size()); 942 DCHECK_EQ(pic_buffers->picture_buffers.size(), mfc_output_buffer_map_.size());
1063 for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i) { 943 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
944 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
945 PictureBufferArrayRef::PictureBufferRef& buffer_ref =
946 pic_buffers->picture_buffers[i];
1064 // We should be blank right now. 947 // We should be blank right now.
1065 GscOutputRecord& output_record = gsc_output_buffer_map_[i]; 948 DCHECK(!output_record.at_device);
1066 DCHECK_EQ(output_record.fd, -1); 949 DCHECK(!output_record.at_client);
1067 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); 950 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR);
1068 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 951 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1069 DCHECK_EQ(output_record.picture_id, -1); 952 DCHECK_EQ(output_record.picture_id, -1);
1070 DCHECK_EQ(output_record.cleared, false); 953 DCHECK_EQ(output_record.cleared, false);
1071 PictureBufferArrayRef::PictureBufferRef& buffer = 954 output_record.egl_image = buffer_ref.egl_image;
1072 pic_buffers->picture_buffers[i]; 955 output_record.picture_id = buffer_ref.picture_id;
1073 output_record.fd = buffer.egl_image_fd; 956 mfc_free_output_buffers_.push(i);
1074 output_record.egl_image = buffer.egl_image; 957 DVLOG(3) << "AssignPictureBuffersTask(): buffer[" << i
1075 output_record.picture_id = buffer.client_id; 958 << "]: picture_id=" << buffer_ref.picture_id;
959 }
960 pic_buffers->picture_buffers.clear();
1076 961
1077 // Take ownership of the EGLImage and fd. 962 // We got buffers! Kick the MFC.
1078 buffer.egl_image = EGL_NO_IMAGE_KHR; 963 EnqueueMfc();
1079 buffer.egl_image_fd = -1;
1080 // And add this buffer to the free list.
1081 gsc_free_output_buffers_.push_back(i);
1082 }
1083
1084 // We got buffers! Kick the GSC.
1085 EnqueueGsc();
1086 964
1087 if (decoder_state_ == kChangingResolution) 965 if (decoder_state_ == kChangingResolution)
1088 ResumeAfterResolutionChange(); 966 ResumeAfterResolutionChange();
1089 } 967 }
1090 968
1091 void ExynosVideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) { 969 void ExynosVideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) {
1092 DVLOG(3) << "ServiceDeviceTask()"; 970 DVLOG(3) << "ServiceDeviceTask()";
1093 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 971 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1094 DCHECK_NE(decoder_state_, kUninitialized); 972 DCHECK_NE(decoder_state_, kUninitialized);
1095 DCHECK_NE(decoder_state_, kInitialized); 973 DCHECK_NE(decoder_state_, kInitialized);
1096 DCHECK_NE(decoder_state_, kAfterReset); 974 DCHECK_NE(decoder_state_, kAfterReset);
1097 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask"); 975 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask");
1098 976
1099 if (decoder_state_ == kResetting) { 977 if (decoder_state_ == kResetting) {
1100 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; 978 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state";
1101 return; 979 return;
1102 } else if (decoder_state_ == kError) { 980 } else if (decoder_state_ == kError) {
1103 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; 981 DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
1104 return; 982 return;
1105 } else if (decoder_state_ == kChangingResolution) { 983 } else if (decoder_state_ == kChangingResolution) {
1106 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; 984 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state";
1107 return; 985 return;
1108 } 986 }
1109 987
1110 if (mfc_event_pending) 988 if (mfc_event_pending)
1111 DequeueMfcEvents(); 989 DequeueMfcEvents();
1112 DequeueMfc(); 990 DequeueMfc();
1113 DequeueGsc();
1114 EnqueueMfc(); 991 EnqueueMfc();
1115 EnqueueGsc();
1116 992
1117 // Clear the interrupt fd. 993 // Clear the interrupt fd.
1118 if (!ClearDevicePollInterrupt()) 994 if (!ClearDevicePollInterrupt())
1119 return; 995 return;
1120 996
1121 unsigned int poll_fds = 0; 997 unsigned int poll_fds = 0;
1122 // Add MFC fd, if we should poll on it. 998 // Add MFC fd, if we should poll on it.
1123 // MFC can be polled as soon as either input or output buffers are queued. 999 // MFC can be polled as soon as either input or output buffers are queued.
1124 if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0) 1000 if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0)
1125 poll_fds |= kPollMfc; 1001 poll_fds |= kPollMfc;
1126 // Add GSC fd, if we should poll on it.
1127 // GSC has to wait until both input and output buffers are queued.
1128 if (gsc_input_buffer_queued_count_ > 0 && gsc_output_buffer_queued_count_ > 0)
1129 poll_fds |= kPollGsc;
1130 1002
1131 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 1003 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
1132 // so either: 1004 // so either:
1133 // * device_poll_thread_ is running normally 1005 // * device_poll_thread_ is running normally
1134 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() 1006 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask()
1135 // shut it down, in which case we're either in kResetting or kError states 1007 // shut it down, in which case we're either in kResetting or kError states
1136 // respectively, and we should have early-outed already. 1008 // respectively, and we should have early-outed already.
1137 DCHECK(device_poll_thread_.message_loop()); 1009 DCHECK(device_poll_thread_.message_loop());
1138 // Queue the DevicePollTask() now. 1010 // Queue the DevicePollTask() now.
1139 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1011 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1140 &ExynosVideoDecodeAccelerator::DevicePollTask, 1012 &ExynosVideoDecodeAccelerator::DevicePollTask,
1141 base::Unretained(this), 1013 base::Unretained(this),
1142 poll_fds)); 1014 poll_fds));
1143 1015
1144 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" 1016 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC["
1145 << decoder_input_queue_.size() << "->" 1017 << decoder_input_queue_.size() << "->"
1146 << mfc_input_ready_queue_.size() << "] => MFC[" 1018 << mfc_input_ready_queue_.size() << "] => MFC["
1147 << mfc_free_input_buffers_.size() << "+" 1019 << mfc_free_input_buffers_.size() << "+"
1148 << mfc_input_buffer_queued_count_ << "/" 1020 << mfc_input_buffer_queued_count_ << "/"
1149 << mfc_input_buffer_map_.size() << "->" 1021 << mfc_input_buffer_map_.size() << "->"
1150 << mfc_free_output_buffers_.size() << "+" 1022 << mfc_free_output_buffers_.size() << "+"
1151 << mfc_output_buffer_queued_count_ << "/" 1023 << mfc_output_buffer_queued_count_ << "/"
1152 << mfc_output_buffer_map_.size() << "] => " 1024 << mfc_output_buffer_map_.size() << "] => VDA["
1153 << mfc_output_gsc_input_queue_.size() << " => GSC["
1154 << gsc_free_input_buffers_.size() << "+"
1155 << gsc_input_buffer_queued_count_ << "/"
1156 << gsc_input_buffer_map_.size() << "->"
1157 << gsc_free_output_buffers_.size() << "+"
1158 << gsc_output_buffer_queued_count_ << "/"
1159 << gsc_output_buffer_map_.size() << "] => VDA["
1160 << decoder_frames_at_client_ << "]"; 1025 << decoder_frames_at_client_ << "]";
1161 1026
1162 ScheduleDecodeBufferTaskIfNeeded(); 1027 ScheduleDecodeBufferTaskIfNeeded();
1163 StartResolutionChangeIfNeeded(); 1028 StartResolutionChangeIfNeeded();
1164 } 1029 }
1165 1030
1166 void ExynosVideoDecodeAccelerator::EnqueueMfc() { 1031 void ExynosVideoDecodeAccelerator::EnqueueMfc() {
1167 DVLOG(3) << "EnqueueMfc()"; 1032 DVLOG(3) << "EnqueueMfc()";
1168 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1033 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1169 DCHECK_NE(decoder_state_, kUninitialized); 1034 DCHECK_NE(decoder_state_, kUninitialized);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 if (errno == EAGAIN) { 1143 if (errno == EAGAIN) {
1279 // EAGAIN if we're just out of buffers to dequeue. 1144 // EAGAIN if we're just out of buffers to dequeue.
1280 break; 1145 break;
1281 } 1146 }
1282 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF"; 1147 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF";
1283 NOTIFY_ERROR(PLATFORM_FAILURE); 1148 NOTIFY_ERROR(PLATFORM_FAILURE);
1284 return; 1149 return;
1285 } 1150 }
1286 MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index]; 1151 MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index];
1287 DCHECK(output_record.at_device); 1152 DCHECK(output_record.at_device);
1153 DCHECK(!output_record.at_client);
1154 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR);
1155 DCHECK_NE(output_record.picture_id, -1);
1288 output_record.at_device = false; 1156 output_record.at_device = false;
1289 output_record.bytes_used[0] = dqbuf.m.planes[0].bytesused; 1157 if (dqbuf.m.planes[0].bytesused + dqbuf.m.planes[1].bytesused == 0) {
1290 output_record.bytes_used[1] = dqbuf.m.planes[1].bytesused;
1291 if (output_record.bytes_used[0] + output_record.bytes_used[1] == 0) {
1292 // This is an empty output buffer returned as part of a flush. 1158 // This is an empty output buffer returned as part of a flush.
1293 mfc_free_output_buffers_.push_back(dqbuf.index); 1159 mfc_free_output_buffers_.push(dqbuf.index);
1294 output_record.input_id = -1;
1295 } else { 1160 } else {
1296 // This is an output buffer with contents to pass down the pipe. 1161 DCHECK_GE(dqbuf.timestamp.tv_sec, 0);
1297 mfc_output_gsc_input_queue_.push_back(dqbuf.index); 1162 output_record.at_client = true;
1298 output_record.input_id = dqbuf.timestamp.tv_sec; 1163 DVLOG(3) << "DequeueMfc(): returning input_id=" << dqbuf.timestamp.tv_sec
1299 DCHECK(output_record.input_id >= 0); 1164 << " as picture_id=" << output_record.picture_id;
1300 DVLOG(3) << "DequeueMfc(): dequeued input_id=" << output_record.input_id; 1165 const media::Picture& picture =
1301 // We don't count this output buffer dequeued yet, or add it to the free 1166 media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec);
1302 // list, as it has data GSC needs to process. 1167 pending_picture_ready_.push(
1303 1168 PictureRecord(output_record.cleared, picture));
1304 // We have new frames in mfc_output_gsc_input_queue_. Kick the pipe. 1169 SendPictureReady();
1305 SetDevicePollInterrupt(); 1170 output_record.cleared = true;
1171 decoder_frames_at_client_++;
1306 } 1172 }
1307 mfc_output_buffer_queued_count_--; 1173 mfc_output_buffer_queued_count_--;
1308 } 1174 }
1309 1175
1310 NotifyFlushDoneIfNeeded(); 1176 NotifyFlushDoneIfNeeded();
1311 } 1177 }
1312 1178
1313 void ExynosVideoDecodeAccelerator::EnqueueGsc() {
1314 DVLOG(3) << "EnqueueGsc()";
1315 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1316 DCHECK_NE(decoder_state_, kUninitialized);
1317 DCHECK_NE(decoder_state_, kInitialized);
1318 TRACE_EVENT0("Video Decoder", "EVDA::EnqueueGsc");
1319
1320 // Drain the pipe of completed MFC output buffers.
1321 const int old_gsc_inputs_queued = gsc_input_buffer_queued_count_;
1322 while (!mfc_output_gsc_input_queue_.empty() &&
1323 !gsc_free_input_buffers_.empty()) {
1324 if (!EnqueueGscInputRecord())
1325 return;
1326 }
1327 if (old_gsc_inputs_queued == 0 && gsc_input_buffer_queued_count_ != 0) {
1328 // We just started up a previously empty queue.
1329 // Queue state changed; signal interrupt.
1330 if (!SetDevicePollInterrupt())
1331 return;
1332 // Start VIDIOC_STREAMON if we haven't yet.
1333 if (!gsc_input_streamon_) {
1334 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1335 IOCTL_OR_ERROR_RETURN(gsc_fd_, VIDIOC_STREAMON, &type);
1336 gsc_input_streamon_ = true;
1337 }
1338 }
1339
1340 if (gsc_input_buffer_queued_count_ != 0 &&
1341 gsc_output_buffer_queued_count_ == 0 &&
1342 !gsc_free_output_buffers_.empty()) {
1343 const int old_gsc_outputs_queued = gsc_output_buffer_queued_count_;
1344 if (!EnqueueGscOutputRecord())
1345 return;
1346 if (old_gsc_outputs_queued == 0 && gsc_output_buffer_queued_count_ != 0) {
1347 // We just started up a previously empty queue.
1348 // Queue state changed; signal interrupt.
1349 if (!SetDevicePollInterrupt())
1350 return;
1351 // Start VIDIOC_STREAMON if we haven't yet.
1352 if (!gsc_output_streamon_) {
1353 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1354 IOCTL_OR_ERROR_RETURN(gsc_fd_, VIDIOC_STREAMON, &type);
1355 gsc_output_streamon_ = true;
1356 }
1357 }
1358 }
1359 // Bug check: GSC is liable to race conditions if more than one buffer is
1360 // simultaneously queued.
1361 DCHECK_GE(1, gsc_output_buffer_queued_count_);
1362 }
1363
1364 void ExynosVideoDecodeAccelerator::DequeueGsc() {
1365 DVLOG(3) << "DequeueGsc()";
1366 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1367 DCHECK_NE(decoder_state_, kUninitialized);
1368 DCHECK_NE(decoder_state_, kInitialized);
1369 DCHECK_NE(decoder_state_, kAfterReset);
1370 TRACE_EVENT0("Video Decoder", "EVDA::DequeueGsc");
1371
1372 // Dequeue completed GSC input (VIDEO_OUTPUT) buffers, and recycle to the free
1373 // list. Also recycle the corresponding MFC output buffers at this time.
1374 struct v4l2_buffer dqbuf;
1375 struct v4l2_plane planes[2];
1376 while (gsc_input_buffer_queued_count_ > 0) {
1377 DCHECK(gsc_input_streamon_);
1378 memset(&dqbuf, 0, sizeof(dqbuf));
1379 memset(planes, 0, sizeof(planes));
1380 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1381 dqbuf.memory = V4L2_MEMORY_DMABUF;
1382 dqbuf.m.planes = planes;
1383 dqbuf.length = 2;
1384 if (ioctl(gsc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) {
1385 if (errno == EAGAIN) {
1386 // EAGAIN if we're just out of buffers to dequeue.
1387 break;
1388 }
1389 DPLOG(ERROR) << "DequeueGsc(): ioctl() failed: VIDIOC_DQBUF";
1390 NOTIFY_ERROR(PLATFORM_FAILURE);
1391 return;
1392 }
1393 GscInputRecord& input_record = gsc_input_buffer_map_[dqbuf.index];
1394 MfcOutputRecord& output_record =
1395 mfc_output_buffer_map_[input_record.mfc_output];
1396 DCHECK(input_record.at_device);
1397 gsc_free_input_buffers_.push_back(dqbuf.index);
1398 mfc_free_output_buffers_.push_back(input_record.mfc_output);
1399 input_record.at_device = false;
1400 input_record.mfc_output = -1;
1401 output_record.input_id = -1;
1402 gsc_input_buffer_queued_count_--;
1403 }
1404
1405 // Dequeue completed GSC output (VIDEO_CAPTURE) buffers, and send them off to
1406 // the client. Don't recycle to its free list yet -- we can't do that until
1407 // ReusePictureBuffer() returns it to us.
1408 while (gsc_output_buffer_queued_count_ > 0) {
1409 DCHECK(gsc_output_streamon_);
1410 memset(&dqbuf, 0, sizeof(dqbuf));
1411 memset(planes, 0, sizeof(planes));
1412 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1413 dqbuf.memory = V4L2_MEMORY_DMABUF;
1414 dqbuf.m.planes = planes;
1415 dqbuf.length = 1;
1416 if (ioctl(gsc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) {
1417 if (errno == EAGAIN) {
1418 // EAGAIN if we're just out of buffers to dequeue.
1419 break;
1420 }
1421 DPLOG(ERROR) << "DequeueGsc(): ioctl() failed: VIDIOC_DQBUF";
1422 NOTIFY_ERROR(PLATFORM_FAILURE);
1423 return;
1424 }
1425 GscOutputRecord& output_record = gsc_output_buffer_map_[dqbuf.index];
1426 DCHECK(output_record.at_device);
1427 DCHECK(!output_record.at_client);
1428 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1429 output_record.at_device = false;
1430 output_record.at_client = true;
1431 gsc_output_buffer_queued_count_--;
1432 DVLOG(3) << "DequeueGsc(): returning input_id=" << dqbuf.timestamp.tv_sec
1433 << " as picture_id=" << output_record.picture_id;
1434 const media::Picture& picture =
1435 media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec);
1436 pending_picture_ready_.push(PictureRecord(output_record.cleared, picture));
1437 SendPictureReady();
1438 output_record.cleared = true;
1439 decoder_frames_at_client_++;
1440 }
1441
1442 NotifyFlushDoneIfNeeded();
1443 }
1444
1445 bool ExynosVideoDecodeAccelerator::EnqueueMfcInputRecord() { 1179 bool ExynosVideoDecodeAccelerator::EnqueueMfcInputRecord() {
1446 DVLOG(3) << "EnqueueMfcInputRecord()"; 1180 DVLOG(3) << "EnqueueMfcInputRecord()";
1447 DCHECK(!mfc_input_ready_queue_.empty()); 1181 DCHECK(!mfc_input_ready_queue_.empty());
1448 1182
1449 // Enqueue a MFC input (VIDEO_OUTPUT) buffer. 1183 // Enqueue a MFC input (VIDEO_OUTPUT) buffer.
1450 const int buffer = mfc_input_ready_queue_.back(); 1184 const int buffer = mfc_input_ready_queue_.front();
1451 MfcInputRecord& input_record = mfc_input_buffer_map_[buffer]; 1185 MfcInputRecord& input_record = mfc_input_buffer_map_[buffer];
1452 DCHECK(!input_record.at_device); 1186 DCHECK(!input_record.at_device);
1453 struct v4l2_buffer qbuf; 1187 struct v4l2_buffer qbuf;
1454 struct v4l2_plane qbuf_plane; 1188 struct v4l2_plane qbuf_plane;
1455 memset(&qbuf, 0, sizeof(qbuf)); 1189 memset(&qbuf, 0, sizeof(qbuf));
1456 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); 1190 memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1457 qbuf.index = buffer; 1191 qbuf.index = buffer;
1458 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1192 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1459 qbuf.timestamp.tv_sec = input_record.input_id; 1193 qbuf.timestamp.tv_sec = input_record.input_id;
1460 qbuf.memory = V4L2_MEMORY_MMAP; 1194 qbuf.memory = V4L2_MEMORY_MMAP;
1461 qbuf.m.planes = &qbuf_plane; 1195 qbuf.m.planes = &qbuf_plane;
1462 qbuf.m.planes[0].bytesused = input_record.bytes_used; 1196 qbuf.m.planes[0].bytesused = input_record.bytes_used;
1463 qbuf.length = 1; 1197 qbuf.length = 1;
1464 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf); 1198 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf);
1465 mfc_input_ready_queue_.pop_back(); 1199 mfc_input_ready_queue_.pop();
1466 input_record.at_device = true; 1200 input_record.at_device = true;
1467 mfc_input_buffer_queued_count_++; 1201 mfc_input_buffer_queued_count_++;
1468 DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id=" 1202 DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id="
1469 << input_record.input_id; 1203 << input_record.input_id;
1470 return true; 1204 return true;
1471 } 1205 }
1472 1206
1473 bool ExynosVideoDecodeAccelerator::EnqueueMfcOutputRecord() { 1207 bool ExynosVideoDecodeAccelerator::EnqueueMfcOutputRecord() {
1474 DVLOG(3) << "EnqueueMfcOutputRecord()"; 1208 DVLOG(3) << "EnqueueMfcOutputRecord()";
1475 DCHECK(!mfc_free_output_buffers_.empty()); 1209 DCHECK(!mfc_free_output_buffers_.empty());
1476 1210
1477 // Enqueue a MFC output (VIDEO_CAPTURE) buffer. 1211 // Enqueue a MFC output (VIDEO_CAPTURE) buffer.
1478 const int buffer = mfc_free_output_buffers_.back(); 1212 const int buffer = mfc_free_output_buffers_.front();
1479 MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer]; 1213 MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer];
1480 DCHECK(!output_record.at_device); 1214 DCHECK(!output_record.at_device);
1481 DCHECK_EQ(output_record.input_id, -1);
1482 struct v4l2_buffer qbuf;
1483 struct v4l2_plane qbuf_planes[2];
1484 memset(&qbuf, 0, sizeof(qbuf));
1485 memset(qbuf_planes, 0, sizeof(qbuf_planes));
1486 qbuf.index = buffer;
1487 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1488 qbuf.memory = V4L2_MEMORY_MMAP;
1489 qbuf.m.planes = qbuf_planes;
1490 qbuf.length = 2;
1491 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf);
1492 mfc_free_output_buffers_.pop_back();
1493 output_record.at_device = true;
1494 mfc_output_buffer_queued_count_++;
1495 return true;
1496 }
1497
1498 bool ExynosVideoDecodeAccelerator::EnqueueGscInputRecord() {
1499 DVLOG(3) << "EnqueueGscInputRecord()";
1500 DCHECK(!gsc_free_input_buffers_.empty());
1501
1502 // Enqueue a GSC input (VIDEO_OUTPUT) buffer for a complete MFC output
1503 // (VIDEO_CAPTURE) buffer.
1504 const int mfc_buffer = mfc_output_gsc_input_queue_.front();
1505 const int gsc_buffer = gsc_free_input_buffers_.back();
1506 MfcOutputRecord& output_record = mfc_output_buffer_map_[mfc_buffer];
1507 DCHECK(!output_record.at_device);
1508 GscInputRecord& input_record = gsc_input_buffer_map_[gsc_buffer];
1509 DCHECK(!input_record.at_device);
1510 DCHECK_EQ(input_record.mfc_output, -1);
1511 struct v4l2_buffer qbuf;
1512 struct v4l2_plane qbuf_planes[2];
1513 memset(&qbuf, 0, sizeof(qbuf));
1514 memset(qbuf_planes, 0, sizeof(qbuf_planes));
1515 qbuf.index = gsc_buffer;
1516 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1517 qbuf.timestamp.tv_sec = output_record.input_id;
1518 qbuf.memory = V4L2_MEMORY_USERPTR;
1519 qbuf.m.planes = qbuf_planes;
1520 qbuf.m.planes[0].bytesused = output_record.bytes_used[0];
1521 qbuf.m.planes[0].length = mfc_output_buffer_size_[0];
1522 qbuf.m.planes[0].m.userptr = (unsigned long)output_record.address[0];
1523 qbuf.m.planes[1].bytesused = output_record.bytes_used[1];
1524 qbuf.m.planes[1].length = mfc_output_buffer_size_[1];
1525 qbuf.m.planes[1].m.userptr = (unsigned long)output_record.address[1];
1526 qbuf.length = 2;
1527 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QBUF, &qbuf);
1528 mfc_output_gsc_input_queue_.pop_front();
1529 gsc_free_input_buffers_.pop_back();
1530 input_record.at_device = true;
1531 input_record.mfc_output = mfc_buffer;
1532 output_record.bytes_used[0] = 0;
1533 output_record.bytes_used[1] = 0;
1534 gsc_input_buffer_queued_count_++;
1535 DVLOG(3) << "EnqueueGscInputRecord(): enqueued input_id="
1536 << output_record.input_id;
1537 return true;
1538 }
1539
1540 bool ExynosVideoDecodeAccelerator::EnqueueGscOutputRecord() {
1541 DVLOG(3) << "EnqueueGscOutputRecord()";
1542 DCHECK(!gsc_free_output_buffers_.empty());
1543
1544 // Enqueue a GSC output (VIDEO_CAPTURE) buffer.
1545 const int buffer = gsc_free_output_buffers_.front();
1546 GscOutputRecord& output_record = gsc_output_buffer_map_[buffer];
1547 DCHECK(!output_record.at_device);
1548 DCHECK(!output_record.at_client); 1215 DCHECK(!output_record.at_client);
1216 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR);
1217 DCHECK_NE(output_record.picture_id, -1);
1549 if (output_record.egl_sync != EGL_NO_SYNC_KHR) { 1218 if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
1550 TRACE_EVENT0( 1219 TRACE_EVENT0("Video Decoder",
1551 "Video Decoder", 1220 "EVDA::EnqueueMfcOutputRecord: eglClientWaitSyncKHR");
1552 "EVDA::EnqueueGscOutputRecord: eglClientWaitSyncKHR");
1553 // If we have to wait for completion, wait. Note that 1221 // If we have to wait for completion, wait. Note that
1554 // gsc_free_output_buffers_ is a FIFO queue, so we always wait on the 1222 // mfc_free_output_buffers_ is a FIFO queue, so we always wait on the
1555 // buffer that has been in the queue the longest. 1223 // buffer that has been in the queue the longest.
1556 eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0, 1224 eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0,
1557 EGL_FOREVER_KHR); 1225 EGL_FOREVER_KHR);
1558 eglDestroySyncKHR(egl_display_, output_record.egl_sync); 1226 eglDestroySyncKHR(egl_display_, output_record.egl_sync);
1559 output_record.egl_sync = EGL_NO_SYNC_KHR; 1227 output_record.egl_sync = EGL_NO_SYNC_KHR;
1560 } 1228 }
1561 struct v4l2_buffer qbuf; 1229 struct v4l2_buffer qbuf;
1562 struct v4l2_plane qbuf_plane; 1230 struct v4l2_plane qbuf_planes[arraysize(output_record.fds)];
1563 memset(&qbuf, 0, sizeof(qbuf)); 1231 memset(&qbuf, 0, sizeof(qbuf));
1564 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); 1232 memset(qbuf_planes, 0, sizeof(qbuf_planes));
1565 qbuf.index = buffer; 1233 qbuf.index = buffer;
1566 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1234 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1567 qbuf.memory = V4L2_MEMORY_DMABUF; 1235 qbuf.memory = V4L2_MEMORY_MMAP;
1568 qbuf.m.planes = &qbuf_plane; 1236 qbuf.m.planes = qbuf_planes;
1569 qbuf.m.planes[0].m.fd = output_record.fd; 1237 qbuf.length = arraysize(output_record.fds);
1570 qbuf.length = 1; 1238 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf);
1571 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QBUF, &qbuf); 1239 mfc_free_output_buffers_.pop();
1572 gsc_free_output_buffers_.pop_front();
1573 output_record.at_device = true; 1240 output_record.at_device = true;
1574 gsc_output_buffer_queued_count_++; 1241 mfc_output_buffer_queued_count_++;
1575 return true; 1242 return true;
1576 } 1243 }
1577 1244
1578 void ExynosVideoDecodeAccelerator::ReusePictureBufferTask( 1245 void ExynosVideoDecodeAccelerator::ReusePictureBufferTask(
1579 int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) { 1246 int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) {
1580 DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id=" 1247 DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id="
1581 << picture_buffer_id; 1248 << picture_buffer_id;
1582 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1249 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1583 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask"); 1250 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask");
1584 1251
1585 // We run ReusePictureBufferTask even if we're in kResetting. 1252 // We run ReusePictureBufferTask even if we're in kResetting.
1586 if (decoder_state_ == kError) { 1253 if (decoder_state_ == kError) {
1587 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state"; 1254 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state";
1588 return; 1255 return;
1589 } 1256 }
1590 1257
1591 if (decoder_state_ == kChangingResolution) { 1258 if (decoder_state_ == kChangingResolution) {
1592 DVLOG(2) << "ReusePictureBufferTask(): early out: kChangingResolution"; 1259 DVLOG(2) << "ReusePictureBufferTask(): early out: kChangingResolution";
1593 return; 1260 return;
1594 } 1261 }
1595 1262
1596 size_t index; 1263 size_t index;
1597 for (index = 0; index < gsc_output_buffer_map_.size(); ++index) 1264 for (index = 0; index < mfc_output_buffer_map_.size(); ++index)
1598 if (gsc_output_buffer_map_[index].picture_id == picture_buffer_id) 1265 if (mfc_output_buffer_map_[index].picture_id == picture_buffer_id)
1599 break; 1266 break;
1600 1267
1601 if (index >= gsc_output_buffer_map_.size()) { 1268 if (index >= mfc_output_buffer_map_.size()) {
1602 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not found"; 1269 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not found";
1603 NOTIFY_ERROR(INVALID_ARGUMENT); 1270 NOTIFY_ERROR(INVALID_ARGUMENT);
1604 return; 1271 return;
1605 } 1272 }
1606 1273
1607 GscOutputRecord& output_record = gsc_output_buffer_map_[index]; 1274 MfcOutputRecord& output_record = mfc_output_buffer_map_[index];
1608 if (output_record.at_device || !output_record.at_client) { 1275 if (output_record.at_device || !output_record.at_client) {
1609 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not reusable"; 1276 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not reusable";
1610 NOTIFY_ERROR(INVALID_ARGUMENT); 1277 NOTIFY_ERROR(INVALID_ARGUMENT);
1611 return; 1278 return;
1612 } 1279 }
1613 1280
1614 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 1281 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1615 output_record.at_client = false; 1282 output_record.at_client = false;
1616 output_record.egl_sync = egl_sync_ref->egl_sync; 1283 output_record.egl_sync = egl_sync_ref->egl_sync;
1617 gsc_free_output_buffers_.push_back(index); 1284 mfc_free_output_buffers_.push(index);
1618 decoder_frames_at_client_--; 1285 decoder_frames_at_client_--;
1619 // Take ownership of the EGLSync. 1286 // Take ownership of the EGLSync.
1620 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR; 1287 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR;
1621 // We got a buffer back, so kick the GSC. 1288 // We got a buffer back, so kick the MFC.
1622 EnqueueGsc(); 1289 EnqueueMfc();
1623 } 1290 }
1624 1291
1625 void ExynosVideoDecodeAccelerator::FlushTask() { 1292 void ExynosVideoDecodeAccelerator::FlushTask() {
1626 DVLOG(3) << "FlushTask()"; 1293 DVLOG(3) << "FlushTask()";
1627 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1294 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1628 TRACE_EVENT0("Video Decoder", "EVDA::FlushTask"); 1295 TRACE_EVENT0("Video Decoder", "EVDA::FlushTask");
1629 1296
1630 // Flush outstanding buffers. 1297 // Flush outstanding buffers.
1631 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) { 1298 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) {
1632 // There's nothing in the pipe, so return done immediately. 1299 // There's nothing in the pipe, so return done immediately.
1633 DVLOG(3) << "FlushTask(): returning flush"; 1300 DVLOG(3) << "FlushTask(): returning flush";
1634 child_message_loop_proxy_->PostTask( 1301 child_message_loop_proxy_->PostTask(
1635 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); 1302 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_));
1636 return; 1303 return;
1637 } else if (decoder_state_ == kError) { 1304 } else if (decoder_state_ == kError) {
1638 DVLOG(2) << "FlushTask(): early out: kError state"; 1305 DVLOG(2) << "FlushTask(): early out: kError state";
1639 return; 1306 return;
1640 } 1307 }
1641 1308
1642 // We don't support stacked flushing. 1309 // We don't support stacked flushing.
1643 DCHECK(!decoder_flushing_); 1310 DCHECK(!decoder_flushing_);
1644 1311
1645 // Queue up an empty buffer -- this triggers the flush. 1312 // Queue up an empty buffer -- this triggers the flush.
1646 decoder_input_queue_.push_back(linked_ptr<BitstreamBufferRef>( 1313 decoder_input_queue_.push(
1647 new BitstreamBufferRef(io_client_, io_message_loop_proxy_, NULL, 0, 1314 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
1648 kFlushBufferId))); 1315 io_client_, io_message_loop_proxy_, NULL, 0, kFlushBufferId)));
1649 decoder_flushing_ = true; 1316 decoder_flushing_ = true;
1650 SendPictureReady(); // Send all pending PictureReady. 1317 SendPictureReady(); // Send all pending PictureReady.
1651 1318
1652 ScheduleDecodeBufferTaskIfNeeded(); 1319 ScheduleDecodeBufferTaskIfNeeded();
1653 } 1320 }
1654 1321
1655 void ExynosVideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { 1322 void ExynosVideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
1656 if (!decoder_flushing_) 1323 if (!decoder_flushing_)
1657 return; 1324 return;
1658 1325
1659 // Pipeline is empty when: 1326 // Pipeline is empty when:
1660 // * Decoder input queue is empty of non-delayed buffers. 1327 // * Decoder input queue is empty of non-delayed buffers.
1661 // * There is no currently filling input buffer. 1328 // * There is no currently filling input buffer.
1662 // * MFC input holding queue is empty. 1329 // * MFC input holding queue is empty.
1663 // * All MFC input (VIDEO_OUTPUT) buffers are returned. 1330 // * All MFC input (VIDEO_OUTPUT) buffers are returned.
1664 // * MFC -> GSC holding queue is empty.
1665 // * All GSC input (VIDEO_OUTPUT) buffers are returned.
1666 if (!decoder_input_queue_.empty()) { 1331 if (!decoder_input_queue_.empty()) {
1667 if (decoder_input_queue_.front()->input_id != 1332 if (decoder_input_queue_.front()->input_id !=
1668 decoder_delay_bitstream_buffer_id_) 1333 decoder_delay_bitstream_buffer_id_)
1669 return; 1334 return;
1670 } 1335 }
1671 if (decoder_current_input_buffer_ != -1) 1336 if (decoder_current_input_buffer_ != -1)
1672 return; 1337 return;
1673 if ((mfc_input_ready_queue_.size() + 1338 if ((mfc_input_ready_queue_.size() + mfc_input_buffer_queued_count_) != 0)
1674 mfc_input_buffer_queued_count_ + mfc_output_gsc_input_queue_.size() +
1675 gsc_input_buffer_queued_count_ + gsc_output_buffer_queued_count_ ) != 0)
1676 return; 1339 return;
1677 1340
1678 // TODO(posciak): crbug.com/270039. MFC requires a streamoff-streamon 1341 // TODO(posciak): crbug.com/270039. MFC requires a streamoff-streamon
1679 // sequence after flush to continue, even if we are not resetting. This would 1342 // sequence after flush to continue, even if we are not resetting. This would
1680 // make sense, because we don't really want to resume from a non-resume point 1343 // make sense, because we don't really want to resume from a non-resume point
1681 // (e.g. not from an IDR) if we are flushed. 1344 // (e.g. not from an IDR) if we are flushed.
1682 // MSE player however triggers a Flush() on chunk end, but never Reset(). One 1345 // MSE player however triggers a Flush() on chunk end, but never Reset(). One
1683 // could argue either way, or even say that Flush() is not needed/harmful when 1346 // could argue either way, or even say that Flush() is not needed/harmful when
1684 // transitioning to next chunk. 1347 // transitioning to next chunk.
1685 // For now, do the streamoff-streamon cycle to satisfy MFC and not freeze when 1348 // For now, do the streamoff-streamon cycle to satisfy MFC and not freeze when
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 // We stop streaming and clear buffer tracking info (not preserving 1386 // We stop streaming and clear buffer tracking info (not preserving
1724 // MFC inputs). 1387 // MFC inputs).
1725 // StopDevicePoll() unconditionally does _not_ destroy buffers, however. 1388 // StopDevicePoll() unconditionally does _not_ destroy buffers, however.
1726 if (!StopDevicePoll(false)) 1389 if (!StopDevicePoll(false))
1727 return; 1390 return;
1728 1391
1729 DequeueMfcEvents(); 1392 DequeueMfcEvents();
1730 1393
1731 resolution_change_pending_ = false; 1394 resolution_change_pending_ = false;
1732 decoder_current_bitstream_buffer_.reset(); 1395 decoder_current_bitstream_buffer_.reset();
1733 decoder_input_queue_.clear(); 1396 while (!decoder_input_queue_.empty())
1397 decoder_input_queue_.pop();
1734 1398
1735 decoder_current_input_buffer_ = -1; 1399 decoder_current_input_buffer_ = -1;
1736 1400
1737 // If we were flushing, we'll never return any more BitstreamBuffers or 1401 // If we were flushing, we'll never return any more BitstreamBuffers or
1738 // PictureBuffers; they have all been dropped and returned by now. 1402 // PictureBuffers; they have all been dropped and returned by now.
1739 NotifyFlushDoneIfNeeded(); 1403 NotifyFlushDoneIfNeeded();
1740 1404
1741 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening 1405 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening
1742 // jobs will early-out in the kResetting state. 1406 // jobs will early-out in the kResetting state.
1743 decoder_state_ = kResetting; 1407 decoder_state_ = kResetting;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 1444
1781 // DestroyTask() should run regardless of decoder_state_. 1445 // DestroyTask() should run regardless of decoder_state_.
1782 1446
1783 // Stop streaming and the device_poll_thread_. 1447 // Stop streaming and the device_poll_thread_.
1784 StopDevicePoll(false); 1448 StopDevicePoll(false);
1785 1449
1786 decoder_current_bitstream_buffer_.reset(); 1450 decoder_current_bitstream_buffer_.reset();
1787 decoder_current_input_buffer_ = -1; 1451 decoder_current_input_buffer_ = -1;
1788 decoder_decode_buffer_tasks_scheduled_ = 0; 1452 decoder_decode_buffer_tasks_scheduled_ = 0;
1789 decoder_frames_at_client_ = 0; 1453 decoder_frames_at_client_ = 0;
1790 decoder_input_queue_.clear(); 1454 while (!decoder_input_queue_.empty())
1455 decoder_input_queue_.pop();
1791 decoder_flushing_ = false; 1456 decoder_flushing_ = false;
1792 1457
1793 // Set our state to kError. Just in case. 1458 // Set our state to kError. Just in case.
1794 decoder_state_ = kError; 1459 decoder_state_ = kError;
1795 } 1460 }
1796 1461
1797 bool ExynosVideoDecodeAccelerator::StartDevicePoll() { 1462 bool ExynosVideoDecodeAccelerator::StartDevicePoll() {
1798 DVLOG(3) << "StartDevicePoll()"; 1463 DVLOG(3) << "StartDevicePoll()";
1799 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1464 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1800 DCHECK(!device_poll_thread_.IsRunning()); 1465 DCHECK(!device_poll_thread_.IsRunning());
(...skipping 30 matching lines...) Expand all
1831 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1496 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1832 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); 1497 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
1833 } 1498 }
1834 mfc_input_streamon_ = false; 1499 mfc_input_streamon_ = false;
1835 } 1500 }
1836 if (mfc_output_streamon_) { 1501 if (mfc_output_streamon_) {
1837 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1502 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1838 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); 1503 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
1839 } 1504 }
1840 mfc_output_streamon_ = false; 1505 mfc_output_streamon_ = false;
1841 if (gsc_input_streamon_) {
1842 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1843 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type);
1844 }
1845 gsc_input_streamon_ = false;
1846 if (gsc_output_streamon_) {
1847 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1848 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type);
1849 }
1850 gsc_output_streamon_ = false;
1851 1506
1852 // Reset all our accounting info. 1507 // Reset all our accounting info.
1853 if (!keep_mfc_input_state) { 1508 if (!keep_mfc_input_state) {
1854 mfc_input_ready_queue_.clear(); 1509 while (!mfc_input_ready_queue_.empty())
1510 mfc_input_ready_queue_.pop();
1855 mfc_free_input_buffers_.clear(); 1511 mfc_free_input_buffers_.clear();
1856 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { 1512 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
1857 mfc_free_input_buffers_.push_back(i); 1513 mfc_free_input_buffers_.push_back(i);
1858 mfc_input_buffer_map_[i].at_device = false; 1514 mfc_input_buffer_map_[i].at_device = false;
1859 mfc_input_buffer_map_[i].bytes_used = 0; 1515 mfc_input_buffer_map_[i].bytes_used = 0;
1860 mfc_input_buffer_map_[i].input_id = -1; 1516 mfc_input_buffer_map_[i].input_id = -1;
1861 } 1517 }
1862 mfc_input_buffer_queued_count_ = 0; 1518 mfc_input_buffer_queued_count_ = 0;
1863 } 1519 }
1864 mfc_free_output_buffers_.clear(); 1520 while (!mfc_free_output_buffers_.empty())
1521 mfc_free_output_buffers_.pop();
1865 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { 1522 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
1866 mfc_free_output_buffers_.push_back(i); 1523 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
1867 mfc_output_buffer_map_[i].at_device = false; 1524 // Only mark those free that aren't being held by the VDA client.
1868 mfc_output_buffer_map_[i].input_id = -1; 1525 if (!output_record.at_client) {
1526 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1527 mfc_free_output_buffers_.push(i);
1528 mfc_output_buffer_map_[i].at_device = false;
1529 }
1869 } 1530 }
1870 mfc_output_buffer_queued_count_ = 0; 1531 mfc_output_buffer_queued_count_ = 0;
1871 mfc_output_gsc_input_queue_.clear();
1872 gsc_free_input_buffers_.clear();
1873 for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) {
1874 gsc_free_input_buffers_.push_back(i);
1875 gsc_input_buffer_map_[i].at_device = false;
1876 gsc_input_buffer_map_[i].mfc_output = -1;
1877 }
1878 gsc_input_buffer_queued_count_ = 0;
1879 gsc_free_output_buffers_.clear();
1880 for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i) {
1881 // Only mark those free that aren't being held by the VDA.
1882 if (!gsc_output_buffer_map_[i].at_client) {
1883 gsc_free_output_buffers_.push_back(i);
1884 gsc_output_buffer_map_[i].at_device = false;
1885 }
1886 }
1887 gsc_output_buffer_queued_count_ = 0;
1888 1532
1889 DVLOG(3) << "StopDevicePoll(): device poll stopped"; 1533 DVLOG(3) << "StopDevicePoll(): device poll stopped";
1890 return true; 1534 return true;
1891 } 1535 }
1892 1536
1893 bool ExynosVideoDecodeAccelerator::SetDevicePollInterrupt() { 1537 bool ExynosVideoDecodeAccelerator::SetDevicePollInterrupt() {
1894 DVLOG(3) << "SetDevicePollInterrupt()"; 1538 DVLOG(3) << "SetDevicePollInterrupt()";
1895 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1539 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1896 1540
1897 const uint64 buf = 1; 1541 const uint64 buf = 1;
(...skipping 23 matching lines...) Expand all
1921 return true; 1565 return true;
1922 } 1566 }
1923 1567
1924 void ExynosVideoDecodeAccelerator::StartResolutionChangeIfNeeded() { 1568 void ExynosVideoDecodeAccelerator::StartResolutionChangeIfNeeded() {
1925 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1569 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1926 DCHECK_EQ(decoder_state_, kDecoding); 1570 DCHECK_EQ(decoder_state_, kDecoding);
1927 1571
1928 if (!resolution_change_pending_) 1572 if (!resolution_change_pending_)
1929 return; 1573 return;
1930 1574
1931 if (!mfc_output_gsc_input_queue_.empty() || 1575 DVLOG(3) << "No more work, initiate resolution change";
1932 gsc_input_buffer_queued_count_ + gsc_output_buffer_queued_count_ > 0) {
1933 DVLOG(3) << "StartResolutionChangeIfNeeded(): waiting for GSC to finish.";
1934 return;
1935 }
1936
1937 DVLOG(3) << "No more work for GSC, initiate resolution change";
1938 1576
1939 // Keep MFC input queue. 1577 // Keep MFC input queue.
1940 if (!StopDevicePoll(true)) 1578 if (!StopDevicePoll(true))
1941 return; 1579 return;
1942 1580
1943 decoder_state_ = kChangingResolution; 1581 decoder_state_ = kChangingResolution;
1944 DCHECK(resolution_change_pending_); 1582 DCHECK(resolution_change_pending_);
1945 resolution_change_pending_ = false; 1583 resolution_change_pending_ = false;
1946 1584
1947 // Post a task to clean up buffers on child thread. This will also ensure 1585 // Post a task to clean up buffers on child thread. This will also ensure
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1988 if (resolution_change_reset_pending_) { 1626 if (resolution_change_reset_pending_) {
1989 resolution_change_reset_pending_ = false; 1627 resolution_change_reset_pending_ = false;
1990 ResetTask(); 1628 ResetTask();
1991 return; 1629 return;
1992 } 1630 }
1993 1631
1994 if (!StartDevicePoll()) 1632 if (!StartDevicePoll())
1995 return; 1633 return;
1996 1634
1997 EnqueueMfc(); 1635 EnqueueMfc();
1998 // Gsc will get enqueued in AssignPictureBuffersTask().
1999 ScheduleDecodeBufferTaskIfNeeded(); 1636 ScheduleDecodeBufferTaskIfNeeded();
2000 } 1637 }
2001 1638
2002 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) { 1639 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) {
2003 DVLOG(3) << "DevicePollTask()"; 1640 DVLOG(3) << "DevicePollTask()";
2004 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); 1641 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
2005 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask"); 1642 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask");
2006 1643
2007 // This routine just polls the set of device fds, and schedules a 1644 // This routine just polls the set of device fds, and schedules a
2008 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur. 1645 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur.
2009 // Other threads may notify this task to return early by writing to 1646 // Other threads may notify this task to return early by writing to
2010 // device_poll_interrupt_fd_. 1647 // device_poll_interrupt_fd_.
2011 struct pollfd pollfds[3]; 1648 struct pollfd pollfds[3];
2012 nfds_t nfds; 1649 nfds_t nfds;
2013 int mfc_pollfd = -1; 1650 int mfc_pollfd = -1;
2014 1651
2015 // Add device_poll_interrupt_fd_; 1652 // Add device_poll_interrupt_fd_;
2016 pollfds[0].fd = device_poll_interrupt_fd_; 1653 pollfds[0].fd = device_poll_interrupt_fd_;
2017 pollfds[0].events = POLLIN | POLLERR; 1654 pollfds[0].events = POLLIN | POLLERR;
2018 nfds = 1; 1655 nfds = 1;
2019 1656
2020 if (poll_fds & kPollMfc) { 1657 if (poll_fds & kPollMfc) {
2021 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set"; 1658 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set";
2022 pollfds[nfds].fd = mfc_fd_; 1659 pollfds[nfds].fd = mfc_fd_;
2023 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI; 1660 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI;
2024 mfc_pollfd = nfds; 1661 mfc_pollfd = nfds;
2025 nfds++; 1662 nfds++;
2026 } 1663 }
2027 // Add GSC fd, if we should poll on it.
2028 // GSC has to wait until both input and output buffers are queued.
2029 if (poll_fds & kPollGsc) {
2030 DVLOG(3) << "DevicePollTask(): adding GSC to poll() set";
2031 pollfds[nfds].fd = gsc_fd_;
2032 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR;
2033 nfds++;
2034 }
2035 1664
2036 // Poll it! 1665 // Poll it!
2037 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) { 1666 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) {
2038 DPLOG(ERROR) << "DevicePollTask(): poll() failed"; 1667 DPLOG(ERROR) << "DevicePollTask(): poll() failed";
2039 NOTIFY_ERROR(PLATFORM_FAILURE); 1668 NOTIFY_ERROR(PLATFORM_FAILURE);
2040 return; 1669 return;
2041 } 1670 }
2042 1671
2043 bool mfc_event_pending = (mfc_pollfd != -1 && 1672 bool mfc_event_pending = (mfc_pollfd != -1 &&
2044 pollfds[mfc_pollfd].revents & POLLPRI); 1673 pollfds[mfc_pollfd].revents & POLLPRI);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 1730
2102 return true; 1731 return true;
2103 } 1732 }
2104 1733
2105 bool ExynosVideoDecodeAccelerator::CreateBuffersForFormat( 1734 bool ExynosVideoDecodeAccelerator::CreateBuffersForFormat(
2106 const struct v4l2_format& format) { 1735 const struct v4l2_format& format) {
2107 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1736 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2108 CHECK_EQ(format.fmt.pix_mp.num_planes, 2); 1737 CHECK_EQ(format.fmt.pix_mp.num_planes, 2);
2109 frame_buffer_size_.SetSize( 1738 frame_buffer_size_.SetSize(
2110 format.fmt.pix_mp.width, format.fmt.pix_mp.height); 1739 format.fmt.pix_mp.width, format.fmt.pix_mp.height);
2111 mfc_output_buffer_size_[0] = format.fmt.pix_mp.plane_fmt[0].sizeimage;
2112 mfc_output_buffer_size_[1] = format.fmt.pix_mp.plane_fmt[1].sizeimage;
2113 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat; 1740 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat;
2114 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12MT_16X16); 1741 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12M);
2115 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " 1742 DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
2116 << frame_buffer_size_.ToString(); 1743 << frame_buffer_size_.ToString();
2117 1744
2118 if (!CreateMfcOutputBuffers() || !CreateGscInputBuffers() || 1745 if (!CreateMfcOutputBuffers())
2119 !CreateGscOutputBuffers())
2120 return false; 1746 return false;
2121 1747
2122 return true; 1748 return true;
2123 } 1749 }
2124 1750
2125 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() { 1751 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() {
2126 DVLOG(3) << "CreateMfcInputBuffers()"; 1752 DVLOG(3) << "CreateMfcInputBuffers()";
2127 // We always run this as we prepare to initialize. 1753 // We always run this as we prepare to initialize.
2128 DCHECK_EQ(decoder_state_, kUninitialized); 1754 DCHECK_EQ(decoder_state_, kUninitialized);
2129 DCHECK(!mfc_input_streamon_); 1755 DCHECK(!mfc_input_streamon_);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 // Output format setup in Initialize(). 1826 // Output format setup in Initialize().
2201 1827
2202 // Allocate the output buffers. 1828 // Allocate the output buffers.
2203 struct v4l2_requestbuffers reqbufs; 1829 struct v4l2_requestbuffers reqbufs;
2204 memset(&reqbufs, 0, sizeof(reqbufs)); 1830 memset(&reqbufs, 0, sizeof(reqbufs));
2205 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount; 1831 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount;
2206 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1832 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2207 reqbufs.memory = V4L2_MEMORY_MMAP; 1833 reqbufs.memory = V4L2_MEMORY_MMAP;
2208 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs); 1834 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs);
2209 1835
2210 // Fill our free-buffers list, and create DMABUFs from them. 1836 // Create DMABUFs from output buffers.
2211 mfc_output_buffer_map_.resize(reqbufs.count); 1837 mfc_output_buffer_map_.resize(reqbufs.count);
2212 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { 1838 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
2213 mfc_free_output_buffers_.push_back(i); 1839 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
2214 1840 for (size_t j = 0; j < arraysize(output_record.fds); ++j) {
2215 // Query for the MEMORY_MMAP pointer. 1841 // Export the DMABUF fd so we can export it as a texture.
2216 struct v4l2_plane planes[2]; 1842 struct v4l2_exportbuffer expbuf;
2217 struct v4l2_buffer buffer; 1843 memset(&expbuf, 0, sizeof(expbuf));
2218 memset(&buffer, 0, sizeof(buffer)); 1844 expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2219 memset(planes, 0, sizeof(planes)); 1845 expbuf.index = i;
2220 buffer.index = i; 1846 expbuf.plane = j;
2221 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1847 expbuf.flags = O_CLOEXEC;
2222 buffer.memory = V4L2_MEMORY_MMAP; 1848 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_EXPBUF, &expbuf);
2223 buffer.m.planes = planes; 1849 output_record.fds[j] = expbuf.fd;
2224 buffer.length = 2;
2225 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYBUF, &buffer);
2226
2227 // Get their user memory for GSC input.
2228 for (int j = 0; j < 2; ++j) {
2229 void* address = mmap(NULL, buffer.m.planes[j].length,
2230 PROT_READ | PROT_WRITE, MAP_SHARED, mfc_fd_,
2231 buffer.m.planes[j].m.mem_offset);
2232 if (address == MAP_FAILED) {
2233 DPLOG(ERROR) << "CreateMfcInputBuffers(): mmap() failed";
2234 return false;
2235 }
2236 mfc_output_buffer_map_[i].address[j] = address;
2237 mfc_output_buffer_map_[i].length[j] = buffer.m.planes[j].length;
2238 } 1850 }
2239 } 1851 }
2240 1852
2241 return true; 1853 DVLOG(3) << "CreateMfcOutputBuffers(): ProvidePictureBuffers(): "
2242 } 1854 << "buffer_count=" << mfc_output_buffer_map_.size()
2243 1855 << ", width=" << frame_buffer_size_.width()
2244 bool ExynosVideoDecodeAccelerator::CreateGscInputBuffers() { 1856 << ", height=" << frame_buffer_size_.height();
2245 DVLOG(3) << "CreateGscInputBuffers()"; 1857 child_message_loop_proxy_->PostTask(FROM_HERE,
2246 DCHECK(decoder_state_ == kInitialized || 1858 base::Bind(&Client::ProvidePictureBuffers,
2247 decoder_state_ == kChangingResolution); 1859 client_,
2248 DCHECK(!gsc_input_streamon_); 1860 mfc_output_buffer_map_.size(),
2249 DCHECK(gsc_input_buffer_map_.empty()); 1861 frame_buffer_size_,
2250 1862 GL_TEXTURE_EXTERNAL_OES));
2251 struct v4l2_format format;
2252 memset(&format, 0, sizeof(format));
2253 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2254 format.fmt.pix_mp.width = frame_buffer_size_.width();
2255 format.fmt.pix_mp.height = frame_buffer_size_.height();
2256 format.fmt.pix_mp.pixelformat = mfc_output_buffer_pixelformat_;
2257 format.fmt.pix_mp.plane_fmt[0].sizeimage = mfc_output_buffer_size_[0];
2258 format.fmt.pix_mp.plane_fmt[1].sizeimage = mfc_output_buffer_size_[1];
2259 // NV12MT_16X16 is a tiled format for which bytesperline doesn't make too much
2260 // sense. Convention seems to be to assume 8bpp for these tiled formats.
2261 format.fmt.pix_mp.plane_fmt[0].bytesperline = frame_buffer_size_.width();
2262 format.fmt.pix_mp.plane_fmt[1].bytesperline = frame_buffer_size_.width();
2263 format.fmt.pix_mp.num_planes = 2;
2264 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_FMT, &format);
2265
2266 struct v4l2_control control;
2267 memset(&control, 0, sizeof(control));
2268 control.id = V4L2_CID_ROTATE;
2269 control.value = 0;
2270 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
2271
2272 memset(&control, 0, sizeof(control));
2273 control.id = V4L2_CID_HFLIP;
2274 control.value = 0;
2275 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
2276
2277 memset(&control, 0, sizeof(control));
2278 control.id = V4L2_CID_VFLIP;
2279 control.value = 0;
2280 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
2281
2282 memset(&control, 0, sizeof(control));
2283 control.id = V4L2_CID_GLOBAL_ALPHA;
2284 control.value = 255;
2285 if (HANDLE_EINTR(ioctl(gsc_fd_, VIDIOC_S_CTRL, &control)) != 0) {
2286 memset(&control, 0, sizeof(control));
2287 control.id = V4L2_CID_ALPHA_COMPONENT;
2288 control.value = 255;
2289 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
2290 }
2291
2292 struct v4l2_requestbuffers reqbufs;
2293 memset(&reqbufs, 0, sizeof(reqbufs));
2294 reqbufs.count = kGscInputBufferCount;
2295 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2296 reqbufs.memory = V4L2_MEMORY_USERPTR;
2297 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_REQBUFS, &reqbufs);
2298
2299 gsc_input_buffer_map_.resize(reqbufs.count);
2300 for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) {
2301 gsc_free_input_buffers_.push_back(i);
2302 gsc_input_buffer_map_[i].mfc_output = -1;
2303 }
2304 1863
2305 return true; 1864 return true;
2306 } 1865 }
2307
2308 bool ExynosVideoDecodeAccelerator::CreateGscOutputBuffers() {
2309 DVLOG(3) << "CreateGscOutputBuffers()";
2310 DCHECK(decoder_state_ == kInitialized ||
2311 decoder_state_ == kChangingResolution);
2312 DCHECK(!gsc_output_streamon_);
2313 DCHECK(gsc_output_buffer_map_.empty());
2314
2315 // GSC outputs into the EGLImages we create from the textures we are
2316 // assigned. Assume RGBA8888 format.
2317 struct v4l2_format format;
2318 memset(&format, 0, sizeof(format));
2319 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2320 format.fmt.pix_mp.width = frame_buffer_size_.width();
2321 format.fmt.pix_mp.height = frame_buffer_size_.height();
2322 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_RGB32;
2323 format.fmt.pix_mp.plane_fmt[0].sizeimage =
2324 frame_buffer_size_.width() * frame_buffer_size_.height() * 4;
2325 format.fmt.pix_mp.plane_fmt[0].bytesperline = frame_buffer_size_.width() * 4;
2326 format.fmt.pix_mp.num_planes = 1;
2327 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_FMT, &format);
2328
2329 struct v4l2_requestbuffers reqbufs;
2330 memset(&reqbufs, 0, sizeof(reqbufs));
2331 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount;
2332 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2333 reqbufs.memory = V4L2_MEMORY_DMABUF;
2334 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_REQBUFS, &reqbufs);
2335
2336 // We don't actually fill in the freelist or the map here. That happens once
2337 // we have actual usable buffers, after AssignPictureBuffers();
2338 gsc_output_buffer_map_.resize(reqbufs.count);
2339
2340 DVLOG(3) << "CreateGscOutputBuffers(): ProvidePictureBuffers(): "
2341 << "buffer_count=" << gsc_output_buffer_map_.size()
2342 << ", width=" << frame_buffer_size_.width()
2343 << ", height=" << frame_buffer_size_.height();
2344 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
2345 &Client::ProvidePictureBuffers, client_, gsc_output_buffer_map_.size(),
2346 gfx::Size(frame_buffer_size_.width(), frame_buffer_size_.height()),
2347 GL_TEXTURE_2D));
2348
2349 return true;
2350 }
2351 1866
2352 void ExynosVideoDecodeAccelerator::DestroyMfcInputBuffers() { 1867 void ExynosVideoDecodeAccelerator::DestroyMfcInputBuffers() {
2353 DVLOG(3) << "DestroyMfcInputBuffers()"; 1868 DVLOG(3) << "DestroyMfcInputBuffers()";
2354 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1869 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2355 DCHECK(!mfc_input_streamon_); 1870 DCHECK(!mfc_input_streamon_);
2356 1871
2357 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { 1872 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
2358 if (mfc_input_buffer_map_[i].address != NULL) { 1873 if (mfc_input_buffer_map_[i].address != NULL) {
2359 munmap(mfc_input_buffer_map_[i].address, 1874 munmap(mfc_input_buffer_map_[i].address,
2360 mfc_input_buffer_map_[i].length); 1875 mfc_input_buffer_map_[i].length);
(...skipping 10 matching lines...) Expand all
2371 1886
2372 mfc_input_buffer_map_.clear(); 1887 mfc_input_buffer_map_.clear();
2373 mfc_free_input_buffers_.clear(); 1888 mfc_free_input_buffers_.clear();
2374 } 1889 }
2375 1890
2376 void ExynosVideoDecodeAccelerator::DestroyMfcOutputBuffers() { 1891 void ExynosVideoDecodeAccelerator::DestroyMfcOutputBuffers() {
2377 DVLOG(3) << "DestroyMfcOutputBuffers()"; 1892 DVLOG(3) << "DestroyMfcOutputBuffers()";
2378 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1893 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2379 DCHECK(!mfc_output_streamon_); 1894 DCHECK(!mfc_output_streamon_);
2380 1895
2381 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { 1896 if (mfc_output_buffer_map_.size() != 0) {
2382 if (mfc_output_buffer_map_[i].address[0] != NULL) 1897 if (!make_context_current_.Run()) {
2383 munmap(mfc_output_buffer_map_[i].address[0], 1898 DLOG(ERROR) << "DestroyMfcOutputBuffers(): "
2384 mfc_output_buffer_map_[i].length[0]); 1899 << "could not make context current";
2385 if (mfc_output_buffer_map_[i].address[1] != NULL) 1900 } else {
2386 munmap(mfc_output_buffer_map_[i].address[1], 1901 size_t i = 0;
2387 mfc_output_buffer_map_[i].length[1]); 1902 do {
1903 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
1904 for (size_t j = 0; j < arraysize(output_record.fds); ++j) {
1905 if (output_record.fds[j] != -1)
1906 HANDLE_EINTR(close(output_record.fds[j]));
1907 if (output_record.egl_image != EGL_NO_IMAGE_KHR)
1908 eglDestroyImageKHR(egl_display_, output_record.egl_image);
1909 if (output_record.egl_sync != EGL_NO_SYNC_KHR)
1910 eglDestroySyncKHR(egl_display_, output_record.egl_sync);
1911 }
1912 DVLOG(1) << "DestroyMfcOutputBuffers(): dismissing PictureBuffer id="
1913 << output_record.picture_id;
1914 child_message_loop_proxy_->PostTask(
1915 FROM_HERE,
1916 base::Bind(&Client::DismissPictureBuffer,
1917 client_,
1918 output_record.picture_id));
1919 i++;
1920 } while (i < mfc_output_buffer_map_.size());
1921 }
2388 } 1922 }
2389 1923
2390 struct v4l2_requestbuffers reqbufs; 1924 struct v4l2_requestbuffers reqbufs;
2391 memset(&reqbufs, 0, sizeof(reqbufs)); 1925 memset(&reqbufs, 0, sizeof(reqbufs));
2392 reqbufs.count = 0; 1926 reqbufs.count = 0;
2393 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1927 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2394 reqbufs.memory = V4L2_MEMORY_MMAP; 1928 reqbufs.memory = V4L2_MEMORY_MMAP;
2395 if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) 1929 if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
2396 DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS"; 1930 DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS";
2397 1931
2398 mfc_output_buffer_map_.clear(); 1932 mfc_output_buffer_map_.clear();
2399 mfc_free_output_buffers_.clear(); 1933 while (!mfc_free_output_buffers_.empty())
2400 } 1934 mfc_free_output_buffers_.pop();
2401
2402 void ExynosVideoDecodeAccelerator::DestroyGscInputBuffers() {
2403 DVLOG(3) << "DestroyGscInputBuffers()";
2404 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2405 DCHECK(!gsc_input_streamon_);
2406
2407 struct v4l2_requestbuffers reqbufs;
2408 memset(&reqbufs, 0, sizeof(reqbufs));
2409 reqbufs.count = 0;
2410 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2411 reqbufs.memory = V4L2_MEMORY_DMABUF;
2412 if (ioctl(gsc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
2413 DPLOG(ERROR) << "DestroyGscInputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
2414
2415 gsc_input_buffer_map_.clear();
2416 gsc_free_input_buffers_.clear();
2417 }
2418
2419 void ExynosVideoDecodeAccelerator::DestroyGscOutputBuffers() {
2420 DVLOG(3) << "DestroyGscOutputBuffers()";
2421 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2422 DCHECK(!gsc_output_streamon_);
2423
2424 if (gsc_output_buffer_map_.size() != 0) {
2425 if (!make_context_current_.Run())
2426 DLOG(ERROR) << "DestroyGscOutputBuffers(): "
2427 << "could not make context current";
2428
2429 size_t i = 0;
2430 do {
2431 GscOutputRecord& output_record = gsc_output_buffer_map_[i];
2432 if (output_record.fd != -1)
2433 HANDLE_EINTR(close(output_record.fd));
2434 if (output_record.egl_image != EGL_NO_IMAGE_KHR)
2435 eglDestroyImageKHR(egl_display_, output_record.egl_image);
2436 if (output_record.egl_sync != EGL_NO_SYNC_KHR)
2437 eglDestroySyncKHR(egl_display_, output_record.egl_sync);
2438 if (client_) {
2439 DVLOG(1) << "DestroyGscOutputBuffers(): "
2440 << "dismissing PictureBuffer id=" << output_record.picture_id;
2441 client_->DismissPictureBuffer(output_record.picture_id);
2442 }
2443 ++i;
2444 } while (i < gsc_output_buffer_map_.size());
2445 }
2446
2447 struct v4l2_requestbuffers reqbufs;
2448 memset(&reqbufs, 0, sizeof(reqbufs));
2449 reqbufs.count = 0;
2450 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2451 reqbufs.memory = V4L2_MEMORY_DMABUF;
2452 if (ioctl(gsc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
2453 DPLOG(ERROR) << "DestroyGscOutputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
2454
2455 gsc_output_buffer_map_.clear();
2456 gsc_free_output_buffers_.clear();
2457 } 1935 }
2458 1936
2459 void ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers() { 1937 void ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
2460 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1938 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2461 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; 1939 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
2462 1940
2463 DestroyGscInputBuffers();
2464 DestroyGscOutputBuffers();
2465 DestroyMfcOutputBuffers(); 1941 DestroyMfcOutputBuffers();
2466 1942
2467 // Finish resolution change on decoder thread. 1943 // Finish resolution change on decoder thread.
2468 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1944 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
2469 &ExynosVideoDecodeAccelerator::FinishResolutionChange, 1945 &ExynosVideoDecodeAccelerator::FinishResolutionChange,
2470 base::Unretained(this))); 1946 base::Unretained(this)));
2471 } 1947 }
2472 1948
2473 void ExynosVideoDecodeAccelerator::SendPictureReady() { 1949 void ExynosVideoDecodeAccelerator::SendPictureReady() {
1950 DVLOG(3) << "SendPictureReady()";
2474 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1951 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2475 bool resetting_or_flushing = 1952 bool resetting_or_flushing =
2476 (decoder_state_ == kResetting || decoder_flushing_); 1953 (decoder_state_ == kResetting || decoder_flushing_);
2477 while (pending_picture_ready_.size() > 0) { 1954 while (pending_picture_ready_.size() > 0) {
2478 bool cleared = pending_picture_ready_.front().cleared; 1955 bool cleared = pending_picture_ready_.front().cleared;
2479 const media::Picture& picture = pending_picture_ready_.front().picture; 1956 const media::Picture& picture = pending_picture_ready_.front().picture;
2480 if (cleared && picture_clearing_count_ == 0) { 1957 if (cleared && picture_clearing_count_ == 0) {
2481 // This picture is cleared. Post it to IO thread to reduce latency. This 1958 // This picture is cleared. Post it to IO thread to reduce latency. This
2482 // should be the case after all pictures are cleared at the beginning. 1959 // should be the case after all pictures are cleared at the beginning.
2483 io_message_loop_proxy_->PostTask( 1960 io_message_loop_proxy_->PostTask(
(...skipping 29 matching lines...) Expand all
2513 1990
2514 void ExynosVideoDecodeAccelerator::PictureCleared() { 1991 void ExynosVideoDecodeAccelerator::PictureCleared() {
2515 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; 1992 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_;
2516 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1993 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2517 DCHECK_GT(picture_clearing_count_, 0); 1994 DCHECK_GT(picture_clearing_count_, 0);
2518 picture_clearing_count_--; 1995 picture_clearing_count_--;
2519 SendPictureReady(); 1996 SendPictureReady();
2520 } 1997 }
2521 1998
2522 } // namespace content 1999 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698