Я пишу видеоредактор, и мне нужно найти точный кадр, зная номер кадра.
В других сообщениях на stackoverflow мне говорилось, что ffmpeg может дать мне несколько битых кадров после поиска, что не является проблемой для воспроизведения, но является большой проблемой для видеоредакторов.
И мне нужно искать по номеру кадра, не по времени, которое станет неточным при преобразовании в номер кадра.
Я прочитал 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);
}
}
EDIT2: Оказывается, для этого есть библиотека: FFMS2. Это «исходная библиотека [...] на основе FFmpeg для легкого доступа с точностью до кадра» и переносимая (по крайней мере, в Windows и Linux).