我正在使用JavaCPP av_read_packet从H264(MPEG4 AVC)源读取AVPackets,然后我试图仅将视频数据包传递给Android的MediaCodec来解码它们并渲染到Surface(用于显示)。 我已经读过,当你使用AVC源与MediaCodec兼容时,使用av_bitstream_filter_filter和h264_mp4toannexb过滤器是必要的。
问题是dequeueOutputBuffer总是返回-1,我不知道问题是在使用过滤器时还是其他任何原因。
这是代码片段:
bsfc = new AVBitStreamFilterContext();
bsfc = av_bitstream_filter_init("h264_mp4toannexb");
public void FilterPacket(AVPacket paquete){
IntPointer size_pointer = new IntPointer(1);
size_pointer.put(paquete.size());
BytePointer data = new BytePointer();
int sal = av_bitstream_filter_filter(bsfc, video_codec, (BytePointer)null, data, size_pointer, paquete.data(), paquete.size(), paquete.flags() & AV_PKT_FLAG_KEY );
paquete.size(size_pointer.get());
paquete.data(data);
}
这就是解码循环中的内容:
public void DecoderLoop(AVPacket paquete){
int inputBufferIndex = decoder.dequeueInputBuffer(5000);
if (inputBufferIndex >= 0) {
ByteBuffer bufferSalida = inputBuffers[inputBufferIndex];
FilterPacket(paquete);
bufferSalida.put(paquete.data().asByteBuffer());
//double presentationTemp = (double)(paquete.pts()/paquete.duration()) * (1000000/30);
//long presentationTime = (long)presentationTemp;
decoder.queueInputBuffer(inputBufferIndex, 0, paquete.size(), 0, 0);
}
int outputBufferIndex = decoder.dequeueOutputBuffer(info, 10000);
if (outputBufferIndex >= 0) {
// outputBuffer is ready to be processed or rendered.
decoder.releaseOutputBuffer(outputBufferIndex, true);
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = decoder.getOutputBuffers();
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
format = decoder.getOutputFormat();
}
}
dequeueInputBuffer返回一个正值,av_bitstream_filter_filter返回1(但我不知道它是否正常工作),但dequeueOutputBuffers总是返回-1。任何人都可以帮我解决问题吗?
我怀疑问题可能出现在以下问题之一:
av_bitstream_filter_filter
bufferSalida.put(paquete.data()asByteBuffer());我可以用这些方式吗?
如果我使用.asByteBuffer,我可以使用paquete.size(),还是可以使用不同的东西?
非常感谢
答案 0 :(得分:0)
我不熟悉libavcodec库的这个JavaCPP包装,但除了普通的AVPackets之外,你还需要AVCodecContext.extradata(在初始化比特流过滤器之后,以及在过滤第一个数据包之后)。您需要在传递给配置的输入MediaFormat中将extradata中的数据作为ByteBuffer传递,名称为“csd-0”,或者在发送第一个AVPacket之前将其作为具有BUFFER_FLAG_CODEC_CONFIG的单独缓冲区传递。