我使用 ffmpeg的MPEG4解码器。解码器具有 CODEC_CAP_DELAY 等功能。这意味着解码器将为我提供延迟为1帧的解码帧。
我有一组来自AVI文件的MPEG4(I-& P-)帧,并使用这些帧提供ffmpeg解码器。因为第一个I帧解码器什么都没给,但是成功解码了帧。我可以强制解码器通过第二次调用 avcodec_decode_video2 来获取解码帧并提供空值(刷新它),但如果我为每个帧执行此操作,我会得到第一组图片的伪像(例如第二个解码的P帧是灰色的。)
如果我现在不强制ffmpeg解码器给我解码帧,那么它可以完美无缺地工作。
问题: 但是有可能在没有给出解码器下一帧并且没有伪像的情况下获得解码帧吗?
如何为每个帧实现解码的小例子:
// decode
int got_frame = 0;
int err = 0;
int tries = 5;
do
{
err = avcodec_decode_video2(m_CodecContext, m_Frame, &got_frame, &m_Packet);
/* some codecs, such as MPEG, transmit the I and P frame with a
latency of one frame. You must do the following to have a
chance to get the last frame of the video */
m_Packet.data = NULL;
m_Packet.size = 0;
--tries;
}
while (err >= 0 && got_frame == 0 && tries > 0);
但正如我所说的那样,给了我第一个用途的文物。
答案 0 :(得分:4)
使用" -flags + low_delay"选项(或在代码中,设置AVCodecContext.flags | = CODEC_FLAG_LOW_DELAY)。
答案 1 :(得分:0)
我测试了几个选项,“-flags low_delay”和“-probesize 32”比其他选项更重要。波纹管代码对我有用。
AVDictionary* avDic = nullptr;
av_dict_set(&avDic, "flags", "low_delay", 0);
av_dict_set(&avDic, "probesize", "32", 0);
const int errorCode = avformat_open_input(&pFormatCtx, mUrl.c_str(), nullptr, &avDic);