} else {
#ifdef HAVE_SRT
// SRT socket, already opened.
- AVInputFormat *mpegts_fmt = av_find_input_format("mpegts");
+ const AVInputFormat *mpegts_fmt = av_find_input_format("mpegts");
format_ctx = avformat_open_input_unique(&FFmpegCapture::read_srt_thunk, this,
mpegts_fmt, /*options=*/nullptr,
AVIOInterruptCB{ &FFmpegCapture::interrupt_cb_thunk, this });
// Open video decoder.
const AVCodecParameters *video_codecpar = format_ctx->streams[video_stream_index]->codecpar;
- AVCodec *video_codec = avcodec_find_decoder(video_codecpar->codec_id);
+ const AVCodec *video_codec = avcodec_find_decoder(video_codecpar->codec_id);
video_timebase = format_ctx->streams[video_stream_index]->time_base;
AVCodecContextWithDeleter video_codec_ctx = avcodec_alloc_context3_unique(nullptr);
fprintf(stderr, "%s: Cannot fill audio codec parameters\n", pathname.c_str());
return false;
}
- AVCodec *audio_codec = avcodec_find_decoder(audio_codecpar->codec_id);
+ const AVCodec *audio_codec = avcodec_find_decoder(audio_codecpar->codec_id);
if (audio_codec == nullptr) {
fprintf(stderr, "%s: Cannot find audio decoder\n", pathname.c_str());
return false;
// Main loop.
bool first_frame = true;
+ int consecutive_errors = 0;
while (!producer_thread_should_quit.should_quit()) {
if (process_queued_commands(format_ctx.get(), pathname, last_modified, /*rewound=*/nullptr)) {
return true;
AVFrameWithDeleter frame = decode_frame(format_ctx.get(), video_codec_ctx.get(), audio_codec_ctx.get(),
pathname, video_stream_index, audio_stream_index, subtitle_stream_index, audio_frame.get(), &audio_format, &audio_pts, &error);
if (error) {
- return false;
+ if (++consecutive_errors >= 100) {
+ fprintf(stderr, "More than 100 consecutive video frames, aborting playback.\n");
+ return false;
+ } else {
+ continue;
+ }
+ } else {
+ consecutive_errors = 0;
}
if (frame == nullptr) {
// EOF. Loop back to the start if we can.
1e3 * duration<double>(now - next_frame_start).count());
pts_origin = frame->pts;
start = next_frame_start = now;
- timecode += MAX_FPS * 2 + 1;
+ timecode += TYPICAL_FPS * 2 + 1;
}
}
bool finished_wakeup;
// Make sure to get the audio resampler reset. (This is a hack;
// ideally, the frame callback should just accept a way to signal
// audio discontinuity.)
- timecode += MAX_FPS * 2 + 1;
+ timecode += TYPICAL_FPS * 2 + 1;
}
last_neutral_color = get_neutral_color(frame->metadata);
if (frame_callback != nullptr) {