diff --git a/src/ui/Logic/VideoPlayers/Ffmpeg/FfmpegPlayer.cs b/src/ui/Logic/VideoPlayers/Ffmpeg/FfmpegPlayer.cs index 9d9e4deda3..01a5ee9c5f 100644 --- a/src/ui/Logic/VideoPlayers/Ffmpeg/FfmpegPlayer.cs +++ b/src/ui/Logic/VideoPlayers/Ffmpeg/FfmpegPlayer.cs @@ -1162,7 +1162,7 @@ private static bool SupportsHardwareDevice(AVCodec* decoder, AVHWDeviceType devi /// is attached; the caller can tell by hw_device_ctx being set. Any hardware setup /// failure silently means software. /// - private AVCodecContext* OpenDecoder(AVStream* stream, bool hardware = false) + private AVCodecContext* OpenDecoder(AVStream* stream, bool hardware = false, int hardwareStartIndex = 0) { var decoder = ffmpeg.avcodec_find_decoder(stream->codecpar->codec_id); if (decoder == null) @@ -1186,10 +1186,12 @@ private static bool SupportsHardwareDevice(AVCodec* decoder, AVHWDeviceType devi codec->pkt_timebase = stream->time_base; codec->thread_count = 0; // auto + var selectedHardwareIndex = -1; if (hardware && stream->codecpar->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO) { - foreach (var deviceType in HardwareDeviceTypes) + for (var i = hardwareStartIndex; i < HardwareDeviceTypes.Length; i++) { + var deviceType = HardwareDeviceTypes[i]; if (!SupportsHardwareDevice(decoder, deviceType)) { continue; @@ -1212,6 +1214,7 @@ private static bool SupportsHardwareDevice(AVCodec* decoder, AVHWDeviceType devi codec->hw_device_ctx = device; // freed with the codec context codec->get_format = GetHardwareFormatDelegate; + selectedHardwareIndex = i; break; } } @@ -1219,6 +1222,14 @@ private static bool SupportsHardwareDevice(AVCodec* decoder, AVHWDeviceType devi result = ffmpeg.avcodec_open2(codec, decoder, null); if (result < 0) { + if (hardware && selectedHardwareIndex >= 0) + { + var deviceName = HardwareDeviceName(codec); + Se.LogError($"ffmpeg player: {deviceName} decoder open failed for {ffmpeg.avcodec_get_name(stream->codecpar->codec_id)} ({FfmpegLibraries.ErrorText(result)}), trying the next hardware decoder or software"); + ffmpeg.avcodec_free_context(&codec); + return OpenDecoder(stream, hardware: true, hardwareStartIndex: selectedHardwareIndex + 1); + } + ffmpeg.avcodec_free_context(&codec); throw new InvalidOperationException($"avcodec_open2: {FfmpegLibraries.ErrorText(result)}"); }