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