stride3d/stride · error · ApplicationException
Couldn't transfer frame data from GPU to CPU
Error message
Couldn't transfer frame data from GPU to CPU
What it means
When a decoded frame lives in GPU memory (hardware decoding, detected via the frame format matching the codec's HardwarePixelFormat), it must be copied to CPU memory with av_hwframe_transfer_data into pCpuCopyFrame. This ApplicationException is thrown when that transfer returns a negative FFmpeg error code.
Solutions
- Fall back to software decoding (disable hardware decoding) if hw transfer repeatedly fails
- Verify GPU drivers are current and the device is stable (no TDR)
- Check the FFmpeg build supports the used hwaccel (e.g. d3d11va) correctly
- Log the FFmpeg error code (ffmpeg.Av_strerror) to identify the exact hw failure
Example fix
// before
ret = ffmpeg.av_hwframe_transfer_data(pCpuCopyFrame, pDecodedFrame, 0);
if (ret < 0)
throw new ApplicationException("Couldn't transfer frame data from GPU to CPU");
// after
ret = ffmpeg.av_hwframe_transfer_data(pCpuCopyFrame, pDecodedFrame, 0);
if (ret < 0)
{
var err = FFmpegUtils.Avw_strerror(ret);
throw new ApplicationException($"Couldn't transfer frame data from GPU to CPU: {err} (code {ret})");
} Defensive patterns
Strategy: try-catch
Validate before calling
// before extraction, verify hw device is alive gpuDevice.DeviceRemovedReason == SharpDX.Result.Ok.Code // or equivalent graphics-device health check
Try / catch
try { status = media.ExtractNextImage(...); }
catch (ApplicationException ex) when (ex.Message.Contains("GPU to CPU"))
{
// recreate media with software decoding fallback
media.Dispose(); media = CreateMedia(useHardwareDecoding: false);
} Prevention
- Keep GPU drivers updated; handle device-lost events
- Prefer software decoding where hw support is unreliable
- Log FFmpeg return codes for diagnosis
When it happens
Trigger: ExtractNextImage encounters a hardware-decoded frame and av_hwframe_transfer_data fails — e.g. the hardware device context was lost, the GPU frame is invalid, or the hw device (GPU removed, driver reset, device lost) is unavailable.
Common situations: GPU driver resets/TDR during video playback; using hardware pixel formats on platforms where the hw device failed to initialize; mismatched hwaccel configuration in the FFmpeg build.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Couldn't allocate a frame for hardware decoding.
- Could not fill codec parameters. Error code=
- Could not initialize the conversion context.
- Couldn't allocate a frame for decoding.
- Failed to compile a video asset. ffmpeg failed to convert
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/690c9878943de87f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs:400
// and feed it the next packet.
continue;
}
if (ret < 0)
{
Logger.Error($"Error while receiving frame. Error code={ret.ToString("X8")}");
Logger.Error(GetErrorMessage(ret));
// Might be a bad frame, ignore it.
return FrameExtractionStatus.Failed;
}
var frameSideData = ffmpeg.av_frame_get_side_data(pDecodedFrame, AVFrameSideDataType.AV_FRAME_DATA_STEREO3D);
if (pDecodedFrame->format == (int)streamInfo.Codec.HardwarePixelFormat)
{
// the frame is coming from the GPU
ret = ffmpeg.av_hwframe_transfer_data(pCpuCopyFrame, pDecodedFrame, 0);
if (ret < 0)
throw new ApplicationException("Couldn't transfer frame data from GPU to CPU");
pFrame = pCpuCopyFrame;
}
else
{
pFrame = pDecodedFrame;
}
var width = pCodecContext->width;
var height = pCodecContext->height;
var sourcePixFmt = (AVPixelFormat)pFrame->format;
pConvertContext = ffmpeg.sws_getCachedContext(pConvertContext, width, height, sourcePixFmt, width, height, DestinationPixelFormat, ffmpeg.SWS_FAST_BILINEAR, null, null, null);
if (pConvertContext == null)
throw new ApplicationException("Could not initialize the conversion context.");
ffmpeg.sws_scale(pConvertContext, pFrame->data, pFrame->linesize, 0, outputImage.Height, dstData, dstLinesize);
outputImage.Timestamp = pDecodedFrame->pts;
View on GitHub (pinned to 96fad776d2)