![](/img/trans.png)
[英]Unable to encode single frame h264 (.mp4) video with FFmpeg. No video stream present
[英]Seeking to video frame of h264 codec in mp4 container with FFmpeg. Packet pts is always 0
我正在尝试使用FFmpeg搜索到特定帧的最近关键帧,但是无论何时我在搜索后使用av_read_frame获取下一帧时,数据包pts或dts始终为0。这仅适用于h264 / mp4视频,因为它可以正常工作.avi容器中的一些编解码器。
我尝试使用avformat_seek_file和av_seek_frame,但它们给我相同的结果。
我还读到我不应该从数据包中读取时间戳,因此我尝试首先使用avcodec_decode_video2解码数据包并读取AVFrame-> pts信息,但是此值对于h264 / mp4视频始终无效。
这是我正在尝试执行的相关代码:
/*Relevant from header*/
AVCodecContext pCodecCtx;
AVFormatContext *pFormatCtx;
int videoStreamIndex;
int Class::getFrame(int desiredFrame, bool seek)
if(seek)
{
/* We seek to the selected frame */
if(avformat_seek_file(pFormatCtx, videoStreamIndex, 0, desiredFrame, desiredFrame, AVSEEK_FLAG_BACKWARD) < 0)
//if(av_seek_frame(pFormatCtx, mVideoStream, desiredFrame, AVSEEK_FLAG_BACKWARD) < 0)
{
// error management
}
avcodec_flush_buffers(pCodecCtx);
}
AVPacket packet;
int frameFinished;
/* Loop until we find the next video frame */
while(av_read_frame(pFormatCtx, &packet) >= 0 )
{
if(packet.stream_index == videoStreamIndex)
{
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
int pcktPts;
/*** management of other codecs here using av_frame_get_best_effort_timestamp() ***/
/* With this approach I have been getting correct pts info after many av_read_frame loops */
if(pCodecCtx->codec->id == AV_CODEC_ID_H264 && videoPath.toLower().endsWith(".mp4"))
{
pcktPts = av_rescale_q(packet.pts, //pFrame->pts always invalid here
pFormatCtx->streams[videoStreamIndex]->time_base,
pFormatCtx->streams[videoStreamIndex]->codec->time_base);
pcktPts = (pcktPts/pCodecCtx->ticks_per_frame);
}
if(pcktPts == desiredFrame) ....
/* more irrelevant code for reading, converting frame, etc */
也许我处理这种编解码器不正确,任何想法都会受到高度赞赏。
注意,我只对视频帧感兴趣。
好吧,我想我得到了一些东西。
似乎avformat_seek_file实际上想要您要查找的数据包的pts,而不是帧数,因此,由于我使用av_rescale_q将数据包pts转换为实际的帧号,我以为我必须执行相反的操作才能转换所需的数据包帧数到包点数。
现在在寻找之前,我像这样变换所需的帧号:
int target = desiredFrame *
(pFormatCtx->streams[videoStreamIndex]->time_base.den /
pFormatCtx->streams[videoStreamIndex]->time_base.num) /
(pFormatCtx->streams[videoStreamIndex]->codec->time_base.den /
pFormatCtx->streams[videoStreamIndex]->codec->time_base.num )*
pCodecCtx->ticks_per_frame;
目前,这似乎可以正常工作。 我仍然会提出任何建议,因为这是我想到的第一个解决方案,可能有点天真,我不确定它是否适用于所有情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.