{"record":{"id":"690c9878943de87f","repo":"stride3d/stride","slug":"couldn-t-transfer-frame-data-from-gpu-to-cpu","errorCode":null,"errorMessage":"Couldn't transfer frame data from GPU to CPU","messagePattern":"Couldn't transfer frame data from GPU to CPU","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs","lineNumber":400,"sourceCode":"                        // and feed it the next packet.\n                        continue;\n                    }\n\n                    if (ret < 0)\n                    {\n                        Logger.Error($\"Error while receiving frame. Error code={ret.ToString(\"X8\")}\");\n                        Logger.Error(GetErrorMessage(ret));\n                        // Might be a bad frame, ignore it.\n                        return FrameExtractionStatus.Failed;\n                    }\n                    var frameSideData = ffmpeg.av_frame_get_side_data(pDecodedFrame, AVFrameSideDataType.AV_FRAME_DATA_STEREO3D);\n\n                    if (pDecodedFrame->format == (int)streamInfo.Codec.HardwarePixelFormat)\n                    {\n                        // the frame is coming from the GPU\n                        ret = ffmpeg.av_hwframe_transfer_data(pCpuCopyFrame, pDecodedFrame, 0);\n                        if (ret < 0)\n                            throw new ApplicationException(\"Couldn't transfer frame data from GPU to CPU\");\n\n                        pFrame = pCpuCopyFrame;\n                    }\n                    else\n                    {\n                        pFrame = pDecodedFrame;\n                    }\n\n                    var width = pCodecContext->width;\n                    var height = pCodecContext->height;\n                    var sourcePixFmt = (AVPixelFormat)pFrame->format;\n                    pConvertContext = ffmpeg.sws_getCachedContext(pConvertContext, width, height, sourcePixFmt, width, height, DestinationPixelFormat, ffmpeg.SWS_FAST_BILINEAR, null, null, null);\n                    if (pConvertContext == null)\n                        throw new ApplicationException(\"Could not initialize the conversion context.\");\n\n                    ffmpeg.sws_scale(pConvertContext, pFrame->data, pFrame->linesize, 0, outputImage.Height, dstData, dstLinesize);\n                    outputImage.Timestamp = pDecodedFrame->pts;\n","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs#L382-L418","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nret = ffmpeg.av_hwframe_transfer_data(pCpuCopyFrame, pDecodedFrame, 0);\nif (ret < 0)\n    throw new ApplicationException(\"Couldn't transfer frame data from GPU to CPU\");\n// after\nret = ffmpeg.av_hwframe_transfer_data(pCpuCopyFrame, pDecodedFrame, 0);\nif (ret < 0)\n{\n    var err = FFmpegUtils.Avw_strerror(ret);\n    throw new ApplicationException($\"Couldn't transfer frame data from GPU to CPU: {err} (code {ret})\");\n}","handlingStrategy":"try-catch","validationCode":"// before extraction, verify hw device is alive\ngpuDevice.DeviceRemovedReason == SharpDX.Result.Ok.Code // or equivalent graphics-device health check","typeGuard":null,"tryCatchPattern":"try { status = media.ExtractNextImage(...); }\ncatch (ApplicationException ex) when (ex.Message.Contains(\"GPU to CPU\"))\n{\n    // recreate media with software decoding fallback\n    media.Dispose(); media = CreateMedia(useHardwareDecoding: false);\n}","preventionTips":["Keep GPU drivers updated; handle device-lost events","Prefer software decoding where hw support is unreliable","Log FFmpeg return codes for diagnosis"],"tags":["ffmpeg","gpu","hardware-decoding","video"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}