Skip to content

Commit b3b504d

Browse files
committed
vcomp/file: do not run avio_seek normally
Prior to the commit 9891f19 (HEAD~3) avio_seek was called prior to avformat_seek_file. This worked fine for normal containers (eg. MP4). But after this was swapped, avio_seek after that broke that. In order to work properly, run avio_seek() just if avformat_seek_file fails (fixes temporarily broken .mp4 loop). Only case remaining is JPEG/MJPEG file loop, which returns 0 for the avformat_seek_file() call. This is handled ad hoc (I don't have any better solution now).
1 parent 8c19440 commit b3b504d

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

src/video_capture/file.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,16 @@ static void print_current_pos(struct vidcap_state_lavf_decoder *s,
348348
s->last_stream_stat = t;
349349
}
350350

351-
#define CHECK_FF(cmd, action_failed) do { int rc = cmd; if (rc < 0) { char buf[1024]; av_strerror(rc, buf, 1024); log_msg(LOG_LEVEL_ERROR, MOD_NAME #cmd ": %s\n", buf); action_failed} } while(0)
351+
#define CHECK_FF(cmd, action_failed) \
352+
do { \
353+
int rc = cmd; \
354+
if (rc < 0) { \
355+
char buf[1024]; \
356+
av_strerror(rc, buf, 1024); \
357+
log_msg(LOG_LEVEL_ERROR, MOD_NAME #cmd ": %s\n", buf); \
358+
action_failed; \
359+
} \
360+
} while (0)
352361
static void vidcap_file_process_messages(struct vidcap_state_lavf_decoder *s) {
353362
struct msg_universal *msg;
354363
while ((msg = (struct msg_universal *) check_message(&s->mod)) != NULL) {
@@ -470,13 +479,22 @@ static void print_packet_info(const AVPacket *pkt, const AVStream *st) {
470479
static void
471480
rewind_file(struct vidcap_state_lavf_decoder *s)
472481
{
482+
bool avseek_failed = false;
473483
CHECK_FF(avformat_seek_file(s->fmt_ctx, -1, INT64_MIN,
474484
s->fmt_ctx->start_time, INT64_MAX, 0),
475-
{});
476-
// handle single JPEG loop, inspired by libavformat's seek_frame_generic
477-
// because img_read_seek (AVInputFormat::read_seek) doesn't do the job -
478-
// seeking is inmplemeted just in img2dec if VideoDemuxData::loop == 1
479-
CHECK_FF(avio_seek(s->fmt_ctx->pb, s->video_stream_idx, SEEK_SET), {});
485+
avseek_failed = true);
486+
const bool mjpeg = s->vid_ctx->codec_id == AV_CODEC_ID_MJPEG &&
487+
s->fmt_ctx->ctx_flags & AVFMTCTX_NOHEADER;
488+
if (avseek_failed || mjpeg) {
489+
// handle single JPEG loop, inspired by libavformat's
490+
// seek_frame_generic because img_read_seek
491+
// (AVInputFormat::read_seek) doesn't do the job - seeking is
492+
// inmplemeted just in img2dec if VideoDemuxData::loop == 1
493+
// used also for AnnexB HEVC stream (avformat_seek_file fails)
494+
CHECK_FF(
495+
avio_seek(s->fmt_ctx->pb, s->video_stream_idx, SEEK_SET),
496+
{});
497+
}
480498
flush_captured_data(s);
481499
}
482500

0 commit comments

Comments
 (0)