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; }
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; }