我正在尝试在管道中开发以下模块:
[Receive data on Socket]
|
buffer1
|
v
[Async Decode Frame]
|
buffer2
|
v
[Async Render to FBO-Texture-pair]
|
buffer3
|
v
[Display_on_screen]
*图例:[]表示模块,缓冲区*表示中间缓冲区
我知道这是一种特殊的用例,但是我使用内存池概念来管理不同缓冲区中的缓冲区对象,以避免内存分配并提高性能。
为实现[异步解码帧],我研究了Android MediaCodec Asynchronous Decoder examples,下面我指的是一个带有问题(Q1)内联注释的问题。
假设以下代码段是[异步解码帧]线程的一部分:
MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
@Override
void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
@Override
void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is equivalent to mOutputFormat
// outputBuffer is ready to be processed or rendered.
// Q1. Will this logic work and efficient?
// send outputBuffer to [Async-Render to FBO-Texture-pair] handler
// when done, send message to DecoderThreadHandler/[Async Decode Frame] to release outputBufferId
}
@Override
void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
mOutputFormat = format; // option B
}
@Override
void onError(…) {
…
}
});
codec.configure(format, …);
mOutputFormat = codec.getOutputFormat(); // option B
codec.start();
// wait for processing to complete
codec.stop();
codec.release();
问题
codec.releaseOutputBuffer(outputBufferId, ...)
回调中调用onOutputBufferAvailable()
来避免渲染到Surface。这样做的主要原因是我可能无法渲染所有解码的帧,因为我可能会丢弃一些解码的帧,并将相应的对象释放回相应的内存池。避免渲染到Surface的另一个原因在in this link中进行了说明,这表明如果解码线程运行得太快,我的渲染线程可能会无意间跳过某些帧。这种方法会行得通吗?任何建议都值得赞赏。让我知道是否需要进一步澄清。