{"record":{"id":"4e703c260c6a4931","repo":"stride3d/stride","slug":"unexpected-result-from-audio-decoder-dequeueoutputbuffer-0","errorCode":null,"errorMessage":"unexpected result from audio decoder.DequeueOutputBuffer: {0}","messagePattern":"unexpected result from audio decoder\\.DequeueOutputBuffer: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Audio/StreamedBufferSoundSource.MediaCodec.cs","lineNumber":162,"sourceCode":"\n                case (int)MediaCodecInfoState.OutputFormatChanged:\n                    {\n                        MediaFormat newFormat = audioMediaDecoder.OutputFormat;\n                        string newFormatStr = newFormat.ToString();\n                        Logger.Verbose(\"audio decoder output format changed: \" + newFormatStr);\n                        break;\n                    }\n\n                case (int)MediaCodecInfoState.OutputBuffersChanged:\n                    {\n                        //deprecated: we just ignore it\n                        break;\n                    }\n\n                default:\n                    {\n                        if (decoderStatus < 0)\n                            throw new InvalidOperationException(string.Format(\"unexpected result from audio decoder.DequeueOutputBuffer: {0}\", decoderStatus));\n\n                        if ((info.Flags & MediaCodecBufferFlags.EndOfStream) != 0)\n                        {\n                            Logger.Verbose(\"audio: output EOS\");\n                            extractionOutputDone = true;\n                        }\n\n                        if (info.Size > 0)\n                        {\n                            hasExtractedData = true;\n                            var buffer = audioMediaDecoder.GetOutputBuffer(decoderStatus);\n                            var presentationTime = TimeSpanExtensions.FromMicroSeconds(info.PresentationTimeUs);\n\n                            if (storageBuffer.CountDataBytes + info.Size <= storageBuffer.Data.Length)\n                            {\n                                buffer.Get(storageBuffer.Data, storageBuffer.CountDataBytes, info.Size); // Read the buffer all at once\n                                buffer.Clear(); // MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN\n                                buffer.Position(0);","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Audio/StreamedBufferSoundSource.MediaCodec.cs#L144-L180","documentation":"ExtractSomeAudioData throws this when MediaCodec.DequeueOutputBuffer returns an unexpected negative status (not INFO_TRY_AGAIN_LATER, INFO_OUTPUT_FORMAT_CHANGED, or INFO_OUTPUT_BUFFERS_CHANGED). It signals the Android audio decoder entered an unrecognized/failed state, so extraction cannot continue reliably.","triggerScenarios":"DequeueOutputBuffer returns a negative code such as MediaCodec.InfoReturned(-101) or a codec-specific error while feeding compressed input and draining output during streaming playback of the audio file.","commonSituations":"Corrupt or truncated media files; unsupported codec profile passed to MediaExtractor (e.g. unusual AAC profiles); decoder released/reconfigured mid-stream (seek racing extraction); device-specific codec bugs on old Android versions.","solutions":["Verify the media file decodes correctly in another player and is not truncated/corrupt","On this exception, dispose and re-create the MediaCodec and MediaExtractor (full re-initialization) rather than continuing to dequeue","Check the Configure call uses the exact MediaFormat from GetTrackFormat(trackIndexAudio)","Log the raw decoderStatus value; negative codes other than -1/-2/-3 indicate a codec error needing reconfigure","Handle seek carefully: after SeekInternalImpl, flush the codec (Flush()) before resuming dequeue loops"],"exampleFix":"// before\ndefault:\n    if (decoderStatus < 0)\n        throw new InvalidOperationException(string.Format(\"unexpected result from audio decoder.DequeueOutputBuffer: {0}\", decoderStatus));\n// after\ndefault:\n    if (decoderStatus < 0)\n    {\n        Logger.Error($\"audio decoder error {decoderStatus}; reinitializing extractor\");\n        ReleaseMediaInternal();\n        InitializeMediaExtractor(InputFile.AbsolutePath, 0, 0);\n        return;\n    }","handlingStrategy":"retry","validationCode":"// before streaming, verify the track selects a supported codec\nvar format = extractor.GetTrackFormat(trackIndexAudio);\nvar mime = format.GetString(MediaFormat.KeyMime);\nif (!MediaCodecList.GetCodecInfos().Any(c => c.GetCodecCapabilities()?.GetSupportedTypes()?.Contains(mime) == true))\n    throw new InvalidOperationException($\"No decoder available for {mime}\");","typeGuard":null,"tryCatchPattern":"try\n{\n    ExtractSomeAudioData();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"DequeueOutputBuffer\"))\n{\n    Logger.Warn($\"Decoder error, resetting stream: {ex.Message}\");\n    ResetDecoder(); // ReleaseMediaInternal + re-init\n}","preventionTips":["Flush/re-create the MediaCodec after every seek","Validate media files with ffprobe/another player before shipping","Configure the codec with the exact MediaFormat from MediaExtractor.GetTrackFormat","Test on low-end Android devices with hardware codec quirks"],"tags":["android","audio","mediacodec","decoder"],"backgroundTag":"unexpected-response-shape","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}