stride3d/stride · critical · ApplicationException

Couldn't allocate a frame for hardware decoding.

Error message

Couldn't allocate a frame for hardware decoding.

What it means

FFmpegMedia.Open also allocates pCpuCopyFrame, used as the CPU-side target when frames come from GPU (hardware) decoding. This error is thrown when that second av_frame_alloc() returns null — same allocation failure mode but for the hardware-decode copy buffer.

Solutions

  1. Free memory or reduce concurrently open videos before calling Open
  2. Verify native FFmpeg binaries are intact and process is 64-bit
  3. Avoid unnecessary hardware-decoding setups if CPU copy frames cannot be allocated
  4. Wrap Open in try/catch for ApplicationException/OutOfMemoryException and retry once after cleanup

Example fix

// before
media.Open(url);
// after
try { media.Open(url); }
catch (ApplicationException ex) when (ex.Message.Contains("hardware decoding"))
{
    GC.Collect();
    media.Open(url); // retry after reclaiming memory
}
Defensive patterns

Strategy: try-catch

Validate before calling

FFmpegUtils.EnsurePlatformSupport();
GC.Collect(); // reduce memory pressure before opening large videos

Try / catch

try { media.Open(url); }
catch (ApplicationException ex) when (ex.Message.Contains("hardware decoding"))
{
    // free memory, optionally disable hw decoding, retry once
}

Prevention

When it happens

Trigger: Calling Open() on a media file when the process cannot allocate the second AVFrame (out of memory); commonly occurs when hardware decoding paths (e.g. D3D11VA) are exercised and an extra CPU copy frame must exist.

Common situations: Memory pressure while playing videos with hardware decoding; fragmented/native heap exhaustion in long-running game processes; opening many FFmpegMedia instances simultaneously.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/989bdf2bb2a263be. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs:165

            AVFormatContext = pFormatContext;
            Duration = TimeSpan.FromSeconds((double)AVFormatContext->duration / ffmpeg.AV_TIME_BASE);
            Url = url;

            // Get the streams
            for (int i = 0; i < pFormatContext->nb_streams; i++)
            {
                var stream = FFmpegStream.Create(pFormatContext->streams[i], this);
                streams.Add(stream);
            }

            pDecodedFrame = ffmpeg.av_frame_alloc();
            if (pDecodedFrame == null)
                throw new ApplicationException("Couldn't allocate a frame for decoding.");

            pCpuCopyFrame = ffmpeg.av_frame_alloc();
            if (pCpuCopyFrame == null)
                throw new ApplicationException("Couldn't allocate a frame for hardware decoding.");

            // dispose cached video image from previous file
            ClearStreamInfo();
        }

        public bool SeekToTime([NotNull] FFmpegStream stream, long timestamp)
        {
            FFmpegUtils.EnsurePlatformSupport();

            if (currentStreams.TryGetValue(stream, out var streamInfo))
            {
                // flush the codec buffered images
                streamInfo.Codec.Flush(pDecodedFrame);
            }

            // flush the format buffered images
            ffmpeg.avformat_flush(AVFormatContext);

View on GitHub (pinned to 96fad776d2)