是否可以使用 ffmpeg 无延迟地解码 MPEG4 帧?
Is it possible to decode MPEG4 frames without delay with ffmpeg?
我使用 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);
但正如我所说,这给了我第一个 gop 的人工制品。
使用“-flags +low_delay”选项(或在代码中,设置 AVCodecContext.flags |= CODEC_FLAG_LOW_DELAY)。
我测试了几个选项,“-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);
我使用 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);
但正如我所说,这给了我第一个 gop 的人工制品。
使用“-flags +low_delay”选项(或在代码中,设置 AVCodecContext.flags |= CODEC_FLAG_LOW_DELAY)。
我测试了几个选项,“-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);