- add sources.
[platform/framework/web/crosswalk.git] / src / content / common / gpu / media / exynos_video_decode_accelerator.cc
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
3 // found in the LICENSE file.
4
5 #include <dlfcn.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <linux/videodev2.h>
9 #include <poll.h>
10 #include <sys/eventfd.h>
11 #include <sys/ioctl.h>
12 #include <sys/mman.h>
13
14 #include "base/bind.h"
15 #include "base/debug/trace_event.h"
16 #include "base/memory/shared_memory.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/message_loop/message_loop_proxy.h"
19 #include "base/posix/eintr_wrapper.h"
20 #include "content/common/gpu/media/exynos_video_decode_accelerator.h"
21 #include "content/common/gpu/media/h264_parser.h"
22 #include "ui/gl/scoped_binders.h"
23
24 namespace content {
25
26 #define NOTIFY_ERROR(x)                                               \
27   do {                                                                \
28     SetDecoderState(kError);                                          \
29     DLOG(ERROR) << "calling NotifyError(): " << x;                    \
30     NotifyError(x);                                                   \
31   } while (0)
32
33 #define IOCTL_OR_ERROR_RETURN(fd, type, arg)                          \
34   do {                                                                \
35     if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) {                    \
36       DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type;    \
37       NOTIFY_ERROR(PLATFORM_FAILURE);                                 \
38       return;                                                         \
39     }                                                                 \
40   } while (0)
41
42 #define IOCTL_OR_ERROR_RETURN_FALSE(fd, type, arg)                    \
43   do {                                                                \
44     if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) {                    \
45       DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type;    \
46       NOTIFY_ERROR(PLATFORM_FAILURE);                                 \
47       return false;                                                   \
48     }                                                                 \
49   } while (0)
50
51 namespace {
52
53 // TODO(posciak): remove once we update linux-headers.
54 #ifndef V4L2_EVENT_RESOLUTION_CHANGE
55 #define V4L2_EVENT_RESOLUTION_CHANGE 5
56 #endif
57
58 const char kExynosMfcDevice[] = "/dev/mfc-dec";
59 const char kExynosGscDevice[] = "/dev/gsc1";
60 const char kMaliDriver[] = "libmali.so";
61
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
69
70 struct ExynosVideoDecodeAccelerator::BitstreamBufferRef {
71   BitstreamBufferRef(
72       base::WeakPtr<Client>& client,
73       scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy,
74       base::SharedMemory* shm,
75       size_t size,
76       int32 input_id);
77   ~BitstreamBufferRef();
78   const base::WeakPtr<Client> client;
79   const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy;
80   const scoped_ptr<base::SharedMemory> shm;
81   const size_t size;
82   off_t bytes_used;
83   const int32 input_id;
84 };
85
86 struct ExynosVideoDecodeAccelerator::PictureBufferArrayRef {
87   PictureBufferArrayRef(EGLDisplay egl_display, size_t count);
88   ~PictureBufferArrayRef();
89
90   struct PictureBufferRef {
91     EGLImageKHR egl_image;
92     int egl_image_fd;
93     int32 client_id;
94   };
95
96   EGLDisplay const egl_display;
97   std::vector<PictureBufferRef> picture_buffers;
98 };
99
100 struct ExynosVideoDecodeAccelerator::EGLSyncKHRRef {
101   EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync);
102   ~EGLSyncKHRRef();
103   EGLDisplay const egl_display;
104   EGLSyncKHR egl_sync;
105 };
106
107 struct ExynosVideoDecodeAccelerator::PictureRecord {
108   PictureRecord(bool cleared, const media::Picture& picture);
109   ~PictureRecord();
110   bool cleared;  // Whether the texture is cleared and safe to render from.
111   media::Picture picture;  // The decoded picture.
112 };
113
114 ExynosVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef(
115     base::WeakPtr<Client>& client,
116     scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy,
117     base::SharedMemory* shm, size_t size, int32 input_id)
118     : client(client),
119       client_message_loop_proxy(client_message_loop_proxy),
120       shm(shm),
121       size(size),
122       bytes_used(0),
123       input_id(input_id) {
124 }
125
126 ExynosVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() {
127   if (input_id >= 0) {
128     client_message_loop_proxy->PostTask(FROM_HERE, base::Bind(
129         &Client::NotifyEndOfBitstreamBuffer, client, input_id));
130   }
131 }
132
133 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef(
134     EGLDisplay egl_display, size_t count)
135     : egl_display(egl_display),
136       picture_buffers(count) {
137   for (size_t i = 0; i < picture_buffers.size(); ++i) {
138     PictureBufferRef& buffer = picture_buffers[i];
139     buffer.egl_image = EGL_NO_IMAGE_KHR;
140     buffer.egl_image_fd = -1;
141     buffer.client_id = -1;
142   }
143 }
144
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(
156     EGLDisplay egl_display, EGLSyncKHR egl_sync)
157     : egl_display(egl_display),
158       egl_sync(egl_sync) {
159 }
160
161 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() {
162   if (egl_sync != EGL_NO_SYNC_KHR)
163     eglDestroySyncKHR(egl_display, egl_sync);
164 }
165
166 ExynosVideoDecodeAccelerator::MfcInputRecord::MfcInputRecord()
167     : at_device(false),
168       address(NULL),
169       length(0),
170       bytes_used(0),
171       input_id(-1) {
172 }
173
174 ExynosVideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() {
175 }
176
177 ExynosVideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord()
178     : 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),
202       fd(-1),
203       egl_image(EGL_NO_IMAGE_KHR),
204       egl_sync(EGL_NO_SYNC_KHR),
205       picture_id(-1),
206       cleared(false) {}
207
208 ExynosVideoDecodeAccelerator::GscOutputRecord::~GscOutputRecord() {
209 }
210
211 ExynosVideoDecodeAccelerator::PictureRecord::PictureRecord(
212     bool cleared,
213     const media::Picture& picture)
214     : cleared(cleared), picture(picture) {}
215
216 ExynosVideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
217
218 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator(
219     EGLDisplay egl_display,
220     EGLContext egl_context,
221     Client* client,
222     const base::WeakPtr<Client>& io_client,
223     const base::Callback<bool(void)>& make_context_current,
224     const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy)
225     : child_message_loop_proxy_(base::MessageLoopProxy::current()),
226       io_message_loop_proxy_(io_message_loop_proxy),
227       weak_this_(base::AsWeakPtr(this)),
228       client_ptr_factory_(client),
229       client_(client_ptr_factory_.GetWeakPtr()),
230       io_client_(io_client),
231       decoder_thread_("ExynosDecoderThread"),
232       decoder_state_(kUninitialized),
233       decoder_delay_bitstream_buffer_id_(-1),
234       decoder_current_input_buffer_(-1),
235       decoder_decode_buffer_tasks_scheduled_(0),
236       decoder_frames_at_client_(0),
237       decoder_flushing_(false),
238       resolution_change_pending_(false),
239       resolution_change_reset_pending_(false),
240       decoder_partial_frame_pending_(false),
241       mfc_fd_(-1),
242       mfc_input_streamon_(false),
243       mfc_input_buffer_queued_count_(0),
244       mfc_output_streamon_(false),
245       mfc_output_buffer_queued_count_(0),
246       mfc_output_buffer_pixelformat_(0),
247       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),
254       device_poll_thread_("ExynosDevicePollThread"),
255       device_poll_interrupt_fd_(-1),
256       make_context_current_(make_context_current),
257       egl_display_(egl_display),
258       egl_context_(egl_context),
259       video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {}
260
261 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() {
262   DCHECK(!decoder_thread_.IsRunning());
263   DCHECK(!device_poll_thread_.IsRunning());
264
265   if (device_poll_interrupt_fd_ != -1) {
266     HANDLE_EINTR(close(device_poll_interrupt_fd_));
267     device_poll_interrupt_fd_ = -1;
268   }
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) {
276     DestroyMfcInputBuffers();
277     DestroyMfcOutputBuffers();
278     HANDLE_EINTR(close(mfc_fd_));
279     mfc_fd_ = -1;
280   }
281
282   // These maps have members that should be manually destroyed, e.g. file
283   // descriptors, mmap() segments, etc.
284   DCHECK(mfc_input_buffer_map_.empty());
285   DCHECK(mfc_output_buffer_map_.empty());
286   DCHECK(gsc_input_buffer_map_.empty());
287   DCHECK(gsc_output_buffer_map_.empty());
288 }
289
290 bool ExynosVideoDecodeAccelerator::Initialize(
291     media::VideoCodecProfile profile) {
292   DVLOG(3) << "Initialize()";
293   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
294   DCHECK_EQ(decoder_state_, kUninitialized);
295
296   switch (profile) {
297     case media::H264PROFILE_BASELINE:
298       DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE";
299       break;
300     case media::H264PROFILE_MAIN:
301       DVLOG(2) << "Initialize(): profile H264PROFILE_MAIN";
302       break;
303     case media::H264PROFILE_HIGH:
304       DVLOG(2) << "Initialize(): profile H264PROFILE_HIGH";
305       break;
306     case media::VP8PROFILE_MAIN:
307       DVLOG(2) << "Initialize(): profile VP8PROFILE_MAIN";
308       break;
309     default:
310       DLOG(ERROR) << "Initialize(): unsupported profile=" << profile;
311       return false;
312   };
313   video_profile_ = profile;
314
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) {
323     DLOG(ERROR) << "Initialize(): could not get EGLDisplay";
324     NOTIFY_ERROR(PLATFORM_FAILURE);
325     return false;
326   }
327
328   if (egl_context_ == EGL_NO_CONTEXT) {
329     DLOG(ERROR) << "Initialize(): could not get EGLContext";
330     NOTIFY_ERROR(PLATFORM_FAILURE);
331     return false;
332   }
333
334   // We need the context to be initialized to query extensions.
335   if (!make_context_current_.Run()) {
336     DLOG(ERROR) << "Initialize(): could not make context current";
337     NOTIFY_ERROR(PLATFORM_FAILURE);
338     return false;
339   }
340
341   if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
342     DLOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync";
343     NOTIFY_ERROR(PLATFORM_FAILURE);
344     return false;
345   }
346
347   // Open the video devices.
348   DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice;
349   mfc_fd_ = HANDLE_EINTR(open(kExynosMfcDevice,
350                               O_RDWR | O_NONBLOCK | O_CLOEXEC));
351   if (mfc_fd_ == -1) {
352     DPLOG(ERROR) << "Initialize(): could not open MFC device: "
353                  << kExynosMfcDevice;
354     NOTIFY_ERROR(PLATFORM_FAILURE);
355     return false;
356   }
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
367   // Create the interrupt fd.
368   DCHECK_EQ(device_poll_interrupt_fd_, -1);
369   device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
370   if (device_poll_interrupt_fd_ == -1) {
371     DPLOG(ERROR) << "Initialize(): eventfd() failed";
372     NOTIFY_ERROR(PLATFORM_FAILURE);
373     return false;
374   }
375
376   // Capabilities check.
377   struct v4l2_capability caps;
378   const __u32 kCapsRequired =
379       V4L2_CAP_VIDEO_CAPTURE_MPLANE |
380       V4L2_CAP_VIDEO_OUTPUT_MPLANE |
381       V4L2_CAP_STREAMING;
382   IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYCAP, &caps);
383   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
384     DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
385         ", caps check failed: 0x" << std::hex << caps.capabilities;
386     NOTIFY_ERROR(PLATFORM_FAILURE);
387     return false;
388   }
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
397   if (!CreateMfcInputBuffers())
398     return false;
399
400   // MFC output format has to be setup before streaming starts.
401   struct v4l2_format format;
402   memset(&format, 0, sizeof(format));
403   format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
404   format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
405   IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format);
406
407   // Subscribe to the resolution change event.
408   struct v4l2_event_subscription sub;
409   memset(&sub, 0, sizeof(sub));
410   sub.type = V4L2_EVENT_RESOLUTION_CHANGE;
411   IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub);
412
413   // Initialize format-specific bits.
414   if (video_profile_ >= media::H264PROFILE_MIN &&
415       video_profile_ <= media::H264PROFILE_MAX) {
416     decoder_h264_parser_.reset(new content::H264Parser());
417   }
418
419   if (!decoder_thread_.Start()) {
420     DLOG(ERROR) << "Initialize(): decoder thread failed to start";
421     NOTIFY_ERROR(PLATFORM_FAILURE);
422     return false;
423   }
424
425   SetDecoderState(kInitialized);
426
427   child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
428       &Client::NotifyInitializeDone, client_));
429   return true;
430 }
431
432 void ExynosVideoDecodeAccelerator::Decode(
433     const media::BitstreamBuffer& bitstream_buffer) {
434   DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id()
435            << ", size=" << bitstream_buffer.size();
436   DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
437
438   // DecodeTask() will take care of running a DecodeBufferTask().
439   decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
440       &ExynosVideoDecodeAccelerator::DecodeTask, base::Unretained(this),
441       bitstream_buffer));
442 }
443
444 void ExynosVideoDecodeAccelerator::AssignPictureBuffers(
445     const std::vector<media::PictureBuffer>& buffers) {
446   DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
447   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
448
449   if (buffers.size() != gsc_output_buffer_map_.size()) {
450     DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
451       " buffers. (Got " << buffers.size() << ", requested " <<
452       gsc_output_buffer_map_.size() << ")";
453     NOTIFY_ERROR(INVALID_ARGUMENT);
454     return;
455   }
456
457   if (!make_context_current_.Run()) {
458     DLOG(ERROR) << "AssignPictureBuffers(): could not make context current";
459     NOTIFY_ERROR(PLATFORM_FAILURE);
460     return;
461   }
462
463   scoped_ptr<PictureBufferArrayRef> pic_buffers_ref(
464       new PictureBufferArrayRef(egl_display_, buffers.size()));
465
466   const static EGLint kImageAttrs[] = {
467     EGL_IMAGE_PRESERVED_KHR, 0,
468     EGL_NONE,
469   };
470   Display* x_display = base::MessagePumpForUI::GetDefaultXDisplay();
471   gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_2D, 0);
472   for (size_t i = 0; i < pic_buffers_ref->picture_buffers.size(); ++i) {
473     DCHECK(buffers[i].size() == frame_buffer_size_);
474     PictureBufferArrayRef::PictureBufferRef& buffer =
475         pic_buffers_ref->picture_buffers[i];
476     // Create the X pixmap and then create an EGLImageKHR from it, so we can
477     // get dma_buf backing.
478     Pixmap pixmap = XCreatePixmap(x_display,
479                                   RootWindow(x_display, 0),
480                                   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(
490         egl_display_, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
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) {
497       DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR";
498       NOTIFY_ERROR(PLATFORM_FAILURE);
499       return;
500     }
501     buffer.egl_image = egl_image;
502     int fd;
503     if (!mali_egl_image_get_buffer_ext_phandle(buffer.egl_image, NULL, &fd)) {
504       DLOG(ERROR) << "AssignPictureBuffers(): "
505                   << "could not get EGLImageKHR dmabuf fd";
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   }
513   decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
514       &ExynosVideoDecodeAccelerator::AssignPictureBuffersTask,
515       base::Unretained(this), base::Passed(&pic_buffers_ref)));
516 }
517
518 void ExynosVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
519   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.
521   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
522
523   if (!make_context_current_.Run()) {
524     DLOG(ERROR) << "ReusePictureBuffer(): could not make context current";
525     NOTIFY_ERROR(PLATFORM_FAILURE);
526     return;
527   }
528
529   EGLSyncKHR egl_sync =
530       eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
531   if (egl_sync == EGL_NO_SYNC_KHR) {
532     DLOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed";
533     NOTIFY_ERROR(PLATFORM_FAILURE);
534     return;
535   }
536
537   scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef(
538       egl_display_, egl_sync));
539   decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
540       &ExynosVideoDecodeAccelerator::ReusePictureBufferTask,
541       base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref)));
542 }
543
544 void ExynosVideoDecodeAccelerator::Flush() {
545   DVLOG(3) << "Flush()";
546   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
547   decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
548       &ExynosVideoDecodeAccelerator::FlushTask, base::Unretained(this)));
549 }
550
551 void ExynosVideoDecodeAccelerator::Reset() {
552   DVLOG(3) << "Reset()";
553   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
554   decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
555       &ExynosVideoDecodeAccelerator::ResetTask, base::Unretained(this)));
556 }
557
558 void ExynosVideoDecodeAccelerator::Destroy() {
559   DVLOG(3) << "Destroy()";
560   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
561
562   // We're destroying; cancel all callbacks.
563   client_ptr_factory_.InvalidateWeakPtrs();
564
565   // If the decoder thread is running, destroy using posted task.
566   if (decoder_thread_.IsRunning()) {
567     decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
568         &ExynosVideoDecodeAccelerator::DestroyTask, base::Unretained(this)));
569     // DestroyTask() will cause the decoder_thread_ to flush all tasks.
570     decoder_thread_.Stop();
571   } else {
572     // Otherwise, call the destroy task directly.
573     DestroyTask();
574   }
575
576   // Set to kError state just in case.
577   SetDecoderState(kError);
578
579   delete this;
580 }
581
582 bool ExynosVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; }
583
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(
618     const media::BitstreamBuffer& bitstream_buffer) {
619   DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id();
620   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
621   DCHECK_NE(decoder_state_, kUninitialized);
622   TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id",
623                bitstream_buffer.id());
624
625   scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
626       io_client_, io_message_loop_proxy_,
627       new base::SharedMemory(bitstream_buffer.handle(), true),
628       bitstream_buffer.size(), bitstream_buffer.id()));
629   if (!bitstream_record->shm->Map(bitstream_buffer.size())) {
630     DLOG(ERROR) << "Decode(): could not map bitstream_buffer";
631     NOTIFY_ERROR(UNREADABLE_INPUT);
632     return;
633   }
634   DVLOG(3) << "Decode(): mapped to addr=" << bitstream_record->shm->memory();
635
636   if (decoder_state_ == kResetting || decoder_flushing_) {
637     // In the case that we're resetting or flushing, we need to delay decoding
638     // the BitstreamBuffers that come after the Reset() or Flush() call.  When
639     // 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;
641     // thus set up the delay if necessary.
642     if (decoder_delay_bitstream_buffer_id_ == -1)
643       decoder_delay_bitstream_buffer_id_ = bitstream_record->input_id;
644   } else if (decoder_state_ == kError) {
645     DVLOG(2) << "DecodeTask(): early out: kError state";
646     return;
647   }
648
649   decoder_input_queue_.push_back(
650       linked_ptr<BitstreamBufferRef>(bitstream_record.release()));
651   decoder_decode_buffer_tasks_scheduled_++;
652   DecodeBufferTask();
653 }
654
655 void ExynosVideoDecodeAccelerator::DecodeBufferTask() {
656   DVLOG(3) << "DecodeBufferTask()";
657   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
658   DCHECK_NE(decoder_state_, kUninitialized);
659   TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask");
660
661   decoder_decode_buffer_tasks_scheduled_--;
662
663   if (decoder_state_ == kResetting) {
664     DVLOG(2) << "DecodeBufferTask(): early out: kResetting state";
665     return;
666   } else if (decoder_state_ == kError) {
667     DVLOG(2) << "DecodeBufferTask(): early out: kError state";
668     return;
669   } else if (decoder_state_ == kChangingResolution) {
670     DVLOG(2) << "DecodeBufferTask(): early out: resolution change pending";
671     return;
672   }
673
674   if (decoder_current_bitstream_buffer_ == NULL) {
675     if (decoder_input_queue_.empty()) {
676       // We're waiting for a new buffer -- exit without scheduling a new task.
677       return;
678     }
679     linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front();
680     if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) {
681       // We're asked to delay decoding on this and subsequent buffers.
682       return;
683     }
684
685     // Setup to use the next buffer.
686     decoder_current_bitstream_buffer_.reset(buffer_ref.release());
687     decoder_input_queue_.pop_front();
688     DVLOG(3) << "DecodeBufferTask(): reading input_id="
689              << decoder_current_bitstream_buffer_->input_id
690              << ", addr=" << (decoder_current_bitstream_buffer_->shm ?
691                               decoder_current_bitstream_buffer_->shm->memory() :
692                               NULL)
693              << ", size=" << decoder_current_bitstream_buffer_->size;
694   }
695   bool schedule_task = false;
696   const size_t size = decoder_current_bitstream_buffer_->size;
697   size_t decoded_size = 0;
698   if (size == 0) {
699     const int32 input_id = decoder_current_bitstream_buffer_->input_id;
700     if (input_id >= 0) {
701       // This is a buffer queued from the client that has zero size.  Skip.
702       schedule_task = true;
703     } else {
704       // This is a buffer of zero size, queued to flush the pipe.  Flush.
705       DCHECK_EQ(decoder_current_bitstream_buffer_->shm.get(),
706                 static_cast<base::SharedMemory*>(NULL));
707       // Enqueue a buffer guaranteed to be empty.  To do that, we flush the
708       // current input, enqueue no data to the next frame, then flush that down.
709       schedule_task = true;
710       if (decoder_current_input_buffer_ != -1 &&
711           mfc_input_buffer_map_[decoder_current_input_buffer_].input_id !=
712               kFlushBufferId)
713         schedule_task = FlushInputFrame();
714
715       if (schedule_task && AppendToInputFrame(NULL, 0) && FlushInputFrame()) {
716         DVLOG(2) << "DecodeBufferTask(): enqueued flush buffer";
717         decoder_partial_frame_pending_ = false;
718         schedule_task = true;
719       } else {
720         // If we failed to enqueue the empty buffer (due to pipeline
721         // backpressure), don't advance the bitstream buffer queue, and don't
722         // schedule the next task.  This bitstream buffer queue entry will get
723         // reprocessed when the pipeline frees up.
724         schedule_task = false;
725       }
726     }
727   } else {
728     // This is a buffer queued from the client, with actual contents.  Decode.
729     const uint8* const data =
730         reinterpret_cast<const uint8*>(
731             decoder_current_bitstream_buffer_->shm->memory()) +
732         decoder_current_bitstream_buffer_->bytes_used;
733     const size_t data_size =
734         decoder_current_bitstream_buffer_->size -
735         decoder_current_bitstream_buffer_->bytes_used;
736     if (!AdvanceFrameFragment(data, data_size, &decoded_size)) {
737       NOTIFY_ERROR(UNREADABLE_INPUT);
738       return;
739     }
740     // AdvanceFrameFragment should not return a size larger than the buffer
741     // size, even on invalid data.
742     CHECK_LE(decoded_size, data_size);
743
744     switch (decoder_state_) {
745       case kInitialized:
746       case kAfterReset:
747         schedule_task = DecodeBufferInitial(data, decoded_size, &decoded_size);
748         break;
749       case kDecoding:
750         schedule_task = DecodeBufferContinue(data, decoded_size);
751         break;
752       default:
753         NOTIFY_ERROR(ILLEGAL_STATE);
754         return;
755     }
756   }
757   if (decoder_state_ == kError) {
758     // Failed during decode.
759     return;
760   }
761
762   if (schedule_task) {
763     decoder_current_bitstream_buffer_->bytes_used += decoded_size;
764     if (decoder_current_bitstream_buffer_->bytes_used ==
765         decoder_current_bitstream_buffer_->size) {
766       // Our current bitstream buffer is done; return it.
767       int32 input_id = decoder_current_bitstream_buffer_->input_id;
768       DVLOG(3) << "DecodeBufferTask(): finished input_id=" << input_id;
769       // BitstreamBufferRef destructor calls NotifyEndOfBitstreamBuffer().
770       decoder_current_bitstream_buffer_.reset();
771     }
772     ScheduleDecodeBufferTaskIfNeeded();
773   }
774 }
775
776 bool ExynosVideoDecodeAccelerator::AdvanceFrameFragment(
777     const uint8* data,
778     size_t size,
779     size_t* endpos) {
780   if (video_profile_ >= media::H264PROFILE_MIN &&
781       video_profile_ <= media::H264PROFILE_MAX) {
782     // For H264, we need to feed HW one frame at a time.  This is going to take
783     // some parsing of our input stream.
784     decoder_h264_parser_->SetStream(data, size);
785     content::H264NALU nalu;
786     content::H264Parser::Result result;
787     *endpos = 0;
788
789     // Keep on peeking the next NALs while they don't indicate a frame
790     // boundary.
791     for (;;) {
792       bool end_of_frame = false;
793       result = decoder_h264_parser_->AdvanceToNextNALU(&nalu);
794       if (result == content::H264Parser::kInvalidStream ||
795           result == content::H264Parser::kUnsupportedStream)
796         return false;
797       if (result == content::H264Parser::kEOStream) {
798         // We've reached the end of the buffer before finding a frame boundary.
799         decoder_partial_frame_pending_ = true;
800         return true;
801       }
802       switch (nalu.nal_unit_type) {
803         case content::H264NALU::kNonIDRSlice:
804         case content::H264NALU::kIDRSlice:
805           if (nalu.size < 1)
806             return false;
807           // For these two, if the "first_mb_in_slice" field is zero, start a
808           // new frame and return.  This field is Exp-Golomb coded starting on
809           // the eighth data bit of the NAL; a zero value is encoded with a
810           // leading '1' bit in the byte, which we can detect as the byte being
811           // (unsigned) greater than or equal to 0x80.
812           if (nalu.data[1] >= 0x80) {
813             end_of_frame = true;
814             break;
815           }
816           break;
817         case content::H264NALU::kSPS:
818         case content::H264NALU::kPPS:
819         case content::H264NALU::kEOSeq:
820         case content::H264NALU::kEOStream:
821           // These unconditionally signal a frame boundary.
822           end_of_frame = true;
823           break;
824         default:
825           // For all others, keep going.
826           break;
827       }
828       if (end_of_frame) {
829         if (!decoder_partial_frame_pending_ && *endpos == 0) {
830           // The frame was previously restarted, and we haven't filled the
831           // current frame with any contents yet.  Start the new frame here and
832           // continue parsing NALs.
833         } else {
834           // The frame wasn't previously restarted and/or we have contents for
835           // the current frame; signal the start of a new frame here: we don't
836           // have a partial frame anymore.
837           decoder_partial_frame_pending_ = false;
838           return true;
839         }
840       }
841       *endpos = (nalu.data + nalu.size) - data;
842     }
843     NOTREACHED();
844     return false;
845   } else {
846     DCHECK_GE(video_profile_, media::VP8PROFILE_MIN);
847     DCHECK_LE(video_profile_, media::VP8PROFILE_MAX);
848     // For VP8, we can just dump the entire buffer.  No fragmentation needed,
849     // and we never return a partial frame.
850     *endpos = size;
851     decoder_partial_frame_pending_ = false;
852     return true;
853   }
854 }
855
856 void ExynosVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() {
857   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
858
859   // If we're behind on tasks, schedule another one.
860   int buffers_to_decode = decoder_input_queue_.size();
861   if (decoder_current_bitstream_buffer_ != NULL)
862     buffers_to_decode++;
863   if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) {
864     decoder_decode_buffer_tasks_scheduled_++;
865     decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
866         &ExynosVideoDecodeAccelerator::DecodeBufferTask,
867         base::Unretained(this)));
868   }
869 }
870
871 bool ExynosVideoDecodeAccelerator::DecodeBufferInitial(
872     const void* data, size_t size, size_t* endpos) {
873   DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size;
874   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
875   DCHECK_NE(decoder_state_, kUninitialized);
876   DCHECK_NE(decoder_state_, kDecoding);
877   DCHECK(!device_poll_thread_.IsRunning());
878   // Initial decode.  We haven't been able to get output stream format info yet.
879   // Get it, and start decoding.
880
881   // Copy in and send to HW.
882   if (!AppendToInputFrame(data, size))
883     return false;
884
885   // If we only have a partial frame, don't flush and process yet.
886   if (decoder_partial_frame_pending_)
887     return true;
888
889   if (!FlushInputFrame())
890     return false;
891
892   // Recycle buffers.
893   DequeueMfc();
894
895   // Check and see if we have format info yet.
896   struct v4l2_format format;
897   bool again = false;
898   if (!GetFormatInfo(&format, &again))
899     return false;
900
901   if (again) {
902     // Need more stream to decode format, return true and schedule next buffer.
903     *endpos = size;
904     return true;
905   }
906
907   // Run this initialization only on first startup.
908   if (decoder_state_ == kInitialized) {
909     DVLOG(3) << "DecodeBufferInitial(): running initialization";
910     // Success! Setup our parameters.
911     if (!CreateBuffersForFormat(format))
912       return false;
913
914     // MFC expects to process the initial buffer once during stream init to
915     // configure stream parameters, but will not consume the steam data on that
916     // iteration.  Subsequent iterations (including after reset) do not require
917     // the stream init step.
918     *endpos = 0;
919   } else {
920     *endpos = size;
921   }
922
923   // StartDevicePoll will raise the error if there is one.
924   if (!StartDevicePoll())
925     return false;
926
927   decoder_state_ = kDecoding;
928   ScheduleDecodeBufferTaskIfNeeded();
929   return true;
930 }
931
932 bool ExynosVideoDecodeAccelerator::DecodeBufferContinue(
933     const void* data, size_t size) {
934   DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size;
935   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
936   DCHECK_EQ(decoder_state_, kDecoding);
937
938   // Both of these calls will set kError state if they fail.
939   // Only flush the frame if it's complete.
940   return (AppendToInputFrame(data, size) &&
941           (decoder_partial_frame_pending_ || FlushInputFrame()));
942 }
943
944 bool ExynosVideoDecodeAccelerator::AppendToInputFrame(
945     const void* data, size_t size) {
946   DVLOG(3) << "AppendToInputFrame()";
947   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
948   DCHECK_NE(decoder_state_, kUninitialized);
949   DCHECK_NE(decoder_state_, kResetting);
950   DCHECK_NE(decoder_state_, kError);
951   // This routine can handle data == NULL and size == 0, which occurs when
952   // we queue an empty buffer for the purposes of flushing the pipe.
953
954   // Flush if we're too big
955   if (decoder_current_input_buffer_ != -1) {
956     MfcInputRecord& input_record =
957         mfc_input_buffer_map_[decoder_current_input_buffer_];
958     if (input_record.bytes_used + size > input_record.length) {
959       if (!FlushInputFrame())
960         return false;
961       decoder_current_input_buffer_ = -1;
962     }
963   }
964
965   // Try to get an available input buffer
966   if (decoder_current_input_buffer_ == -1) {
967     if (mfc_free_input_buffers_.empty()) {
968       // See if we can get more free buffers from HW
969       DequeueMfc();
970       if (mfc_free_input_buffers_.empty()) {
971         // Nope!
972         DVLOG(2) << "AppendToInputFrame(): stalled for input buffers";
973         return false;
974       }
975     }
976     decoder_current_input_buffer_ = mfc_free_input_buffers_.back();
977     mfc_free_input_buffers_.pop_back();
978     MfcInputRecord& input_record =
979         mfc_input_buffer_map_[decoder_current_input_buffer_];
980     DCHECK_EQ(input_record.bytes_used, 0);
981     DCHECK_EQ(input_record.input_id, -1);
982     DCHECK(decoder_current_bitstream_buffer_ != NULL);
983     input_record.input_id = decoder_current_bitstream_buffer_->input_id;
984   }
985
986   DCHECK(data != NULL || size == 0);
987   if (size == 0) {
988     // If we asked for an empty buffer, return now.  We return only after
989     // getting the next input buffer, since we might actually want an empty
990     // input buffer for flushing purposes.
991     return true;
992   }
993
994   // Copy in to the buffer.
995   MfcInputRecord& input_record =
996       mfc_input_buffer_map_[decoder_current_input_buffer_];
997   if (size > input_record.length - input_record.bytes_used) {
998     LOG(ERROR) << "AppendToInputFrame(): over-size frame, erroring";
999     NOTIFY_ERROR(UNREADABLE_INPUT);
1000     return false;
1001   }
1002   memcpy(
1003       reinterpret_cast<uint8*>(input_record.address) + input_record.bytes_used,
1004       data,
1005       size);
1006   input_record.bytes_used += size;
1007
1008   return true;
1009 }
1010
1011 bool ExynosVideoDecodeAccelerator::FlushInputFrame() {
1012   DVLOG(3) << "FlushInputFrame()";
1013   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1014   DCHECK_NE(decoder_state_, kUninitialized);
1015   DCHECK_NE(decoder_state_, kResetting);
1016   DCHECK_NE(decoder_state_, kError);
1017
1018   if (decoder_current_input_buffer_ == -1)
1019     return true;
1020
1021   MfcInputRecord& input_record =
1022       mfc_input_buffer_map_[decoder_current_input_buffer_];
1023   DCHECK_NE(input_record.input_id, -1);
1024   DCHECK(input_record.input_id != kFlushBufferId ||
1025          input_record.bytes_used == 0);
1026   // * if input_id >= 0, this input buffer was prompted by a bitstream buffer we
1027   //   got from the client.  We can skip it if it is empty.
1028   // * if input_id < 0 (should be kFlushBufferId in this case), this input
1029   //   buffer was prompted by a flush buffer, and should be queued even when
1030   //   empty.
1031   if (input_record.input_id >= 0 && input_record.bytes_used == 0) {
1032     input_record.input_id = -1;
1033     mfc_free_input_buffers_.push_back(decoder_current_input_buffer_);
1034     decoder_current_input_buffer_ = -1;
1035     return true;
1036   }
1037
1038   // Queue it to MFC.
1039   mfc_input_ready_queue_.push_back(decoder_current_input_buffer_);
1040   decoder_current_input_buffer_ = -1;
1041   DVLOG(3) << "FlushInputFrame(): submitting input_id="
1042            << input_record.input_id;
1043   // Kick the MFC once since there's new available input for it.
1044   EnqueueMfc();
1045
1046   return (decoder_state_ != kError);
1047 }
1048
1049 void ExynosVideoDecodeAccelerator::AssignPictureBuffersTask(
1050     scoped_ptr<PictureBufferArrayRef> pic_buffers) {
1051   DVLOG(3) << "AssignPictureBuffersTask()";
1052   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1053   DCHECK_NE(decoder_state_, kUninitialized);
1054   TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask");
1055
1056   // We run AssignPictureBuffersTask even if we're in kResetting.
1057   if (decoder_state_ == kError) {
1058     DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state";
1059     return;
1060   }
1061
1062   DCHECK_EQ(pic_buffers->picture_buffers.size(), gsc_output_buffer_map_.size());
1063   for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i) {
1064     // We should be blank right now.
1065     GscOutputRecord& output_record = gsc_output_buffer_map_[i];
1066     DCHECK_EQ(output_record.fd, -1);
1067     DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR);
1068     DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1069     DCHECK_EQ(output_record.picture_id, -1);
1070     DCHECK_EQ(output_record.cleared, false);
1071     PictureBufferArrayRef::PictureBufferRef& buffer =
1072         pic_buffers->picture_buffers[i];
1073     output_record.fd = buffer.egl_image_fd;
1074     output_record.egl_image = buffer.egl_image;
1075     output_record.picture_id = buffer.client_id;
1076
1077     // Take ownership of the EGLImage and fd.
1078     buffer.egl_image = EGL_NO_IMAGE_KHR;
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
1087   if (decoder_state_ == kChangingResolution)
1088     ResumeAfterResolutionChange();
1089 }
1090
1091 void ExynosVideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) {
1092   DVLOG(3) << "ServiceDeviceTask()";
1093   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1094   DCHECK_NE(decoder_state_, kUninitialized);
1095   DCHECK_NE(decoder_state_, kInitialized);
1096   DCHECK_NE(decoder_state_, kAfterReset);
1097   TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask");
1098
1099   if (decoder_state_ == kResetting) {
1100     DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state";
1101     return;
1102   } else if (decoder_state_ == kError) {
1103     DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
1104     return;
1105   } else if (decoder_state_ == kChangingResolution) {
1106     DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state";
1107     return;
1108   }
1109
1110   if (mfc_event_pending)
1111     DequeueMfcEvents();
1112   DequeueMfc();
1113   DequeueGsc();
1114   EnqueueMfc();
1115   EnqueueGsc();
1116
1117   // Clear the interrupt fd.
1118   if (!ClearDevicePollInterrupt())
1119     return;
1120
1121   unsigned int poll_fds = 0;
1122   // Add MFC fd, if we should poll on it.
1123   // 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)
1125     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
1131   // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
1132   // so either:
1133   // * device_poll_thread_ is running normally
1134   // * 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
1136   //   respectively, and we should have early-outed already.
1137   DCHECK(device_poll_thread_.message_loop());
1138   // Queue the DevicePollTask() now.
1139   device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1140       &ExynosVideoDecodeAccelerator::DevicePollTask,
1141       base::Unretained(this),
1142       poll_fds));
1143
1144   DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC["
1145            << decoder_input_queue_.size() << "->"
1146            << mfc_input_ready_queue_.size() << "] => MFC["
1147            << mfc_free_input_buffers_.size() << "+"
1148            << mfc_input_buffer_queued_count_ << "/"
1149            << mfc_input_buffer_map_.size() << "->"
1150            << mfc_free_output_buffers_.size() << "+"
1151            << mfc_output_buffer_queued_count_ << "/"
1152            << mfc_output_buffer_map_.size() << "] => "
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_ << "]";
1161
1162   ScheduleDecodeBufferTaskIfNeeded();
1163   StartResolutionChangeIfNeeded();
1164 }
1165
1166 void ExynosVideoDecodeAccelerator::EnqueueMfc() {
1167   DVLOG(3) << "EnqueueMfc()";
1168   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1169   DCHECK_NE(decoder_state_, kUninitialized);
1170   TRACE_EVENT0("Video Decoder", "EVDA::EnqueueMfc");
1171
1172   // Drain the pipe of completed decode buffers.
1173   const int old_mfc_inputs_queued = mfc_input_buffer_queued_count_;
1174   while (!mfc_input_ready_queue_.empty()) {
1175     if (!EnqueueMfcInputRecord())
1176       return;
1177   }
1178   if (old_mfc_inputs_queued == 0 && mfc_input_buffer_queued_count_ != 0) {
1179     // We just started up a previously empty queue.
1180     // Queue state changed; signal interrupt.
1181     if (!SetDevicePollInterrupt())
1182       return;
1183     // Start VIDIOC_STREAMON if we haven't yet.
1184     if (!mfc_input_streamon_) {
1185       __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1186       IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type);
1187       mfc_input_streamon_ = true;
1188     }
1189   }
1190
1191   // Enqueue all the MFC outputs we can.
1192   const int old_mfc_outputs_queued = mfc_output_buffer_queued_count_;
1193   while (!mfc_free_output_buffers_.empty()) {
1194     if (!EnqueueMfcOutputRecord())
1195       return;
1196   }
1197   if (old_mfc_outputs_queued == 0 && mfc_output_buffer_queued_count_ != 0) {
1198     // We just started up a previously empty queue.
1199     // Queue state changed; signal interrupt.
1200     if (!SetDevicePollInterrupt())
1201       return;
1202     // Start VIDIOC_STREAMON if we haven't yet.
1203     if (!mfc_output_streamon_) {
1204       __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1205       IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type);
1206       mfc_output_streamon_ = true;
1207     }
1208   }
1209 }
1210
1211 void ExynosVideoDecodeAccelerator::DequeueMfcEvents() {
1212   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1213   DCHECK_EQ(decoder_state_, kDecoding);
1214   DVLOG(3) << "DequeueMfcEvents()";
1215
1216   struct v4l2_event ev;
1217   memset(&ev, 0, sizeof(ev));
1218
1219   while (ioctl(mfc_fd_, VIDIOC_DQEVENT, &ev) == 0) {
1220     if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) {
1221       DVLOG(3) << "DequeueMfcEvents(): got resolution change event.";
1222       DCHECK(!resolution_change_pending_);
1223       resolution_change_pending_ = true;
1224     } else {
1225       DLOG(FATAL) << "DequeueMfcEvents(): got an event (" << ev.type
1226                   << ") we haven't subscribed to.";
1227     }
1228   }
1229 }
1230
1231 void ExynosVideoDecodeAccelerator::DequeueMfc() {
1232   DVLOG(3) << "DequeueMfc()";
1233   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1234   DCHECK_NE(decoder_state_, kUninitialized);
1235   TRACE_EVENT0("Video Decoder", "EVDA::DequeueMfc");
1236
1237   // Dequeue completed MFC input (VIDEO_OUTPUT) buffers, and recycle to the free
1238   // list.
1239   struct v4l2_buffer dqbuf;
1240   struct v4l2_plane planes[2];
1241   while (mfc_input_buffer_queued_count_ > 0) {
1242     DCHECK(mfc_input_streamon_);
1243     memset(&dqbuf, 0, sizeof(dqbuf));
1244     memset(planes, 0, sizeof(planes));
1245     dqbuf.type   = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1246     dqbuf.memory = V4L2_MEMORY_MMAP;
1247     dqbuf.m.planes = planes;
1248     dqbuf.length = 1;
1249     if (ioctl(mfc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) {
1250       if (errno == EAGAIN) {
1251         // EAGAIN if we're just out of buffers to dequeue.
1252         break;
1253       }
1254       DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF";
1255       NOTIFY_ERROR(PLATFORM_FAILURE);
1256       return;
1257     }
1258     MfcInputRecord& input_record = mfc_input_buffer_map_[dqbuf.index];
1259     DCHECK(input_record.at_device);
1260     mfc_free_input_buffers_.push_back(dqbuf.index);
1261     input_record.at_device = false;
1262     input_record.bytes_used = 0;
1263     input_record.input_id = -1;
1264     mfc_input_buffer_queued_count_--;
1265   }
1266
1267   // Dequeue completed MFC output (VIDEO_CAPTURE) buffers, and queue to the
1268   // completed queue.
1269   while (mfc_output_buffer_queued_count_ > 0) {
1270     DCHECK(mfc_output_streamon_);
1271     memset(&dqbuf, 0, sizeof(dqbuf));
1272     memset(planes, 0, sizeof(planes));
1273     dqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1274     dqbuf.memory = V4L2_MEMORY_MMAP;
1275     dqbuf.m.planes = planes;
1276     dqbuf.length = 2;
1277     if (ioctl(mfc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) {
1278       if (errno == EAGAIN) {
1279         // EAGAIN if we're just out of buffers to dequeue.
1280         break;
1281       }
1282       DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF";
1283       NOTIFY_ERROR(PLATFORM_FAILURE);
1284       return;
1285     }
1286     MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index];
1287     DCHECK(output_record.at_device);
1288     output_record.at_device = false;
1289     output_record.bytes_used[0] = dqbuf.m.planes[0].bytesused;
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.
1293       mfc_free_output_buffers_.push_back(dqbuf.index);
1294       output_record.input_id = -1;
1295     } else {
1296       // This is an output buffer with contents to pass down the pipe.
1297       mfc_output_gsc_input_queue_.push_back(dqbuf.index);
1298       output_record.input_id = dqbuf.timestamp.tv_sec;
1299       DCHECK(output_record.input_id >= 0);
1300       DVLOG(3) << "DequeueMfc(): dequeued input_id=" << output_record.input_id;
1301       // We don't count this output buffer dequeued yet, or add it to the free
1302       // list, as it has data GSC needs to process.
1303
1304       // We have new frames in mfc_output_gsc_input_queue_.  Kick the pipe.
1305       SetDevicePollInterrupt();
1306     }
1307     mfc_output_buffer_queued_count_--;
1308   }
1309
1310   NotifyFlushDoneIfNeeded();
1311 }
1312
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() {
1446   DVLOG(3) << "EnqueueMfcInputRecord()";
1447   DCHECK(!mfc_input_ready_queue_.empty());
1448
1449   // Enqueue a MFC input (VIDEO_OUTPUT) buffer.
1450   const int buffer = mfc_input_ready_queue_.back();
1451   MfcInputRecord& input_record = mfc_input_buffer_map_[buffer];
1452   DCHECK(!input_record.at_device);
1453   struct v4l2_buffer qbuf;
1454   struct v4l2_plane qbuf_plane;
1455   memset(&qbuf, 0, sizeof(qbuf));
1456   memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1457   qbuf.index                 = buffer;
1458   qbuf.type                  = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1459   qbuf.timestamp.tv_sec      = input_record.input_id;
1460   qbuf.memory                = V4L2_MEMORY_MMAP;
1461   qbuf.m.planes              = &qbuf_plane;
1462   qbuf.m.planes[0].bytesused = input_record.bytes_used;
1463   qbuf.length                = 1;
1464   IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf);
1465   mfc_input_ready_queue_.pop_back();
1466   input_record.at_device = true;
1467   mfc_input_buffer_queued_count_++;
1468   DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id="
1469            << input_record.input_id;
1470   return true;
1471 }
1472
1473 bool ExynosVideoDecodeAccelerator::EnqueueMfcOutputRecord() {
1474   DVLOG(3) << "EnqueueMfcOutputRecord()";
1475   DCHECK(!mfc_free_output_buffers_.empty());
1476
1477   // Enqueue a MFC output (VIDEO_CAPTURE) buffer.
1478   const int buffer = mfc_free_output_buffers_.back();
1479   MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer];
1480   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);
1549   if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
1550     TRACE_EVENT0(
1551         "Video Decoder",
1552         "EVDA::EnqueueGscOutputRecord: eglClientWaitSyncKHR");
1553     // 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
1555     // buffer that has been in the queue the longest.
1556     eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0,
1557         EGL_FOREVER_KHR);
1558     eglDestroySyncKHR(egl_display_, output_record.egl_sync);
1559     output_record.egl_sync = EGL_NO_SYNC_KHR;
1560   }
1561   struct v4l2_buffer qbuf;
1562   struct v4l2_plane qbuf_plane;
1563   memset(&qbuf, 0, sizeof(qbuf));
1564   memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1565   qbuf.index            = buffer;
1566   qbuf.type             = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1567   qbuf.memory           = V4L2_MEMORY_DMABUF;
1568   qbuf.m.planes         = &qbuf_plane;
1569   qbuf.m.planes[0].m.fd = output_record.fd;
1570   qbuf.length           = 1;
1571   IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QBUF, &qbuf);
1572   gsc_free_output_buffers_.pop_front();
1573   output_record.at_device = true;
1574   gsc_output_buffer_queued_count_++;
1575   return true;
1576 }
1577
1578 void ExynosVideoDecodeAccelerator::ReusePictureBufferTask(
1579     int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) {
1580   DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id="
1581            << picture_buffer_id;
1582   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1583   TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask");
1584
1585   // We run ReusePictureBufferTask even if we're in kResetting.
1586   if (decoder_state_ == kError) {
1587     DVLOG(2) << "ReusePictureBufferTask(): early out: kError state";
1588     return;
1589   }
1590
1591   if (decoder_state_ == kChangingResolution) {
1592     DVLOG(2) << "ReusePictureBufferTask(): early out: kChangingResolution";
1593     return;
1594   }
1595
1596   size_t index;
1597   for (index = 0; index < gsc_output_buffer_map_.size(); ++index)
1598     if (gsc_output_buffer_map_[index].picture_id == picture_buffer_id)
1599       break;
1600
1601   if (index >= gsc_output_buffer_map_.size()) {
1602     DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not found";
1603     NOTIFY_ERROR(INVALID_ARGUMENT);
1604     return;
1605   }
1606
1607   GscOutputRecord& output_record = gsc_output_buffer_map_[index];
1608   if (output_record.at_device || !output_record.at_client) {
1609     DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not reusable";
1610     NOTIFY_ERROR(INVALID_ARGUMENT);
1611     return;
1612   }
1613
1614   DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1615   output_record.at_client = false;
1616   output_record.egl_sync = egl_sync_ref->egl_sync;
1617   gsc_free_output_buffers_.push_back(index);
1618   decoder_frames_at_client_--;
1619   // Take ownership of the EGLSync.
1620   egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR;
1621   // We got a buffer back, so kick the GSC.
1622   EnqueueGsc();
1623 }
1624
1625 void ExynosVideoDecodeAccelerator::FlushTask() {
1626   DVLOG(3) << "FlushTask()";
1627   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1628   TRACE_EVENT0("Video Decoder", "EVDA::FlushTask");
1629
1630   // Flush outstanding buffers.
1631   if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) {
1632     // There's nothing in the pipe, so return done immediately.
1633     DVLOG(3) << "FlushTask(): returning flush";
1634     child_message_loop_proxy_->PostTask(
1635         FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_));
1636     return;
1637   } else if (decoder_state_ == kError) {
1638     DVLOG(2) << "FlushTask(): early out: kError state";
1639     return;
1640   }
1641
1642   // We don't support stacked flushing.
1643   DCHECK(!decoder_flushing_);
1644
1645   // Queue up an empty buffer -- this triggers the flush.
1646   decoder_input_queue_.push_back(linked_ptr<BitstreamBufferRef>(
1647       new BitstreamBufferRef(io_client_, io_message_loop_proxy_, NULL, 0,
1648                              kFlushBufferId)));
1649   decoder_flushing_ = true;
1650   SendPictureReady();  // Send all pending PictureReady.
1651
1652   ScheduleDecodeBufferTaskIfNeeded();
1653 }
1654
1655 void ExynosVideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
1656   if (!decoder_flushing_)
1657     return;
1658
1659   // Pipeline is empty when:
1660   // * Decoder input queue is empty of non-delayed buffers.
1661   // * There is no currently filling input buffer.
1662   // * MFC input holding queue is empty.
1663   // * 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()) {
1667     if (decoder_input_queue_.front()->input_id !=
1668         decoder_delay_bitstream_buffer_id_)
1669       return;
1670   }
1671   if (decoder_current_input_buffer_ != -1)
1672     return;
1673   if ((mfc_input_ready_queue_.size() +
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;
1677
1678   // TODO(posciak): crbug.com/270039. MFC requires a streamoff-streamon
1679   // 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
1681   // (e.g. not from an IDR) if we are flushed.
1682   // 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
1684   // transitioning to next chunk.
1685   // For now, do the streamoff-streamon cycle to satisfy MFC and not freeze when
1686   // doing MSE. This should be harmless otherwise.
1687   if (!StopDevicePoll(false))
1688     return;
1689
1690   if (!StartDevicePoll())
1691     return;
1692
1693   decoder_delay_bitstream_buffer_id_ = -1;
1694   decoder_flushing_ = false;
1695   DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush";
1696   child_message_loop_proxy_->PostTask(
1697       FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_));
1698
1699   // While we were flushing, we early-outed DecodeBufferTask()s.
1700   ScheduleDecodeBufferTaskIfNeeded();
1701 }
1702
1703 void ExynosVideoDecodeAccelerator::ResetTask() {
1704   DVLOG(3) << "ResetTask()";
1705   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1706   TRACE_EVENT0("Video Decoder", "EVDA::ResetTask");
1707
1708   if (decoder_state_ == kError) {
1709     DVLOG(2) << "ResetTask(): early out: kError state";
1710     return;
1711   }
1712
1713   // If we are in the middle of switching resolutions, postpone reset until
1714   // it's done. We don't have to worry about timing of this wrt to decoding,
1715   // because MFC input pipe is already stopped if we are changing resolution.
1716   // We will come back here after we are done with the resolution change.
1717   DCHECK(!resolution_change_reset_pending_);
1718   if (resolution_change_pending_ || decoder_state_ == kChangingResolution) {
1719     resolution_change_reset_pending_ = true;
1720     return;
1721   }
1722
1723   // We stop streaming and clear buffer tracking info (not preserving
1724   // MFC inputs).
1725   // StopDevicePoll() unconditionally does _not_ destroy buffers, however.
1726   if (!StopDevicePoll(false))
1727     return;
1728
1729   DequeueMfcEvents();
1730
1731   resolution_change_pending_ = false;
1732   decoder_current_bitstream_buffer_.reset();
1733   decoder_input_queue_.clear();
1734
1735   decoder_current_input_buffer_ = -1;
1736
1737   // If we were flushing, we'll never return any more BitstreamBuffers or
1738   // PictureBuffers; they have all been dropped and returned by now.
1739   NotifyFlushDoneIfNeeded();
1740
1741   // Mark that we're resetting, then enqueue a ResetDoneTask().  All intervening
1742   // jobs will early-out in the kResetting state.
1743   decoder_state_ = kResetting;
1744   SendPictureReady();  // Send all pending PictureReady.
1745   decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1746       &ExynosVideoDecodeAccelerator::ResetDoneTask, base::Unretained(this)));
1747 }
1748
1749 void ExynosVideoDecodeAccelerator::ResetDoneTask() {
1750   DVLOG(3) << "ResetDoneTask()";
1751   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1752   TRACE_EVENT0("Video Decoder", "EVDA::ResetDoneTask");
1753
1754   if (decoder_state_ == kError) {
1755     DVLOG(2) << "ResetDoneTask(): early out: kError state";
1756     return;
1757   }
1758
1759   // Reset format-specific bits.
1760   if (video_profile_ >= media::H264PROFILE_MIN &&
1761       video_profile_ <= media::H264PROFILE_MAX) {
1762     decoder_h264_parser_.reset(new content::H264Parser());
1763   }
1764
1765   // Jobs drained, we're finished resetting.
1766   DCHECK_EQ(decoder_state_, kResetting);
1767   decoder_state_ = kAfterReset;
1768   decoder_partial_frame_pending_ = false;
1769   decoder_delay_bitstream_buffer_id_ = -1;
1770   child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1771       &Client::NotifyResetDone, client_));
1772
1773   // While we were resetting, we early-outed DecodeBufferTask()s.
1774   ScheduleDecodeBufferTaskIfNeeded();
1775 }
1776
1777 void ExynosVideoDecodeAccelerator::DestroyTask() {
1778   DVLOG(3) << "DestroyTask()";
1779   TRACE_EVENT0("Video Decoder", "EVDA::DestroyTask");
1780
1781   // DestroyTask() should run regardless of decoder_state_.
1782
1783   // Stop streaming and the device_poll_thread_.
1784   StopDevicePoll(false);
1785
1786   decoder_current_bitstream_buffer_.reset();
1787   decoder_current_input_buffer_ = -1;
1788   decoder_decode_buffer_tasks_scheduled_ = 0;
1789   decoder_frames_at_client_ = 0;
1790   decoder_input_queue_.clear();
1791   decoder_flushing_ = false;
1792
1793   // Set our state to kError.  Just in case.
1794   decoder_state_ = kError;
1795 }
1796
1797 bool ExynosVideoDecodeAccelerator::StartDevicePoll() {
1798   DVLOG(3) << "StartDevicePoll()";
1799   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1800   DCHECK(!device_poll_thread_.IsRunning());
1801
1802   // Start up the device poll thread and schedule its first DevicePollTask().
1803   if (!device_poll_thread_.Start()) {
1804     DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
1805     NOTIFY_ERROR(PLATFORM_FAILURE);
1806     return false;
1807   }
1808   device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1809       &ExynosVideoDecodeAccelerator::DevicePollTask,
1810       base::Unretained(this),
1811       0));
1812
1813   return true;
1814 }
1815
1816 bool ExynosVideoDecodeAccelerator::StopDevicePoll(bool keep_mfc_input_state) {
1817   DVLOG(3) << "StopDevicePoll()";
1818   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1819
1820   // Signal the DevicePollTask() to stop, and stop the device poll thread.
1821   if (!SetDevicePollInterrupt())
1822     return false;
1823   device_poll_thread_.Stop();
1824   // Clear the interrupt now, to be sure.
1825   if (!ClearDevicePollInterrupt())
1826     return false;
1827
1828   // Stop streaming.
1829   if (!keep_mfc_input_state) {
1830     if (mfc_input_streamon_) {
1831       __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1832       IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
1833     }
1834     mfc_input_streamon_ = false;
1835   }
1836   if (mfc_output_streamon_) {
1837     __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1838     IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
1839   }
1840   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
1852   // Reset all our accounting info.
1853   if (!keep_mfc_input_state) {
1854     mfc_input_ready_queue_.clear();
1855     mfc_free_input_buffers_.clear();
1856     for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
1857       mfc_free_input_buffers_.push_back(i);
1858       mfc_input_buffer_map_[i].at_device = false;
1859       mfc_input_buffer_map_[i].bytes_used = 0;
1860       mfc_input_buffer_map_[i].input_id = -1;
1861     }
1862     mfc_input_buffer_queued_count_ = 0;
1863   }
1864   mfc_free_output_buffers_.clear();
1865   for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
1866     mfc_free_output_buffers_.push_back(i);
1867     mfc_output_buffer_map_[i].at_device = false;
1868     mfc_output_buffer_map_[i].input_id = -1;
1869   }
1870   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
1889   DVLOG(3) << "StopDevicePoll(): device poll stopped";
1890   return true;
1891 }
1892
1893 bool ExynosVideoDecodeAccelerator::SetDevicePollInterrupt() {
1894   DVLOG(3) << "SetDevicePollInterrupt()";
1895   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1896
1897   const uint64 buf = 1;
1898   if (HANDLE_EINTR(write(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) {
1899     DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed";
1900     NOTIFY_ERROR(PLATFORM_FAILURE);
1901     return false;
1902   }
1903   return true;
1904 }
1905
1906 bool ExynosVideoDecodeAccelerator::ClearDevicePollInterrupt() {
1907   DVLOG(3) << "ClearDevicePollInterrupt()";
1908   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1909
1910   uint64 buf;
1911   if (HANDLE_EINTR(read(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) {
1912     if (errno == EAGAIN) {
1913       // No interrupt flag set, and we're reading nonblocking.  Not an error.
1914       return true;
1915     } else {
1916       DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed";
1917       NOTIFY_ERROR(PLATFORM_FAILURE);
1918       return false;
1919     }
1920   }
1921   return true;
1922 }
1923
1924 void ExynosVideoDecodeAccelerator::StartResolutionChangeIfNeeded() {
1925   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1926   DCHECK_EQ(decoder_state_, kDecoding);
1927
1928   if (!resolution_change_pending_)
1929     return;
1930
1931   if (!mfc_output_gsc_input_queue_.empty() ||
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
1939   // Keep MFC input queue.
1940   if (!StopDevicePoll(true))
1941     return;
1942
1943   decoder_state_ = kChangingResolution;
1944   DCHECK(resolution_change_pending_);
1945   resolution_change_pending_ = false;
1946
1947   // Post a task to clean up buffers on child thread. This will also ensure
1948   // that we won't accept ReusePictureBuffer() anymore after that.
1949   child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1950       &ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers,
1951       weak_this_));
1952 }
1953
1954 void ExynosVideoDecodeAccelerator::FinishResolutionChange() {
1955   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1956   DVLOG(3) << "FinishResolutionChange()";
1957
1958   if (decoder_state_ == kError) {
1959     DVLOG(2) << "FinishResolutionChange(): early out: kError state";
1960     return;
1961   }
1962
1963   struct v4l2_format format;
1964   bool again;
1965   bool ret = GetFormatInfo(&format, &again);
1966   if (!ret || again) {
1967     DVLOG(3) << "Couldn't get format information after resolution change";
1968     NOTIFY_ERROR(PLATFORM_FAILURE);
1969     return;
1970   }
1971
1972   if (!CreateBuffersForFormat(format)) {
1973     DVLOG(3) << "Couldn't reallocate buffers after resolution change";
1974     NOTIFY_ERROR(PLATFORM_FAILURE);
1975     return;
1976   }
1977
1978   // From here we stay in kChangingResolution and wait for
1979   // AssignPictureBuffers() before we can resume.
1980 }
1981
1982 void ExynosVideoDecodeAccelerator::ResumeAfterResolutionChange() {
1983   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1984   DVLOG(3) << "ResumeAfterResolutionChange()";
1985
1986   decoder_state_ = kDecoding;
1987
1988   if (resolution_change_reset_pending_) {
1989     resolution_change_reset_pending_ = false;
1990     ResetTask();
1991     return;
1992   }
1993
1994   if (!StartDevicePoll())
1995     return;
1996
1997   EnqueueMfc();
1998   // Gsc will get enqueued in AssignPictureBuffersTask().
1999   ScheduleDecodeBufferTaskIfNeeded();
2000 }
2001
2002 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) {
2003   DVLOG(3) << "DevicePollTask()";
2004   DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
2005   TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask");
2006
2007   // This routine just polls the set of device fds, and schedules a
2008   // ServiceDeviceTask() on decoder_thread_ when processing needs to occur.
2009   // Other threads may notify this task to return early by writing to
2010   // device_poll_interrupt_fd_.
2011   struct pollfd pollfds[3];
2012   nfds_t nfds;
2013   int mfc_pollfd = -1;
2014
2015   // Add device_poll_interrupt_fd_;
2016   pollfds[0].fd = device_poll_interrupt_fd_;
2017   pollfds[0].events = POLLIN | POLLERR;
2018   nfds = 1;
2019
2020   if (poll_fds & kPollMfc) {
2021     DVLOG(3) << "DevicePollTask(): adding MFC to poll() set";
2022     pollfds[nfds].fd = mfc_fd_;
2023     pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI;
2024     mfc_pollfd = nfds;
2025     nfds++;
2026   }
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
2036   // Poll it!
2037   if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) {
2038     DPLOG(ERROR) << "DevicePollTask(): poll() failed";
2039     NOTIFY_ERROR(PLATFORM_FAILURE);
2040     return;
2041   }
2042
2043   bool mfc_event_pending = (mfc_pollfd != -1 &&
2044                             pollfds[mfc_pollfd].revents & POLLPRI);
2045
2046   // All processing should happen on ServiceDeviceTask(), since we shouldn't
2047   // touch decoder state from this thread.
2048   decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
2049       &ExynosVideoDecodeAccelerator::ServiceDeviceTask,
2050       base::Unretained(this), mfc_event_pending));
2051 }
2052
2053 void ExynosVideoDecodeAccelerator::NotifyError(Error error) {
2054   DVLOG(2) << "NotifyError()";
2055
2056   if (!child_message_loop_proxy_->BelongsToCurrentThread()) {
2057     child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
2058         &ExynosVideoDecodeAccelerator::NotifyError, weak_this_, error));
2059     return;
2060   }
2061
2062   if (client_) {
2063     client_->NotifyError(error);
2064     client_ptr_factory_.InvalidateWeakPtrs();
2065   }
2066 }
2067
2068 void ExynosVideoDecodeAccelerator::SetDecoderState(State state) {
2069   DVLOG(3) << "SetDecoderState(): state=" << state;
2070
2071   // We can touch decoder_state_ only if this is the decoder thread or the
2072   // decoder thread isn't running.
2073   if (decoder_thread_.message_loop() != NULL &&
2074       decoder_thread_.message_loop() != base::MessageLoop::current()) {
2075     decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
2076         &ExynosVideoDecodeAccelerator::SetDecoderState,
2077         base::Unretained(this), state));
2078   } else {
2079     decoder_state_ = state;
2080   }
2081 }
2082
2083 bool ExynosVideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format,
2084                                                  bool* again) {
2085   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2086
2087   *again = false;
2088   memset(format, 0, sizeof(*format));
2089   format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2090   if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_G_FMT, format)) != 0) {
2091     if (errno == EINVAL) {
2092       // EINVAL means we haven't seen sufficient stream to decode the format.
2093       *again = true;
2094       return true;
2095     } else {
2096       DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT";
2097       NOTIFY_ERROR(PLATFORM_FAILURE);
2098       return false;
2099     }
2100   }
2101
2102   return true;
2103 }
2104
2105 bool ExynosVideoDecodeAccelerator::CreateBuffersForFormat(
2106     const struct v4l2_format& format) {
2107   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2108   CHECK_EQ(format.fmt.pix_mp.num_planes, 2);
2109   frame_buffer_size_.SetSize(
2110       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;
2114   DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12MT_16X16);
2115   DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
2116            << frame_buffer_size_.ToString();
2117
2118   if (!CreateMfcOutputBuffers() || !CreateGscInputBuffers() ||
2119       !CreateGscOutputBuffers())
2120     return false;
2121
2122   return true;
2123 }
2124
2125 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() {
2126   DVLOG(3) << "CreateMfcInputBuffers()";
2127   // We always run this as we prepare to initialize.
2128   DCHECK_EQ(decoder_state_, kUninitialized);
2129   DCHECK(!mfc_input_streamon_);
2130   DCHECK(mfc_input_buffer_map_.empty());
2131
2132   __u32 pixelformat = 0;
2133   if (video_profile_ >= media::H264PROFILE_MIN &&
2134       video_profile_ <= media::H264PROFILE_MAX) {
2135     pixelformat = V4L2_PIX_FMT_H264;
2136   } else if (video_profile_ >= media::VP8PROFILE_MIN &&
2137              video_profile_ <= media::VP8PROFILE_MAX) {
2138     pixelformat = V4L2_PIX_FMT_VP8;
2139   } else {
2140     NOTREACHED();
2141   }
2142
2143   struct v4l2_format format;
2144   memset(&format, 0, sizeof(format));
2145   format.type                              = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2146   format.fmt.pix_mp.pixelformat            = pixelformat;
2147   format.fmt.pix_mp.plane_fmt[0].sizeimage = kMfcInputBufferMaxSize;
2148   format.fmt.pix_mp.num_planes             = 1;
2149   IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format);
2150
2151   struct v4l2_requestbuffers reqbufs;
2152   memset(&reqbufs, 0, sizeof(reqbufs));
2153   reqbufs.count  = kMfcInputBufferCount;
2154   reqbufs.type   = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2155   reqbufs.memory = V4L2_MEMORY_MMAP;
2156   IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs);
2157   mfc_input_buffer_map_.resize(reqbufs.count);
2158   for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
2159     mfc_free_input_buffers_.push_back(i);
2160
2161     // Query for the MEMORY_MMAP pointer.
2162     struct v4l2_plane planes[1];
2163     struct v4l2_buffer buffer;
2164     memset(&buffer, 0, sizeof(buffer));
2165     memset(planes, 0, sizeof(planes));
2166     buffer.index    = i;
2167     buffer.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2168     buffer.memory   = V4L2_MEMORY_MMAP;
2169     buffer.m.planes = planes;
2170     buffer.length   = 1;
2171     IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYBUF, &buffer);
2172     void* address = mmap(NULL, buffer.m.planes[0].length,
2173         PROT_READ | PROT_WRITE, MAP_SHARED, mfc_fd_,
2174         buffer.m.planes[0].m.mem_offset);
2175     if (address == MAP_FAILED) {
2176       DPLOG(ERROR) << "CreateMfcInputBuffers(): mmap() failed";
2177       return false;
2178     }
2179     mfc_input_buffer_map_[i].address = address;
2180     mfc_input_buffer_map_[i].length = buffer.m.planes[0].length;
2181   }
2182
2183   return true;
2184 }
2185
2186 bool ExynosVideoDecodeAccelerator::CreateMfcOutputBuffers() {
2187   DVLOG(3) << "CreateMfcOutputBuffers()";
2188   DCHECK(decoder_state_ == kInitialized ||
2189          decoder_state_ == kChangingResolution);
2190   DCHECK(!mfc_output_streamon_);
2191   DCHECK(mfc_output_buffer_map_.empty());
2192
2193   // Number of MFC output buffers we need.
2194   struct v4l2_control ctrl;
2195   memset(&ctrl, 0, sizeof(ctrl));
2196   ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
2197   IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_G_CTRL, &ctrl);
2198   mfc_output_dpb_size_ = ctrl.value;
2199
2200   // Output format setup in Initialize().
2201
2202   // Allocate the output buffers.
2203   struct v4l2_requestbuffers reqbufs;
2204   memset(&reqbufs, 0, sizeof(reqbufs));
2205   reqbufs.count  = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount;
2206   reqbufs.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2207   reqbufs.memory = V4L2_MEMORY_MMAP;
2208   IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs);
2209
2210   // Fill our free-buffers list, and create DMABUFs from them.
2211   mfc_output_buffer_map_.resize(reqbufs.count);
2212   for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
2213     mfc_free_output_buffers_.push_back(i);
2214
2215     // Query for the MEMORY_MMAP pointer.
2216     struct v4l2_plane planes[2];
2217     struct v4l2_buffer buffer;
2218     memset(&buffer, 0, sizeof(buffer));
2219     memset(planes, 0, sizeof(planes));
2220     buffer.index    = i;
2221     buffer.type     = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2222     buffer.memory   = V4L2_MEMORY_MMAP;
2223     buffer.m.planes = planes;
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     }
2239   }
2240
2241   return true;
2242 }
2243
2244 bool ExynosVideoDecodeAccelerator::CreateGscInputBuffers() {
2245   DVLOG(3) << "CreateGscInputBuffers()";
2246   DCHECK(decoder_state_ == kInitialized ||
2247          decoder_state_ == kChangingResolution);
2248   DCHECK(!gsc_input_streamon_);
2249   DCHECK(gsc_input_buffer_map_.empty());
2250
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
2305   return true;
2306 }
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
2352 void ExynosVideoDecodeAccelerator::DestroyMfcInputBuffers() {
2353   DVLOG(3) << "DestroyMfcInputBuffers()";
2354   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2355   DCHECK(!mfc_input_streamon_);
2356
2357   for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
2358     if (mfc_input_buffer_map_[i].address != NULL) {
2359       munmap(mfc_input_buffer_map_[i].address,
2360           mfc_input_buffer_map_[i].length);
2361     }
2362   }
2363
2364   struct v4l2_requestbuffers reqbufs;
2365   memset(&reqbufs, 0, sizeof(reqbufs));
2366   reqbufs.count = 0;
2367   reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2368   reqbufs.memory = V4L2_MEMORY_MMAP;
2369   if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
2370     DPLOG(ERROR) << "DestroyMfcInputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
2371
2372   mfc_input_buffer_map_.clear();
2373   mfc_free_input_buffers_.clear();
2374 }
2375
2376 void ExynosVideoDecodeAccelerator::DestroyMfcOutputBuffers() {
2377   DVLOG(3) << "DestroyMfcOutputBuffers()";
2378   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2379   DCHECK(!mfc_output_streamon_);
2380
2381   for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
2382     if (mfc_output_buffer_map_[i].address[0] != NULL)
2383       munmap(mfc_output_buffer_map_[i].address[0],
2384           mfc_output_buffer_map_[i].length[0]);
2385     if (mfc_output_buffer_map_[i].address[1] != NULL)
2386       munmap(mfc_output_buffer_map_[i].address[1],
2387           mfc_output_buffer_map_[i].length[1]);
2388   }
2389
2390   struct v4l2_requestbuffers reqbufs;
2391   memset(&reqbufs, 0, sizeof(reqbufs));
2392   reqbufs.count = 0;
2393   reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2394   reqbufs.memory = V4L2_MEMORY_MMAP;
2395   if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
2396     DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS";
2397
2398   mfc_output_buffer_map_.clear();
2399   mfc_free_output_buffers_.clear();
2400 }
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 }
2458
2459 void ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
2460   DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2461   DVLOG(3) << "ResolutionChangeDestroyBuffers()";
2462
2463   DestroyGscInputBuffers();
2464   DestroyGscOutputBuffers();
2465   DestroyMfcOutputBuffers();
2466
2467   // Finish resolution change on decoder thread.
2468   decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
2469       &ExynosVideoDecodeAccelerator::FinishResolutionChange,
2470       base::Unretained(this)));
2471 }
2472
2473 void ExynosVideoDecodeAccelerator::SendPictureReady() {
2474   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2475   bool resetting_or_flushing =
2476       (decoder_state_ == kResetting || decoder_flushing_);
2477   while (pending_picture_ready_.size() > 0) {
2478     bool cleared = pending_picture_ready_.front().cleared;
2479     const media::Picture& picture = pending_picture_ready_.front().picture;
2480     if (cleared && picture_clearing_count_ == 0) {
2481       // 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.
2483       io_message_loop_proxy_->PostTask(
2484           FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture));
2485       pending_picture_ready_.pop();
2486     } else if (!cleared || resetting_or_flushing) {
2487       DVLOG(3) << "SendPictureReady()"
2488                << ". cleared=" << pending_picture_ready_.front().cleared
2489                << ", decoder_state_=" << decoder_state_
2490                << ", decoder_flushing_=" << decoder_flushing_
2491                << ", picture_clearing_count_=" << picture_clearing_count_;
2492       // If the picture is not cleared, post it to the child thread because it
2493       // has to be cleared in the child thread. A picture only needs to be
2494       // cleared once. If the decoder is resetting or flushing, send all
2495       // pictures to ensure PictureReady arrive before reset or flush done.
2496       child_message_loop_proxy_->PostTaskAndReply(
2497           FROM_HERE,
2498           base::Bind(&Client::PictureReady, client_, picture),
2499           // Unretained is safe. If Client::PictureReady gets to run, |this| is
2500           // alive. Destroy() will wait the decode thread to finish.
2501           base::Bind(&ExynosVideoDecodeAccelerator::PictureCleared,
2502                      base::Unretained(this)));
2503       picture_clearing_count_++;
2504       pending_picture_ready_.pop();
2505     } else {
2506       // This picture is cleared. But some pictures are about to be cleared on
2507       // the child thread. To preserve the order, do not send this until those
2508       // pictures are cleared.
2509       break;
2510     }
2511   }
2512 }
2513
2514 void ExynosVideoDecodeAccelerator::PictureCleared() {
2515   DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_;
2516   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2517   DCHECK_GT(picture_clearing_count_, 0);
2518   picture_clearing_count_--;
2519   SendPictureReady();
2520 }
2521
2522 }  // namespace content