我使用这个循环从FFMPEG的视频流中读取帧:
while(av_read_frame(pFormatCtx, &packet)>=0) {
// Is this a packet from the video stream?
if(packet.stream_index==videoStream) {
// Decode video frame
avcodec_decode_video2(pCodecCtx,pFrame,&frameFinished,&packet);
// Did we get a video frame?
if(frameFinished) {
sws_scale(img_convert_context ,pFrame->data,pFrame->linesize,0,
pCodecCtx->height, pFrameRGBA->data, pFrameRGBA->linesize);
printf("%s\n","Frame read finished ");
ExportFrame(pFrameRGBA->data[0]);
break;
}
}
// Save the frame to disk
}
printf("%s\n","Read next frame ");
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
因此以这种方式顺序读取流。我想要的是随机访问帧以便能够读取特定帧(按帧号)。它是如何完成的?
答案 0 :(得分:6)
你可能想要看
int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
int flags);
上面的api会在给出时间戳时寻找关键帧。寻求你可以阅读框架。此外,下面的教程还解释了位置和时间戳之间的转换。
答案 1 :(得分:2)
由于视频中的大多数帧依赖于前一帧和下一帧,因此通常,访问视频中的随机帧并不简单。但是,某些帧独立于任何其他帧进行编码,并在整个视频中定期出现。这些帧称为I帧。通过搜索来直接访问这些框架 。
如果您想“随机”访问视频中的任何帧,那么您必须:
你已经获得了第二点的代码,所以你需要做的就是照顾第一点,然后你就完成了。这是人们经常提到的Dranger教程的updated version - 它可能会有所帮助。