如果您是新手并且“只想在 SW 中做”,那么就不要在 SW 中做。我假设您的算法不需要是实时的,并且可以即时压缩视频数据,或者您需要使用硬件编解码器。
这是来自Android MediaCodec 参考
MediaCodec codec = MediaCodec.createDecoderByType(type);
codec.configure(format, ...);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
for (;;) {
int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferIndex >= 0) {
// fill inputBuffers[inputBufferIndex] with valid data
...
codec.queueInputBuffer(inputBufferIndex, ...);
}
int outputBufferIndex = codec.dequeueOutputBuffer(timeoutUs);
if (outputBufferIndex >= 0) {
// outputBuffer is ready to be processed or rendered.
...
codec.releaseOutputBuffer(outputBufferIndex, ...);
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = codec.getOutputBuffers();
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
MediaFormat format = codec.getOutputFormat();
...
}
}
codec.stop();
codec.release();
codec = null;
在显示“// outputBuffer 已准备好进行处理或渲染”的行上应用您的编解码器。
那就是你的第一帧将是 outputBuffers[0] 到 outputBuffers[outputBufferIndex]。保存掉 outputBufferIndex,即 outputBufferIndex_old = outputBufferIndex; 那么你的下一帧将是 outputbuffers[outputBufferIndex_old] 到 outputbuffers[outputBufferIndex]。但这是一个循环缓冲区,所以在 for 循环中... ahhhhh
像这样的东西:
//init
int old = 0;
int len = codec.BufferInfo().size,buff_len=outputBuffers.size;
Byte[] processBuffer = new Byte[len];
... // outputBuffer ready
for (int i=old; i<old+len; i++){
processBuffer[i-old] = outputBuffers[i%buff_len];
}
old = outputBufferIndex;
这是一个很好的例子。您可能需要查看 MediaMetadataRetriever 以获取有关输入视频的信息。高度和宽度等。如果您希望编码器对不同类型的视频具有鲁棒性,则每像素字节大小。无论如何,这应该让你开始。
我强烈推荐使用 Matlab(或 GNU Octave)来制作视频编解码器的原型。它将为您节省大量时间。这意味着您应该确保您的预期编解码器算法有效,然后再尝试在几乎不可能的系统上实现它以进行调试,例如 Android。
希望这可以帮助。