memdiacodec 解码器在 android 5.0 上工作但不在 android 4.4 上工作
memdiacodec decoder working on android 5.0 but not on android 4.4
我正在尝试在 Android 上使用 MediaCodec 解码 h264 流。
我使用 csd-0
、csd-1
像这样设置 sps
和 pps
。
MediaFormat format = MediaFormat.createVideoFormat(MIME, WIDTH, HEIGHT);
format.setByteBuffer("csd-0", sps);
format.setByteBuffer("csd-1", pps);
我使用输出表面配置解码器以呈现输出数据。
decoder.configure(format, surface, null, 0);
然后,我只是启动一个线程来解码我使用此循环从网络接收到的数据。
while (running) {
if (!isEOS) {
int inIndex = decoder.dequeueInputBuffer(10000);
if (inIndex >= 0) {
ByteBuffer buffer = inputBuffers[inIndex];
byte[] data = getVideoPacket(); // native method that get data from network
buffer.put(data);
decoder.queueInputBuffer(inIndex, 0, data.length, 0L, 0);
}
}
int outIndex = decoder.dequeueOutputBuffer(info, 10000);
switch (outIndex) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
outputBuffers = decoder.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
Log.d("DecodeActivity", "New format " + decoder.getOutputFormat());
MediaFormat format = decoder.getOutputFormat();
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");
break;
default:
ByteBuffer buffer = outputBuffers[outIndex];
Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer);
decoder.releaseOutputBuffer(outIndex, true); // render
break;
}
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
break;
}
}
请注意,我使用 0
作为 queueInputBuffer
的 presentationTimestamp,因为我得到的数据来自网络套接字,我不知道如何计算适当的时间戳。
我在 android 5.0(及更高版本)上得到了我想要的东西,但是当我 运行 这些代码在 android 4.4 上时,表面上没有任何显示(实际上我可以偶尔看到相同的图片片段,但大多数时候,表面只是黑色)。
我尝试用从文件中获取的数据填充输入缓冲区(使用 MediaExtractor),它在 android 5.0 和 4.4 上运行良好。
如有任何帮助,我们将不胜感激。
看来问题出在获取数据的方式上。我曾经 get
来自原生层的数据:
public static native byte[] getVideoPacket();
现在我 push
数据从本机层到 java 层:
env->CallVoidMethod(..., data);
现在一切正常。我不知道为什么,但这种方式对我有用。
我正在尝试在 Android 上使用 MediaCodec 解码 h264 流。
我使用 csd-0
、csd-1
像这样设置 sps
和 pps
。
MediaFormat format = MediaFormat.createVideoFormat(MIME, WIDTH, HEIGHT);
format.setByteBuffer("csd-0", sps);
format.setByteBuffer("csd-1", pps);
我使用输出表面配置解码器以呈现输出数据。
decoder.configure(format, surface, null, 0);
然后,我只是启动一个线程来解码我使用此循环从网络接收到的数据。
while (running) {
if (!isEOS) {
int inIndex = decoder.dequeueInputBuffer(10000);
if (inIndex >= 0) {
ByteBuffer buffer = inputBuffers[inIndex];
byte[] data = getVideoPacket(); // native method that get data from network
buffer.put(data);
decoder.queueInputBuffer(inIndex, 0, data.length, 0L, 0);
}
}
int outIndex = decoder.dequeueOutputBuffer(info, 10000);
switch (outIndex) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
outputBuffers = decoder.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
Log.d("DecodeActivity", "New format " + decoder.getOutputFormat());
MediaFormat format = decoder.getOutputFormat();
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");
break;
default:
ByteBuffer buffer = outputBuffers[outIndex];
Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer);
decoder.releaseOutputBuffer(outIndex, true); // render
break;
}
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
break;
}
}
请注意,我使用 0
作为 queueInputBuffer
的 presentationTimestamp,因为我得到的数据来自网络套接字,我不知道如何计算适当的时间戳。
我在 android 5.0(及更高版本)上得到了我想要的东西,但是当我 运行 这些代码在 android 4.4 上时,表面上没有任何显示(实际上我可以偶尔看到相同的图片片段,但大多数时候,表面只是黑色)。
我尝试用从文件中获取的数据填充输入缓冲区(使用 MediaExtractor),它在 android 5.0 和 4.4 上运行良好。
如有任何帮助,我们将不胜感激。
看来问题出在获取数据的方式上。我曾经 get
来自原生层的数据:
public static native byte[] getVideoPacket();
现在我 push
数据从本机层到 java 层:
env->CallVoidMethod(..., data);
现在一切正常。我不知道为什么,但这种方式对我有用。