void CDVDMediaCodecInfo::ReleaseOutputBuffer(bool render) {
  CSingleLock lock(m_section);
  //REPORT_FUNCTION();
  //printf("void CDVDMediaCodecInfo::ReleaseOutputBuffer(%x)\n", render);fflush(stdout);

  if (!m_valid || m_isReleased)
    return;

  // release OutputBuffer and render if indicated
  // then wait for rendered frame to become avaliable.

  if (render)
    m_frameready->Reset();

  //m_codec->releaseOutputBuffer(m_index, render);
  media_codec_release_output_buffer(m_codec, m_index, render);
  m_isReleased = true;
}
Esempio n. 2
0
static void
gst_mir_buffer_pool_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
{
#if 1
  GstMemory *mem = { NULL };
  int err = 0;
  MediaCodecDelegate delegate;

  /* Get access to the GstMemory stored in the GstBuffer */
  if (gst_buffer_n_memory (buffer) >= 1 &&
      (mem = gst_buffer_peek_memory (buffer, 0))
      && gst_is_mir_image_memory (mem)) {
    GST_DEBUG_OBJECT (pool, "It is Mir image memory");
  } else
    GST_DEBUG_OBJECT (pool, "It is NOT Mir image memory");

  delegate = gst_mir_image_memory_get_codec (mem);
  if (!delegate) {
    GST_WARNING_OBJECT (pool, "delegate is NULL, rendering will not function");
    goto done;
  }

  GST_DEBUG_OBJECT (pool, "mem: %p", mem);
  GST_DEBUG_OBJECT (pool, "gst_mir_image_memory_get_codec (mem): %p", delegate);
  GST_DEBUG_OBJECT (pool, "gst_mir_image_memory_get_buffer_index (mem): %d",
      gst_mir_image_memory_get_buffer_index (mem));
  GST_DEBUG_OBJECT (pool, "Rendering buffer: %d",
      gst_mir_image_memory_get_buffer_index (mem));
  GST_DEBUG_OBJECT (pool, "Releasing output buffer index: %d",
      gst_mir_image_memory_get_buffer_index (mem));

  /* Render and release the output buffer back to the decoder */
  err =
      media_codec_release_output_buffer (delegate,
      gst_mir_image_memory_get_buffer_index (mem));
  if (err < 0)
    GST_WARNING_OBJECT (pool,
        "Failed to release output buffer. Rendering will probably be affected (err: %d).",
        err);
#endif

done:
  GST_BUFFER_POOL_CLASS (parent_class)->release_buffer (pool, buffer);
}
int CDVDVideoCodecHybris::GetOutputPicture(void) {
  int rtn = 0;
  int ret = 0;
  int64_t timeout_us = 5000;
  int index;// = m_codec->dequeueOutputBuffer(bufferInfo, timeout_us);
  MediaCodecBufferInfo bufferInfo;
  ret = media_codec_dequeue_output_buffer(m_codec, &bufferInfo, timeout_us);
  index = bufferInfo.index;
  if (ret == OK)
  {
    if (m_drop)
    {
      media_codec_release_output_buffer(m_codec, index, 0);
      return 0;
    }

    // some devices will return a valid index
    // before signaling INFO_OUTPUT_BUFFERS_CHANGED which
    // is used to setup m_output, D'uh. setup m_output here.
#if 0
    if (m_output.empty())
    {
      m_output = m_codec->getOutputBuffers();
      FlushInternal();
    }
#endif
    int flags = bufferInfo.flags;
#if 0
    if (flags & CJNIMediaCodec::BUFFER_FLAG_SYNC_FRAME)
      CLog::Log(LOGDEBUG, "CDVDVideoCodecHybris:: BUFFER_FLAG_SYNC_FRAME");

    if (flags & CJNIMediaCodec::BUFFER_FLAG_CODEC_CONFIG)
      CLog::Log(LOGDEBUG, "CDVDVideoCodecHybris:: BUFFER_FLAG_CODEC_CONFIG");
#endif
    if (flags & 4 /*CJNIMediaCodec::BUFFER_FLAG_END_OF_STREAM*/)
    {
      CLog::Log(LOGDEBUG, "CDVDVideoCodecHybris:: BUFFER_FLAG_END_OF_STREAM");
      media_codec_release_output_buffer(m_codec, index, 0);
      return 0;
    }

    if (!m_render_sw)
    {
      size_t i = 0;
      for (; i < m_inflight.size(); ++i)
      {
        if (m_inflight[i]->GetIndex() == index)
          break;
      }
      if (i == m_inflight.size())
        m_inflight.push_back(
          new CDVDMediaCodecInfo(index, m_textureId, m_codec, m_surfaceTexture, m_frameAvailable)
        );
      m_videoBuffer.mediacodec = m_inflight[i]->Retain();
      m_videoBuffer.mediacodec->Validate(true);
    }
    else
    {
      int size = bufferInfo.size;
      int offset = bufferInfo.offset;

      if (size && media_codec_get_nth_output_buffer_capacity(m_codec, index))
      {
        uint8_t *src_ptr = (uint8_t*)media_codec_get_nth_output_buffer(m_codec, index);
        src_ptr += offset;

        int loop_end = 0;
        if (m_videoBuffer.format == RENDER_FMT_NV12)
          loop_end = 2;
        else if (m_videoBuffer.format == RENDER_FMT_YUV420P)
          loop_end = 3;

        for (int i = 0; i < loop_end; i++)
        {
          uint8_t *src = src_ptr + m_src_offset[i];
          int src_stride = m_src_stride[i];
          uint8_t *dst = m_videoBuffer.data[i];
          int dst_stride = m_videoBuffer.iLineSize[i];

          int height = m_videoBuffer.iHeight;
          if (i > 0)
            height = (m_videoBuffer.iHeight + 1) / 2;

          for (int j = 0; j < height; j++, src += src_stride, dst += dst_stride)
            memcpy(dst, src, dst_stride);
        }
      }
      media_codec_release_output_buffer(m_codec, index, 0);
    }

    int64_t pts = bufferInfo.presentation_time_us;
    m_videoBuffer.dts = DVD_NOPTS_VALUE;
//    m_videoBuffer.pts = DVD_NOPTS_VALUE;
  //  if (pts != AV_NOPTS_VALUE)
    //  m_videoBuffer.pts = pts;
#if 0
    if (pts != AV_NOPTS_VALUE)
      m_videoBuffer.pts = pts;
#endif
/*
    CLog::Log(LOGDEBUG, "CDVDVideoCodecHybris::GetOutputPicture "
        "index(%d), pts(%f)", index, m_videoBuffer.pts);
*/
    rtn = 1;
  }
  else if (ret == -3 /* == CJNIMediaCodec::INFO_OUTPUT_BUFFERS_CHANGED*/)
  {
//    m_output = m_codec->getOutputBuffers();
  }
  else if (ret == -2 /* CJNIMediaCodec::INFO_OUTPUT_FORMAT_CHANGED*/)
  {
    OutputFormatChanged();
  }
  else if (ret == -1/* CJNIMediaCodec::INFO_TRY_AGAIN_LATER*/)
  {
    // normal dequeueOutputBuffer timeout, ignore it.
    rtn = -1;
  }
  else
  {
    // we should never get here
    CLog::Log(LOGERROR, "CDVDVideoCodecHybris::GetOutputPicture unknown index(%d)", index);
  }

  return rtn;
}