加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何使用ffmpeg以msec搜索?

发布时间:2020-12-16 07:04:36 所属栏目:百科 来源:网络整理
导读:我试图用ffmpeg在毫秒内搜索视频.我一直在尝试使用 this question中的代码,该代码使用avformat_seek_file(我使用-1代表流号和AVSEEK_FLAG_ANY标志). 在调用之后,我尝试读取下一帧,即: if (av_read_frame(fmt_ctx,pkt) = 0){ int ret = 0; if (pkt.stream_in
我试图用ffmpeg在毫秒内搜索视频.我一直在尝试使用 this question中的代码,该代码使用avformat_seek_file(我使用-1代表流号和AVSEEK_FLAG_ANY标志).

在调用之后,我尝试读取下一帧,即:

if (av_read_frame(fmt_ctx,&pkt) >= 0)
{
    int ret = 0;

    if (pkt.stream_index == video_stream_idx) {
        /* decode video frame */
        ret = avcodec_decode_video2(video_dec_ctx,frame,got_frame,&pkt);
        if (ret < 0) {
            fprintf(stderr,"Error decoding video framen");
            return ret;
        }
//do something with frame
}

然而,检索帧的帧 – > pts总是保持在搜索之前读取的最后帧之后立即的帧的时间.

编辑:尽管frame-> pts形成了完整的序列,但确实会发生搜索.出于某些奇怪的原因,我读到的第一帧是第一帧.事实上,在我运行之后:

int got_frame = 0;
   do
   if (av_read_frame(fmt_ctx,&pkt) >= 0) {
       decode_packet_ro(&got_frame,0);
       av_free_packet(&pkt);
   }
   else
   {
       read_cache = true;
       pkt.data = NULL;
       pkt.size = 0;
       break;
   }
   while(!got_frame || this->frame->pts*av_q2d(video_dec_ctx->time_base) * 1000 < tsms);

我读的下一帧始终是第一帧.

解决方法

最后,我能够使用以下代码寻求:

/*!
 * brief ffmpeg_reader::seekMs seek to millisecond
 * param tsms timestamp
 * return success of seeking
 */
bool ffmpeg_reader::seekFrame(int s_frame)
{
    if (!isOk())
        return false;

   printf("t avformat_seek_file to %dn",s_frame);
   int flags = AVSEEK_FLAG_FRAME;
   if (s_frame < this->frame->pkt_dts)
   {
       flags |= AVSEEK_FLAG_BACKWARD;
   }

   if(av_seek_frame(fmt_ctx,video_stream_idx,s_frame,flags))
   {
       printf("nFailed to seek for time %d",s_frame);
      return false;
   }

   avcodec_flush_buffers(video_dec_ctx);
   /*read frame without converting it*/
   int got_frame = 0;
   do
   if (av_read_frame(fmt_ctx,&pkt) == 0) {
       decode_packet(&got_frame,false);
       av_free_packet(&pkt);
   }
   else
   {
       read_cache = true;
       pkt.data = NULL;
       pkt.size = 0;
       break;
   }
   while(!(got_frame && this->frame->pkt_dts >= s_frame));
   return true;
}

我自己并没有想出来,但我(遗憾地)不记得信用到期的地方.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读