{"record":{"id":"8de9f14baa9f9515","repo":"stride3d/stride","slug":"got-media-sample-from-track-mediaextractor-sampletrackindex","errorCode":null,"errorMessage":"Got media sample from track {mediaExtractor.SampleTrackIndex}, track expected {mediaTrackIndex}","messagePattern":"Got media sample from track (.+?), track expected (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Video/Android/MediaCodecExtractorBase.cs","lineNumber":324,"sourceCode":"\n                //=================================================================================================\n                //Extract video inputs\n                // While stopped with no seek pending, outputs are not dequeued either, so feeding\n                // the decoder would only build up buffers that the next seek has to flush away.\n                if (!inputExtractionDone && (!isSeekRequestCompleted || currentState != SchedulerAsyncCommandEnum.Stop))\n                {\n                    int inputBufIndex = MediaDecoder.DequeueInputBuffer(0);\n                    if (inputBufIndex >= 0)\n                    {\n                        waitTime = TimeSpan.Zero;\n                        var inputBuffer = MediaDecoder.GetInputBuffer(inputBufIndex);\n\n                        // Read the sample data into the ByteBuffer.  This neither respects nor updates inputBuf's position, limit, etc.\n                        int chunkSize = mediaExtractor.ReadSampleData(inputBuffer, 0);\n                        if (chunkSize > 0)\n                        {\n                            if (mediaExtractor.SampleTrackIndex != mediaTrackIndex)\n                                throw new Exception($\"Got media sample from track {mediaExtractor.SampleTrackIndex}, track expected {mediaTrackIndex}\");\n                            \n                            MediaDecoder.QueueInputBuffer(inputBufIndex, 0, chunkSize, mediaExtractor.SampleTime, 0);\n                            inputQueuedSinceFlush = true;\n                            mediaExtractor.Advance();\n                        }\n                        else // End of stream -- send empty frame with EOS flag set.\n                        {\n                            MediaDecoder.QueueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodecBufferFlags.EndOfStream);\n                            inputQueuedSinceFlush = true;\n                            inputExtractionDone = true;\n                        }\n                    }\n                    else\n                    {\n                        //do nothing: the input buffer queue is full (we need to output them first)\n                    }\n                }\n","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Video/Android/MediaCodecExtractorBase.cs#L306-L342","documentation":"During extraction, a sample read from the MediaExtractor belongs to a different track index than the one this extractor was configured to decode (mediaTrackIndex). The library throws because feeding samples from the wrong track (e.g. audio into a video decoder) would corrupt the decode pipeline.","triggerScenarios":"MediaExtractor.Advance() walks into samples of an unintended track interleaved in the container; the extractor selected the wrong track in Initialize; a malformed/multi-track container reports unexpected sample track indices.","commonSituations":"Container files with multiple video or unusual audio tracks; seek operations landing on a sample of another track; files where SeekTo did not respect the selected track; corrupted containers.","solutions":["Verify the file's track layout (e.g. ffprobe) and that the expected track exists","Ensure mediaExtractor.SeekTo(..., MediaExtractorSeekTo.ClosestSync) is used with the correct track selected before reading","Use a cleanly re-encoded file (single video + audio track) to rule out malformed containers","Check Initialize selected mediaTrackIndex via GetTrackFormat for the intended MediaCodec","Update the Android runtime/Stride package if container demux behavior is buggy"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before reading, assert the extractor's expected track\nif (mediaExtractor.SampleTrackIndex != expectedTrackIndex) mediaExtractor.SeekTo(0, MediaExtractorSeekTo.ClosestSync);","typeGuard":null,"tryCatchPattern":"try { ReadAndQueueSamples(); }\ncatch (Exception ex) when (ex.Message.StartsWith(\"Got media sample from track\"))\n{ /* stop decoding this file; treat media as invalid */ }","preventionTips":["Select the track explicitly with GetTrackFormat for the intended media type","Use SeekTo with ClosestSync on the selected track before reading","Validate container track layout with ffprobe before shipping media assets"],"tags":["android","mediaextractor","video-decoding","container"],"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"}