2013-07-09 34 views
12

Tôi đang viết một biên tập video và tôi cần tìm khung chính xác, biết số khung .Làm thế nào tôi có thể tìm kiếm để khung số X với ffmpeg?

Các bài đăng khác trên stackoverflow nói với tôi rằng ffmpeg có thể cho tôi một vài khung hình bị hỏng sau khi tìm kiếm, đây không phải là vấn đề phát lại mà là một vấn đề lớn đối với trình chỉnh sửa video.

Và tôi cần tìm kiếm theo số khung, không theo thời gian, sẽ trở nên không chính xác khi được chuyển đổi thành số khung.

Tôi đã đọc tuts dranger (mà là lỗi thời bây giờ), và kết thúc với:

av_seek_frame(fmt_ctx, video_stream_id, frame, AVSEEK_FLAG_ANY); 

Nó luôn luôn tìm cách khung No. 0, và luôn luôn return 0 có nghĩa là thành công. Sau đó, tôi đã cố gắng đọc mã nguồn của Blender và thấy nó thực sự phức tạp (có lẽ tôi nên thực hiện một bộ đệm hình ảnh?).

Vì vậy, có cách nào đơn giản để tìm kiếm một khung hình chỉ với một cuộc gọi đơn giản như seek(context, frame_number) (trong khi nhận được một khung hình đầy đủ, không bị hỏng)? Hoặc, có thư viện nhẹ nào đơn giản hóa điều này không?

EDIT: Nhờ praks411, tôi thấy các giải pháp:

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

được bạn được bảo đảm một fps ổn định cố định? Sau đó, bạn có thể tìm kiếm theo thời gian. Xem thêm phần thảo luận về "key -frame" – rogerdpack

+0

chỉ người dùng mới biết. nó có thể là một video tốc độ khung hình biến đổi. – Giumo

Trả lời

6

av_seek_frame sẽ chỉ để tìm kiếm dựa trên dấu thời gian để các key-frame. Vì nó tìm kiếm keyframe, bạn có thể không nhận được những gì bạn muốn. Do đó nó được khuyến khích để tìm kiếm keyframe gần nhất và sau đó đọc khung bởi khung util bạn đạt đến khung mong muốn.

Tuy nhiên, nếu bạn đang xử lý giá trị FPS cố định, thì bạn có thể dễ dàng ánh xạ dấu thời gian tới chỉ mục khung.

Trước khi tìm kiếm, bạn sẽ cần chuyển đổi thời gian của mình thành AVStream.time_base đơn vị nếu bạn đã xác định luồng. Đọc tài liệu ffmpeg của av_seek_frame trong avformat.h.

Ví dụ, nếu bạn muốn tìm cách 1.23 giây của clip:

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

Ồ, và cuối cùng tôi biết tài liệu nằm trong các tệp tiêu đề, không có thắc mắc tôi không thể tìm thấy bất kỳ trực tuyến nào. – Giumo

+0

Sau đó, làm cách nào để biết khung chính gần nhất ở đâu? – Giumo

+0

Không phải là time_base.den/time_base.num fps? Không phải là seek_ts = thời gian * fps số khung? – Giumo

Các vấn đề liên quan