stride3d/stride · error · Exception

Got media sample from track

Error message

Got media sample from track {mediaExtractor.SampleTrackIndex}, track expected {mediaTrackIndex}

What it means

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.

Solutions

  1. Verify the file's track layout (e.g. ffprobe) and that the expected track exists
  2. Ensure mediaExtractor.SeekTo(..., MediaExtractorSeekTo.ClosestSync) is used with the correct track selected before reading
  3. Use a cleanly re-encoded file (single video + audio track) to rule out malformed containers
  4. Check Initialize selected mediaTrackIndex via GetTrackFormat for the intended MediaCodec
  5. Update the Android runtime/Stride package if container demux behavior is buggy
Defensive patterns

Strategy: validation

Validate before calling

// before reading, assert the extractor's expected track
if (mediaExtractor.SampleTrackIndex != expectedTrackIndex) mediaExtractor.SeekTo(0, MediaExtractorSeekTo.ClosestSync);

Try / catch

try { ReadAndQueueSamples(); }
catch (Exception ex) when (ex.Message.StartsWith("Got media sample from track"))
{ /* stop decoding this file; treat media as invalid */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Video/Android/MediaCodecExtractorBase.cs:324

                //=================================================================================================
                //Extract video inputs
                // While stopped with no seek pending, outputs are not dequeued either, so feeding
                // the decoder would only build up buffers that the next seek has to flush away.
                if (!inputExtractionDone && (!isSeekRequestCompleted || currentState != SchedulerAsyncCommandEnum.Stop))
                {
                    int inputBufIndex = MediaDecoder.DequeueInputBuffer(0);
                    if (inputBufIndex >= 0)
                    {
                        waitTime = TimeSpan.Zero;
                        var inputBuffer = MediaDecoder.GetInputBuffer(inputBufIndex);

                        // Read the sample data into the ByteBuffer.  This neither respects nor updates inputBuf's position, limit, etc.
                        int chunkSize = mediaExtractor.ReadSampleData(inputBuffer, 0);
                        if (chunkSize > 0)
                        {
                            if (mediaExtractor.SampleTrackIndex != mediaTrackIndex)
                                throw new Exception($"Got media sample from track {mediaExtractor.SampleTrackIndex}, track expected {mediaTrackIndex}");
                            
                            MediaDecoder.QueueInputBuffer(inputBufIndex, 0, chunkSize, mediaExtractor.SampleTime, 0);
                            inputQueuedSinceFlush = true;
                            mediaExtractor.Advance();
                        }
                        else // End of stream -- send empty frame with EOS flag set.
                        {
                            MediaDecoder.QueueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodecBufferFlags.EndOfStream);
                            inputQueuedSinceFlush = true;
                            inputExtractionDone = true;
                        }
                    }
                    else
                    {
                        //do nothing: the input buffer queue is full (we need to output them first)
                    }
                }

View on GitHub (pinned to 96fad776d2)