aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Pfau <pfau@peak3d.de>2020-06-03 13:20:08 +0200
committerGitHub <noreply@github.com>2020-06-03 13:20:08 +0200
commit788d4eaf5b6aea210be4e3e14edd440e662da2e5 (patch)
treebf7c9e2502cab08f505ced91a4245d33b5f3b7ed
parent9afd7ab5eacc618293dfa7a8ef440c2752fa5585 (diff)
parenteeab938d2c935fcf54eabdf2f629346acde01113 (diff)
Merge pull request #17988 from peak3d/leia_jniexceptions
[Backport][Android] More exception handling in MediaCodec
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp79
1 files changed, 68 insertions, 11 deletions
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
index 362782f500..e4661e3397 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
@@ -788,7 +788,9 @@ void CDVDVideoCodecAndroidMediaCodec::Dispose()
if (m_codec)
{
m_codec->stop();
+ xbmc_jnienv()->ExceptionClear();
m_codec->release();
+ xbmc_jnienv()->ExceptionClear();
m_codec = nullptr;
m_state = MEDIACODEC_STATE_STOPPED;
}
@@ -833,6 +835,12 @@ bool CDVDVideoCodecAndroidMediaCodec::AddData(const DemuxPacket &packet)
// We received a packet but already reached EOS. Flush...
FlushInternal();
m_codec->flush();
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::AddData: flush failed");
+ return false;
+ }
m_state = MEDIACODEC_STATE_FLUSHED;
}
@@ -874,10 +882,17 @@ bool CDVDVideoCodecAndroidMediaCodec::AddData(const DemuxPacket &packet)
m_state = MEDIACODEC_STATE_RUNNING;
CJNIByteBuffer buffer = m_codec->getInputBuffer(m_indexInputBuffer);
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::AddData: getInputBuffer failed");
+ return false;
+ }
+
size_t out_size = buffer.capacity();
if ((size_t)iSize > out_size)
{
- CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::AddData, iSize(%d) > size(%d)", iSize, out_size);
+ CLog::Log(LOGNOTICE, "CDVDVideoCodecAndroidMediaCodec::AddData: iSize(%d) > size(%d)", iSize, out_size);
iSize = out_size;
}
uint8_t* dst_ptr = (uint8_t*)xbmc_jnienv()->GetDirectBufferAddress(buffer.get_raw());
@@ -960,7 +975,6 @@ bool CDVDVideoCodecAndroidMediaCodec::AddData(const DemuxPacket &packet)
}
if (xbmc_jnienv()->ExceptionCheck())
{
- xbmc_jnienv()->ExceptionDescribe();
xbmc_jnienv()->ExceptionClear();
CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::AddData error");
}
@@ -987,10 +1001,22 @@ void CDVDVideoCodecAndroidMediaCodec::Reset()
// now we can flush the actual MediaCodec object
CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec::Reset Current state (%d)", m_state);
m_state = MEDIACODEC_STATE_FLUSHED;
+
m_codec->flush();
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Reset: flush failed");
+ }
CJNIMediaFormat mediaFormat = m_codec->getOutputFormat();
- InjectExtraData(mediaFormat);
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Reset: getOutputFormat failed");
+ }
+ else
+ InjectExtraData(mediaFormat);
// Invalidate our local VideoPicture bits
m_videobuffer.pts = DVD_NOPTS_VALUE;
@@ -1010,7 +1036,7 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecAndroidMediaCodec::GetPicture(VideoPictur
if (!m_opened)
return VC_NONE;
- if (m_OutputDuration < m_fpsDuration || (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN)!=0)
+ if (m_state == MEDIACODEC_STATE_RUNNING && (m_OutputDuration < m_fpsDuration || (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN)!=0))
{
m_videobuffer.videoBuffer = pVideoPicture->videoBuffer;
@@ -1049,7 +1075,15 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecAndroidMediaCodec::GetPicture(VideoPictur
{
// try to fetch an input buffer
if (m_indexInputBuffer < 0)
+ {
m_indexInputBuffer = m_codec->dequeueInputBuffer(5000 /*timout*/);
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::GetPicture dequeueInputBuffer failed");
+ m_indexInputBuffer = -1;
+ }
+ }
if (m_indexInputBuffer >= 0)
{
@@ -1096,7 +1130,15 @@ void CDVDVideoCodecAndroidMediaCodec::SignalEndOfStream()
}
if (m_indexInputBuffer < 0)
+ {
m_indexInputBuffer = m_codec->dequeueInputBuffer(100000);
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::SignalEndOfStream: dequeueInputBuffer failed");
+ }
+ }
+
xbmc_jnienv()->ExceptionClear();
if (m_indexInputBuffer >= 0)
@@ -1106,8 +1148,7 @@ void CDVDVideoCodecAndroidMediaCodec::SignalEndOfStream()
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
- CLog::Log(LOGWARNING, "CDVDVideoCodecAndroidMediaCodec::%s: queueInputBuffer failed",
- __func__);
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::SignalEndOfStream: queueInputBuffer failed");
}
else
{
@@ -1186,22 +1227,20 @@ bool CDVDVideoCodecAndroidMediaCodec::ConfigureMediaCodec(void)
int flags = 0;
m_codec->configure(mediaformat, m_jnivideosurface,
m_crypto ? *m_crypto : CJNIMediaCrypto(jni::jhobject(NULL)), flags);
-
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
- CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec configure error");
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::ConfigureMediaCodec: configure failed");
return false;
}
m_state = MEDIACODEC_STATE_CONFIGURED;
m_codec->start();
-
if (xbmc_jnienv()->ExceptionCheck())
{
xbmc_jnienv()->ExceptionClear();
Dispose();
- CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec start error");
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec:ConfigureMediaCodec: start failed");
return false;
}
m_state = MEDIACODEC_STATE_FLUSHED;
@@ -1216,10 +1255,17 @@ bool CDVDVideoCodecAndroidMediaCodec::ConfigureMediaCodec(void)
int CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(void)
{
int rtn = 0;
-
int64_t timeout_us = 10000;
CJNIMediaCodecBufferInfo bufferInfo;
+
ssize_t index = m_codec->dequeueOutputBuffer(bufferInfo, timeout_us);
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec:GetOutputPicture dequeueOutputBuffer failed");
+ return -2;
+ }
+
if (index >= 0)
{
int64_t pts = bufferInfo.presentationTimeUs();
@@ -1238,6 +1284,11 @@ int CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(void)
{
m_noPictureLoop = 0;
m_codec->releaseOutputBuffer(index, false);
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::GetOutputPicture: releaseOutputBuffer (drop) failed");
+ }
return -2;
}
@@ -1246,6 +1297,11 @@ int CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(void)
{
CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec:: BUFFER_FLAG_END_OF_STREAM");
m_codec->releaseOutputBuffer(index, false);
+ if (xbmc_jnienv()->ExceptionCheck())
+ {
+ xbmc_jnienv()->ExceptionClear();
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::GetOutputPicture: releaseOutputBuffer (eof) failed");
+ }
return -1;
}
@@ -1456,5 +1512,6 @@ void CDVDVideoCodecAndroidMediaCodec::surfaceDestroyed(CJNISurfaceHolder holder)
if (m_jnisurface)
m_jnisurface->release();
m_codec->stop();
+ xbmc_jnienv()->ExceptionClear();
}
}