2013-07-09 29 views
12

我正在寫一個視頻編輯器,我需要尋求確切的幀,知道幀號我如何尋求用ffmpeg來編號X?

在stackoverflow上的其他帖子告訴我,ffmpeg可能會給我一些後,尋找破碎的幀,這不是一個播放問題,但對視頻編輯的一個大問題。

我需要通過幀數,不受時間,轉換爲幀數時將變得不準確尋求

我讀過dranger的TUTS(現在已經過時),並結了:

av_seek_frame(fmt_ctx, video_stream_id, frame, AVSEEK_FLAG_ANY); 

它總是設法框架No. 0,始終return 0,這意味着成功。 然後我嘗試閱讀Blender的源代碼,發現它非常複雜(也許我應該實現一個圖像緩衝區?)。

那麼,有沒有簡單的方法尋求一個簡單的電話,如seek(context, frame_number)(同時得到一個完整的框架,而不是一個破碎的一個)?或者,有沒有簡化這個的輕量級庫?

編輯: 由於praks411,我找到了解決辦法:

void AV_seek(AV * av, size_t frame) 
{ 
    int frame_delta = frame - av->frame_id; 
    if (frame_delta < 0 || frame_delta > 5) 
     av_seek_frame(av->fmt_ctx, av->video_stream_id, 
       frame, AVSEEK_FLAG_BACKWARD); 
    while (av->frame_id != frame) 
     AV_read_frame(av); 
} 

void AV_read_frame(AV * av) 
{ 
    AVPacket packet; 
    int frame_done; 

    while (av_read_frame(av->fmt_ctx, &packet) >= 0) { 
     if (packet.stream_index == av->video_stream_id) { 
      avcodec_decode_video2(av->codec_ctx, av->frame, &frame_done, &packet); 
      if (frame_done) { 
       ... 
       av->frame_id = packet.dts; 
       av_free_packet(&packet); 
       return; 
      } 
     } 
     av_free_packet(&packet); 
    } 
} 
+0

你保證一個固定的穩定的FPS?然後你可以按時間尋找。另見僅用戶知道的關於「關鍵幀」 – rogerdpack

+0

的討論。它可能是一個可變幀頻視頻。 – Giumo

回答

6

av_seek_frame只會尋求基於時間戳的關鍵幀。既然它尋求關鍵幀,你可能得不到你想要的。因此,建議尋求最近的關鍵幀,然後逐幀閱讀,以達到所需的幀。然而,如果你正在處理固定的FPS值,那麼你可以很容易地將時間戳映射到幀索引。

在尋求之前,如果您指定了流,則需要將您的時間轉換爲AVStream.time_base單位。請閱讀avformat.h中的av_seek_frame的ffmpeg文檔。

例如,如果你想尋求1.23秒剪輯:

double m_out_start_time = 1.23; 
int flgs = AVSEEK_FLAG_ANY; 
int seek_ts = (m_out_start_time*(m_in_vid_strm->time_base.den))/(m_in_vid_strm->time_base.num); 
if(av_seek_frame(m_informat, m_in_vid_strm_idx,seek_ts, flgs) < 0) 
{ 
    PRINT_MSG("Failed to seek Video ") 
} 
+1

呵呵,我終於知道這個文件是在頭文件中的,難怪我在網上找不到任何東西。 – Giumo

+0

然後,我怎麼知道最近的關鍵幀在哪裏? – Giumo

+0

是不是time_base.den/time_base.num fps?是不是seek_ts = time * fps的幀數? – Giumo