|
@@ -3411,7 +3411,27 @@ static int read_thread(void *arg)
|
|
|
|
|
|
|
|
ffp_toggle_buffering(ffp, 1);
|
|
ffp_toggle_buffering(ffp, 1);
|
|
|
ffp_notify_msg3(ffp, FFP_MSG_BUFFERING_UPDATE, 0, 0);
|
|
ffp_notify_msg3(ffp, FFP_MSG_BUFFERING_UPDATE, 0, 0);
|
|
|
- ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Workaround for ASF/WMA seek crash (FFmpeg ff_seek_frame_binary uninitialized variable issue)
|
|
|
|
|
+ // See: https://ffmpeg.org/pipermail/ffmpeg-cvslog/2024-April/142447.html
|
|
|
|
|
+ // For ASF format, use AVSEEK_FLAG_BACKWARD to avoid triggering binary seek with uninitialized pos_min/pos_max
|
|
|
|
|
+ int seek_flags = is->seek_flags;
|
|
|
|
|
+ int is_asf_format = (ic->iformat && ic->iformat->name && !strcmp(ic->iformat->name, "asf"));
|
|
|
|
|
+ if (is_asf_format) {
|
|
|
|
|
+ seek_flags |= AVSEEK_FLAG_BACKWARD;
|
|
|
|
|
+ av_log(ffp, AV_LOG_DEBUG, "ASF format detected, using AVSEEK_FLAG_BACKWARD for seek\n");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, seek_flags);
|
|
|
|
|
+
|
|
|
|
|
+ // Fallback for ASF format: if seek failed, try with audio stream index
|
|
|
|
|
+ if (ret < 0 && is_asf_format && is->audio_stream >= 0) {
|
|
|
|
|
+ av_log(ffp, AV_LOG_WARNING, "ASF seek failed, trying fallback with audio stream index\n");
|
|
|
|
|
+ // Convert seek_target from AV_TIME_BASE to audio stream time_base
|
|
|
|
|
+ int64_t seek_ts = av_rescale_q(seek_target, AV_TIME_BASE_Q, is->audio_st->time_base);
|
|
|
|
|
+ ret = av_seek_frame(is->ic, is->audio_stream, seek_ts, seek_flags | AVSEEK_FLAG_ANY);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
|
av_log(NULL, AV_LOG_ERROR,
|
|
av_log(NULL, AV_LOG_ERROR,
|
|
|
"%s: error while seeking\n", is->ic->filename);
|
|
"%s: error while seeking\n", is->ic->filename);
|