Skip to content
This repository was archived by the owner on Dec 24, 2024. It is now read-only.

Commit 443ba11

Browse files
committed
ADD: [amc] API21+ buffer handling
1 parent b779909 commit 443ba11

3 files changed

Lines changed: 51 additions & 19 deletions

File tree

xbmc/android/jni/MediaCodec.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,18 +162,30 @@ const CJNIMediaFormat CJNIMediaCodec::getOutputFormat()
162162
"getOutputFormat", "()Landroid/media/MediaFormat;");
163163
}
164164

165-
std::vector<CJNIByteBuffer> CJNIMediaCodec::getInputBuffers()
165+
std::vector<CJNIByteBuffer> CJNIMediaCodec::getInputBuffers() // Deprecated as of API 21
166166
{
167167
return jcast<CJNIByteBuffers>(call_method<jhobjectArray>(m_object,
168168
"getInputBuffers", "()[Ljava/nio/ByteBuffer;"));
169169
}
170170

171-
std::vector<CJNIByteBuffer> CJNIMediaCodec::getOutputBuffers()
171+
std::vector<CJNIByteBuffer> CJNIMediaCodec::getOutputBuffers() // Deprecated as of API 21
172172
{
173173
return jcast<CJNIByteBuffers>(call_method<jhobjectArray>(m_object,
174174
"getOutputBuffers", "()[Ljava/nio/ByteBuffer;"));
175175
}
176176

