如何在FFmpeg C / C ++中寻找 [英] How to seek in FFmpeg C/C++

查看:124
本文介绍了如何在FFmpeg C / C ++中寻找的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人知道如何在FFmpeg中实现秒(或毫秒)的搜索。我目前正在使用av_read_frame()运行通过视频的帧的循环,我想确定这个帧应该在几秒钟内。如果它到达某一点,那么我想寻求一个稍后的视频。顺便说一下,它不是视频播放器,只是处理帧。我听说我应该能够从数据包中获取dts或pts,但是它始终返回0。

解决方案

注意:这是过时,它仍然可以工作,但现在有 av_seek_frame( ) 正式进行。



我没有写这个,但是这里是一些样本的代码, p>

  bool seekMs(int tsms)
{
// printf(**** SEEK TO ms% d。LLT:%d。LT:%d。LLF:%d。LF:%d。LastFrameOk:%d\\\
,tsms,LastLastFrameTime,LastFrameTime,LastLastFrameNumber,LastFrameNumber,(int)LastFrameOk);

//将时间转换为帧号
DesiredFrameNumber = ffmpeg :: av_rescale(tsms,pFormatCtx-> streams [videoStream] - > time_base.den,pFormatCtx-> streams [videoStream ] - GT; time_base.num);
DesiredFrameNumber / = 1000;

return seekFrame(DesiredFrameNumber);
}

bool seekFrame(ffmpeg :: int64_t frame)
{

// printf(**** seekFrame to%d。LLT :%d。LT:%d。LLF:%d。LF:%d。LastFrameOk:%d\\\
,(int)frame,LastLastFrameTime,LastFrameTime,LastLastFrameNumber,LastFrameNumber,(int)LastFrameOk);

//寻求如果:
// - 我们不知道我们在哪里(Ok = false)
// - 我们知道我们在哪里,但
// - 所需的帧是在最后一个解码帧之后(可以进行优化):如果距离很小,调用decodeSeekFrame可能比从最后一个关键帧寻求更快)
// - 所需的帧较小或等于上一个解码帧的前一个。等于因为如果frame == LastLastFrameNumber,我们不想要LastFrame,而是之前的>我们需要寻找
if((LastFrameOk == false)||((LastFrameOk == true)& &(frame< = LastLastFrameNumber || frame> LastFrameNumber)))
{
// printf(\t avformat_seek_file\\\
);
if(ffmpeg :: avformat_seek_file(pFormatCtx,videoStream,0,frame,frame,AVSEEK_FLAG_FRAME)< 0)
return false;

avcodec_flush_buffers(pCodecCtx);

DesiredFrameNumber = frame;
LastFrameOk = false;
}
// printf(\t decodeSeekFrame\\\
);

return decodeSeekFrame(frame);

返回true;
}


Does anyone know how to implement seeking by seconds (or milliseconds) in FFmpeg. I currently have a loop running through the frames of a video using av_read_frame() and I want to determine what time this frame should be at in seconds. If it gets to a certain point then I want to seek to a later point in the video. By the way it is not a video player, just processing the frames. Ive heard I should be able to get the dts or pts from the packet but its always returning 0.

解决方案

NOTE: This is out of date, it should still work but there is now av_seek_frame() to do it officially.

I didn't write this but here is some code from a sample I have

bool seekMs(int tsms)
{
   //printf("**** SEEK TO ms %d. LLT: %d. LT: %d. LLF: %d. LF: %d. LastFrameOk: %d\n",tsms,LastLastFrameTime,LastFrameTime,LastLastFrameNumber,LastFrameNumber,(int)LastFrameOk);

   // Convert time into frame number
   DesiredFrameNumber = ffmpeg::av_rescale(tsms,pFormatCtx->streams[videoStream]->time_base.den,pFormatCtx->streams[videoStream]->time_base.num);
   DesiredFrameNumber/=1000;

   return seekFrame(DesiredFrameNumber);
}

bool seekFrame(ffmpeg::int64_t frame)
{

   //printf("**** seekFrame to %d. LLT: %d. LT: %d. LLF: %d. LF: %d. LastFrameOk: %d\n",(int)frame,LastLastFrameTime,LastFrameTime,LastLastFrameNumber,LastFrameNumber,(int)LastFrameOk);

   // Seek if:
   // - we don't know where we are (Ok=false)
   // - we know where we are but:
   //    - the desired frame is after the last decoded frame (this could be optimized: if the distance is small, calling decodeSeekFrame may be faster than seeking from the last key frame)
   //    - the desired frame is smaller or equal than the previous to the last decoded frame. Equal because if frame==LastLastFrameNumber we don't want the LastFrame, but the one before->we need to seek there
   if( (LastFrameOk==false) || ((LastFrameOk==true) && (frame<=LastLastFrameNumber || frame>LastFrameNumber) ) )
   {
      //printf("\t avformat_seek_file\n");
      if(ffmpeg::avformat_seek_file(pFormatCtx,videoStream,0,frame,frame,AVSEEK_FLAG_FRAME)<0)
         return false;

      avcodec_flush_buffers(pCodecCtx);

      DesiredFrameNumber = frame;
      LastFrameOk=false;
   }
   //printf("\t decodeSeekFrame\n");

   return decodeSeekFrame(frame);

   return true;
}

这篇关于如何在FFmpeg C / C ++中寻找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