---
title: MESampleCursor
framework: MediaExtension
role: symbol
role_heading: Protocol
platforms: [macOS 14.0+]
path: mediaextension/mesamplecursor
---

# MESampleCursor

A protocol that defines the information to provide about samples within a track of a media asset, and enables stepping through samples in the track in decode or presentation order.

## Declaration

```swift
protocol MESampleCursor : NSCopying, NSObjectProtocol
```

## Overview

Overview This object delivers sample data either by providing sample location and sample chunk information, or by directly generating a sample buffer. Delivering sample data An MESampleCursor object can return sample data to Core Media in two ways: Return information about the sample data location in the media and let Core Media read the data. Read the data and return sample buffers directly. Review the following information that explains these approaches and which one to use for typical scenarios. Allowing Core Media to read the sample data This is the preferred method to deliver sample data. It allows Core Media to optimize data I/O read operations, and potentially combine multiple smaller reads into a single larger read for better performance. There are four methods available to deliver the required sample location information: sampleLocation() This is the baseline method to return sample location information. For formats with individually-stored samples such as video, Core Media calls this method to find each sample location. chunkDetails() For formats with samples stored in groups, blocks, or chunks such as audio, use this method to indicate details about the number of samples stored in each group. After determining the chunk information, Core Media calls sampleLocation() to locate individual samples within the chunk. MESampleCursor objects for these formats need to implement both sampleLocation() and chunkDetails(). estimatedSampleLocation() In some cases it’s not possible to directly determine the sample location and return it through sampleLocation(). Instead, there’s a two-step process to determine the sample location: call estimatedSampleLocation() to obtain a coarse estimation, and then call refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:) to find the exact location. Implement both methods to support this approach. refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:) This method returns the exact sample location information as a second step after it receives the coarse estimate from estimatedSampleLocation(). Implement both methods to support this approach. Reading the sample buffers directly When it’s not possible to let Core Media read the sample data using location information, the MESampleCursor object needs to read the sample data itself using the MEByteSource to deliver the sample data buffers. This is less efficient for data I/O because there’s no way for Core Media to optimize read operations. The method loadSampleBufferContainingSamples(to:completionHandler:) delivers sample data buffers directly, so it allows the MESampleCursor object flexibility to read and unpack the samples from the media. The sample cursor needs to use the MEByteSource directly to seek and read in the sample data. This method can deliver sample buffers either with one sample, such as for video tracks, or with blocks of samples, such as for audio tracks. It’s also suitable for use with synthesized samples that use metadata from the media, such as for timecode tracks. Choosing the best approach Choose the best approach in these typical scenarios: The media stores the samples in groups interleaved among other samples. The MESampleCursor object implements sampleLocation() and chunkDetails() to allow Core Media to locate the chunks and find samples inside the chunks. The media stores the samples in blocks interleaved among other samples, but some blocks are non-contiguous. The MESampleCursor object implements sampleLocation(), chunkDetails(), and loadSampleBufferContainingSamples(to:completionHandler:). For contiguous samples, sampleLocation() returns the samples to read. For non-contiguous samples, sampleLocation() fails with the error MEError.Code.locationNotAvailable and Core Media then uses loadSampleBufferContainingSamples(to:completionHandler:) to read the samples. It’s not possible to determine sample location in one step. The MESampleCursor object implements estimatedSampleLocation() and refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:) (instead of sampleLocation()). If it’s not possible to determine the sample location using either the one-step or two-step approach, the MESampleCursor object implements loadSampleBufferContainingSamples(to:completionHandler:) to directly deliver sample buffers. It’s necessary to unpack or prepare sample data before delivering it. If Core Media can’t directly read the sample data, then the MESampleCursor object implements loadSampleBufferContainingSamples(to:completionHandler:) to read the data itself, unpack or prepare it, and deliver it in sample buffers.

## Topics

### Inspecting a sample cursor

- [presentationTimeStamp](mediaextension/mesamplecursor/presentationtimestamp.md)
- [decodeTimeStamp](mediaextension/mesamplecursor/decodetimestamp.md)
- [currentSampleDuration](mediaextension/mesamplecursor/currentsampleduration.md)
- [currentSampleFormatDescription](mediaextension/mesamplecursor/currentsampleformatdescription.md)
- [syncInfo](mediaextension/mesamplecursor/syncinfo.md)
- [dependencyInfo](mediaextension/mesamplecursor/dependencyinfo.md)
- [hevcDependencyInfo](mediaextension/mesamplecursor/hevcdependencyinfo.md)
- [decodeTimeOfLastSampleReachableByForwardSteppingThatIsAlreadyLoadedByByteSource](mediaextension/mesamplecursor/decodetimeoflastsamplereachablebyforwardsteppingthatisalreadyloadedbybytesource.md)

### Stepping through samples

- [samplesWithEarlierDTSsMayHaveLaterPTSs(than:)](mediaextension/mesamplecursor/sampleswithearlierdtssmayhavelaterptss(than:).md)
- [samplesWithLaterDTSsMayHaveEarlierPTSs(than:)](mediaextension/mesamplecursor/sampleswithlaterdtssmayhaveearlierptss(than:).md)
- [estimatedSampleLocation()](mediaextension/mesamplecursor/estimatedsamplelocation().md)
- [refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:)](mediaextension/mesamplecursor/refinesamplelocation(_:refinementdata:refinementdatalength:refinedlocation:).md)
- [stepByDecodeTime(_:completionHandler:)](mediaextension/mesamplecursor/stepbydecodetime(_:completionhandler:).md)
- [stepByPresentationTime(_:completionHandler:)](mediaextension/mesamplecursor/stepbypresentationtime(_:completionhandler:).md)
- [stepInDecodeOrder(by:completionHandler:)](mediaextension/mesamplecursor/stepindecodeorder(by:completionhandler:).md)
- [stepInPresentationOrder(by:completionHandler:)](mediaextension/mesamplecursor/stepinpresentationorder(by:completionhandler:).md)

### Sending samples to a pipeline

- [chunkDetails()](mediaextension/mesamplecursor/chunkdetails().md)
- [sampleLocation()](mediaextension/mesamplecursor/samplelocation().md)
- [loadSampleBufferContainingSamples(to:completionHandler:)](mediaextension/mesamplecursor/loadsamplebuffercontainingsamples(to:completionhandler:).md)

### RAW processing metadata

- [loadPostDecodeProcessingMetadata(completionHandler:)](mediaextension/mesamplecursor/loadpostdecodeprocessingmetadata(completionhandler:).md)

## Relationships

### Inherits From

- [NSCopying](foundation/nscopying.md)
- [NSObjectProtocol](objectivec/nsobjectprotocol.md)

## See Also

### Sample cursors

- [MESampleLocation](mediaextension/mesamplelocation.md)
- [MESampleCursorChunk](mediaextension/mesamplecursorchunk.md)
- [MEEstimatedSampleLocation](mediaextension/meestimatedsamplelocation.md)
- [MEHEVCDependencyInfo](mediaextension/mehevcdependencyinfo.md)
