P A*_*tar 3 ffmpeg fluent-ffmpeg
int64_t timeBase;
timeBase = (int64_t(pavStrm-> time_base.num) * AV_TIME_BASE) / int64_t(pavStrm->time_base.den);
int64_t seekTarget = int64_t(iFrameNumber) * timeBase;
av_seek_frame(fmt_ctx, -1, seekTarget, AVSEEK_FLAG_FRAME);
Run Code Online (Sandbox Code Playgroud)
在这里,我想在iFrameNumebr之后阅读下一个5帧
for(int iCnt = 0; iCnt <= 4; iCnt++)
{
iRet = av_read_frame(fmt_ctx, &pkt);
do
{
ret = decode_packet(&got_frame, 0);
if (ret < 0)
break;
pkt.data += ret;
pkt.size -= ret;
}while (pkt.size > 0);
av_free_packet(&pkt);
}
static int decode_packet(int *got_frame, int cached)
{
int ret = 0;
int decoded = pkt.size;
*got_frame = 0;
if (pkt.stream_index == video_stream_idx)
{
/* decode video frame */
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
}
Run Code Online (Sandbox Code Playgroud)
当我使用AVSEEK_FLAG_BACKWARD时它返回5个数据包和5个帧前两个是空白但是正确的.
当我使用AVSEEK_FLAG_FRAME时,它返回5个数据包和3帧,这不是前3帧,它从视频返回特定帧.
对于任何iFrameNumber
所以,请帮助我如何获得框架,同时具有帧号和av_seek_frame()的seektarget第3个参数的确切值
将帧转换为rgb24格式时也有问题
hal*_*elf 13
我认为av_seek_frame()是最常见但难以理解的功能之一,也没有很好的评论.
如果AVSEEK_FLAG_FRAME设置了标志,则第三个参数应该是您要搜索的帧编号,这样您就可以了.
让我们看一个例子来更好地理解av_seek_frame():
假设我有一个10帧的视频,fps = 10.第一帧和第五帧是关键帧(I Frame或intra frame).其他是某些格式的P帧甚至B帧.
0 1 2 3 4 5 6 7 8 9(帧号)
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9(时基)
av_seek_frame(fmt_ctx, -1, 2, AVSEEK_FLAG_FRAME);
av_seek_frame(fmt_ctx, -1, 0.15, 0);
// These will seek to the fifth frame. Cause `AVSEEK_FLAG_ANY` is not given. Seeking to the next key frame after third parameter.
av_seek_frame(fmt_ctx, -1, 2, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_ANY);
// This will seek to exactly the third parameter specified. But probably only a frame with no actual meaning. (We can't get a meaningful image if no related I/P/B frames given.)
av_seek_frame(fmt_ctx, -1, 0.15, AVSEEK_FLAG_ANY);
// Seek to 0.2. Nothing interesting as above.
av_seek_frame(fmt_ctx, -1, 0.15, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
// Seek to 0.1. Also nothing interesting.
av_seek_frame(fmt_ctx, -1, 2, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD);
// Got the first frame. Seeking to the nearest key frame before the third parameter.
Run Code Online (Sandbox Code Playgroud)
所以,如果我想获得任意帧,通常AVSEEK_FLAG_BACKWARD首先寻找,像往常一样解码.然后检查前几个数据包的持续时间,看看我们是否需要删除它们.
int64_t FrameToPts(AVStream* pavStream, int frame) const
{
return (int64_t(frame) * pavStream->r_frame_rate.den * pavStream-
>time_base.den) /
(int64_t(pavStream->r_frame_rate.num) *
pavStream->time_base.num);
}
iSeekTarget = FrameToPts(m_pAVVideoStream, max(0, lFrame));
iSuccess = av_seek_frame(m_pAVFmtCtx, m_iVideo_Stream_idx,
iSeekTarget, iSeekFlag);
AVPacket avPacket;
iRet = av_read_frame(m_pAVFmtCtx, &avPacket);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6170 次 |
| 最近记录: |