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; }
int CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(void) { int rtn = 0; int64_t timeout_us = 50000; CJNIMediaCodecBufferInfo bufferInfo; int index = m_codec->dequeueOutputBuffer(bufferInfo, timeout_us); if (xbmc_jnienv()->ExceptionOccurred()) { CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::GetOutputPicture ExceptionOccurred"); xbmc_jnienv()->ExceptionDescribe(); xbmc_jnienv()->ExceptionClear(); return 0; } if (index >= 0) { if (m_drop) { m_codec->releaseOutputBuffer(index, false); if (xbmc_jnienv()->ExceptionOccurred()) xbmc_jnienv()->ExceptionClear(); 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 (m_output.empty()) { m_output = m_codec->getOutputBuffers(); FlushInternal(); } int flags = bufferInfo.flags(); if (flags & CJNIMediaCodec::BUFFER_FLAG_SYNC_FRAME) CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec:: BUFFER_FLAG_SYNC_FRAME"); if (flags & CJNIMediaCodec::BUFFER_FLAG_CODEC_CONFIG) CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec:: BUFFER_FLAG_CODEC_CONFIG"); if (flags & CJNIMediaCodec::BUFFER_FLAG_END_OF_STREAM) { CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec:: BUFFER_FLAG_END_OF_STREAM"); m_codec->releaseOutputBuffer(index, false); if (xbmc_jnienv()->ExceptionOccurred()) xbmc_jnienv()->ExceptionClear(); return 0; } if (!m_render_sw) { m_videobuffer.mediacodec = m_inflight[index]->Retain(); m_videobuffer.mediacodec->Validate(true); } else { int size = bufferInfo.size(); int offset = bufferInfo.offset(); if (!m_output[index].isDirect()) CLog::Log(LOGWARNING, "CDVDVideoCodecAndroidMediaCodec:: m_output[index].isDirect == false"); if (size && m_output[index].capacity()) { uint8_t *src_ptr = (uint8_t*)xbmc_jnienv()->GetDirectBufferAddress(m_output[index].get_raw()); 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; if (src_stride == dst_stride) memcpy(dst, src, dst_stride * height); else for (int j = 0; j < height; j++, src += src_stride, dst += dst_stride) memcpy(dst, src, dst_stride); } } m_codec->releaseOutputBuffer(index, false); } int64_t pts= bufferInfo.presentationTimeUs(); m_videobuffer.dts = DVD_NOPTS_VALUE; m_videobuffer.pts = DVD_NOPTS_VALUE; if (pts != AV_NOPTS_VALUE) m_videobuffer.pts = pts; /* CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec::GetOutputPicture " "index(%d), pts(%f)", index, m_videobuffer.pts); */ // always, check/clear jni exceptions. if (xbmc_jnienv()->ExceptionOccurred()) xbmc_jnienv()->ExceptionClear(); rtn = 1; } else if (index == CJNIMediaCodec::INFO_OUTPUT_BUFFERS_CHANGED) { m_output = m_codec->getOutputBuffers(); FlushInternal(); } else if (index == CJNIMediaCodec::INFO_OUTPUT_FORMAT_CHANGED) { CJNIMediaFormat mediaformat = m_codec->getOutputFormat(); ConfigureOutputFormat(&mediaformat); } else if (index == CJNIMediaCodec::INFO_TRY_AGAIN_LATER) { // normal dequeueOutputBuffer timeout, ignore it. rtn = -1; } else { // we should never get here CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::GetOutputPicture unknown index(%d)", index); } return rtn; }
int RageFileObj::Flush() { return FlushInternal(); }