177+
const CJNIByteBuffer CJNIMediaCodec::getInputBuffer(int index) // API 21+
178+
{
179+
return call_method<jhobject>(m_object,
180+
"getInputBuffer", "(I)Ljava/nio/ByteBuffer;", index);
181+
}
182+
183+
const CJNIByteBuffer CJNIMediaCodec::getOutputBuffer(int index) // API 21+
184+
{
185+
return call_method<jhobject>(m_object,
186+
"getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", index);
187+
}
188+
177189
void CJNIMediaCodec::setVideoScalingMode(int mode)
178190
{
179191
call_method<void>(m_object,

xbmc/android/jni/MediaCodec.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ class CJNIMediaCodec : public CJNIBase
4646
int dequeueOutputBuffer(const CJNIMediaCodecBufferInfo &info, int64_t timeoutUs);
4747
void releaseOutputBuffer(int index, bool render);
4848
const CJNIMediaFormat getOutputFormat();
49-
std::vector<CJNIByteBuffer> getInputBuffers();
50-
std::vector<CJNIByteBuffer> getOutputBuffers();
49+
std::vector<CJNIByteBuffer> getInputBuffers(); // Deprecated as of API 21
50+
std::vector<CJNIByteBuffer> getOutputBuffers(); // Deprecated as of API 21
51+
const CJNIByteBuffer getInputBuffer(int index); // API 21+
52+
const CJNIByteBuffer getOutputBuffer(int index); // API 21+
5153
void setVideoScalingMode(int mode);
5254

5355
static void PopulateStaticFields();

xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -741,10 +741,11 @@ int CDVDVideoCodecAndroidMediaCodec::Decode(uint8_t *pData, int iSize, double dt
741741
}
742742
else if (index >= 0)
743743
{
744+
// Deprecated as of API 21:
744745
// docs lie, getInputBuffers should be good after
745746
// m_codec->start() but the internal refs are not
746747
// setup until much later on some devices.
747-
if (m_input.empty())
748+
if (CJNIBase::GetSDKVersion() < 21 && m_input.empty())
748749
{
749750
m_input = m_codec->getInputBuffers();
750751
if (xbmc_jnienv()->ExceptionCheck())
@@ -763,14 +764,15 @@ int CDVDVideoCodecAndroidMediaCodec::Decode(uint8_t *pData, int iSize, double dt
763764
iSize = m_bitstream->GetConvertSize();
764765
pData = m_bitstream->GetConvertBuffer();
765766
}
766-
int size = m_input[index].capacity();
767+
CJNIByteBuffer buffer = (CJNIBase::GetSDKVersion() < 21 ? m_input[index] : m_codec->getInputBuffer(index));
768+
int size = buffer.capacity();
767769
if (iSize > size)
768770
{
769771
CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Decode, iSize(%d) > size(%d)", iSize, size);
770772
iSize = size;
771773
}
772774
// fetch a pointer to the ByteBuffer backing store
773-
uint8_t *dst_ptr = (uint8_t*)xbmc_jnienv()->GetDirectBufferAddress(m_input[index].get_raw());
775+
uint8_t *dst_ptr = (uint8_t*)xbmc_jnienv()->GetDirectBufferAddress(buffer.get_raw());
774776
if (dst_ptr)
775777
{
776778
// Codec specifics
@@ -949,7 +951,7 @@ void CDVDVideoCodecAndroidMediaCodec::FlushInternal()
949951
}
950952
m_inflight.clear();
951953

952-
for (size_t i = 0; i < m_output.size(); i++)
954+
for (size_t i = 0; i < m_output.size(); i++) // Deprecated as of API 21
953955
{
954956
m_inflight.push_back(
955957
new CDVDMediaCodecInfo(i, m_textureId, m_codec, m_surfaceTexture, m_frameAvailable)
@@ -1070,10 +1072,11 @@ int CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(void)
10701072
return 0;
10711073
}
10721074

1075+
// Deprecated as of API 21
10731076
// some devices will return a valid index
10741077
// before signaling INFO_OUTPUT_BUFFERS_CHANGED which
10751078
// is used to setup m_output, D'uh. setup m_output here.
1076-
if (m_output.empty())
1079+
if (CJNIBase::GetSDKVersion() < 21 && m_output.empty())
10771080
{
10781081
m_output = m_codec->getOutputBuffers();
10791082
if (xbmc_jnienv()->ExceptionCheck())
@@ -1109,20 +1112,32 @@ int CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(void)
11091112

11101113
if (!m_render_sw)
11111114
{
1112-
m_videobuffer.mediacodec = m_inflight[index]->Retain();
1115+
size_t i = 0;
1116+
for (; i < m_inflight.size(); ++i)
1117+
{
1118+
if (m_inflight[i]->GetIndex() == index)
1119+
break;
1120+
}
1121+
if (i == m_inflight.size())
1122+
m_inflight.push_back(
1123+
new CDVDMediaCodecInfo(index, m_textureId, m_codec, m_surfaceTexture, m_frameAvailable)
1124+
);
1125+
m_videobuffer.mediacodec = m_inflight[i]->Retain();
11131126
m_videobuffer.mediacodec->Validate(true);
11141127
}
11151128
else
11161129
{
11171130
int size = bufferInfo.size();
11181131
int offset = bufferInfo.offset();
11191132

1120-
if (!m_output[index].isDirect())
1133+
CJNIByteBuffer buffer = (CJNIBase::GetSDKVersion() < 21 ? m_output[index] : m_codec->getOutputBuffer(index));
1134+
1135+
if (!buffer.isDirect())
11211136
CLog::Log(LOGWARNING, "CDVDVideoCodecAndroidMediaCodec:: m_output[index].isDirect == false");
11221137

1123-
if (size && m_output[index].capacity())
1138+
if (size && buffer.capacity())
11241139
{
1125-
uint8_t *src_ptr = (uint8_t*)xbmc_jnienv()->GetDirectBufferAddress(m_output[index].get_raw());
1140+
uint8_t *src_ptr = (uint8_t*)xbmc_jnienv()->GetDirectBufferAddress(buffer.get_raw());
11261141
src_ptr += offset;
11271142

11281143
int loop_end = 0;
@@ -1176,14 +1191,17 @@ int CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(void)
11761191
}
11771192
else if (index == CJNIMediaCodec::INFO_OUTPUT_BUFFERS_CHANGED)
11781193
{
1179-
m_output = m_codec->getOutputBuffers();
1180-
if (xbmc_jnienv()->ExceptionCheck())
1194+
if (CJNIBase::GetSDKVersion() < 21)
11811195
{
1182-
CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(INFO_OUTPUT_BUFFERS_CHANGED) ExceptionCheck: getOutputBuffers");
1183-
xbmc_jnienv()->ExceptionDescribe();
1184-
xbmc_jnienv()->ExceptionClear();
1196+
m_output = m_codec->getOutputBuffers();
1197+
if (xbmc_jnienv()->ExceptionCheck())
1198+
{
1199+
CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::GetOutputPicture(INFO_OUTPUT_BUFFERS_CHANGED) ExceptionCheck: getOutputBuffers");
1200+
xbmc_jnienv()->ExceptionDescribe();
1201+
xbmc_jnienv()->ExceptionClear();
1202+
}
1203+
FlushInternal();
11851204
}
1186-
FlushInternal();
11871205
}
11881206
else if (index == CJNIMediaCodec::INFO_OUTPUT_FORMAT_CHANGED)
11891207
{

0 commit comments

Comments
 (0)