<!--
{
  "availability" : [
    "macOS: 14.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "MediaExtension",
  "identifier" : "/documentation/MediaExtension/MESampleCursor",
  "metadataVersion" : "0.1.0",
  "role" : "Protocol",
  "symbol" : {
    "kind" : "Protocol",
    "modules" : [
      "MediaExtension"
    ],
    "preciseIdentifier" : "c:objc(pl)MESampleCursor"
  },
  "title" : "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.

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

## 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`](/documentation/MediaExtension/MESampleCursor) object can return sample data to <doc://com.apple.documentation/documentation/CoreMedia> 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:

1. [`sampleLocation()`](/documentation/MediaExtension/MESampleCursor/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.

1. [`chunkDetails()`](/documentation/MediaExtension/MESampleCursor/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()`](/documentation/MediaExtension/MESampleCursor/sampleLocation()) to locate individual samples within the chunk. [`MESampleCursor`](/documentation/MediaExtension/MESampleCursor) objects for these formats need to implement both [`sampleLocation()`](/documentation/MediaExtension/MESampleCursor/sampleLocation()) and [`chunkDetails()`](/documentation/MediaExtension/MESampleCursor/chunkDetails()).

1. [`estimatedSampleLocation()`](/documentation/MediaExtension/MESampleCursor/estimatedSampleLocation())

In some cases it’s not possible to directly determine the sample location and return it through [`sampleLocation()`](/documentation/MediaExtension/MESampleCursor/sampleLocation()). Instead, there’s a two-step process to determine the sample location: call [`estimatedSampleLocation()`](/documentation/MediaExtension/MESampleCursor/estimatedSampleLocation()) to obtain a coarse estimation, and then call [`refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:)`](/documentation/MediaExtension/MESampleCursor/refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:)) to find the exact location. Implement both methods to support this approach.

1. [`refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:)`](/documentation/MediaExtension/MESampleCursor/refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:))

This method returns the exact sample location information as a second step after it receives the coarse estimate from [`estimatedSampleLocation()`](/documentation/MediaExtension/MESampleCursor/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`](/documentation/MediaExtension/MESampleCursor) object needs to read the sample data itself using the [`MEByteSource`](/documentation/MediaExtension/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:)`](/documentation/MediaExtension/MESampleCursor/loadSampleBufferContainingSamples(to:completionHandler:)) delivers sample data buffers directly, so it allows the [`MESampleCursor`](/documentation/MediaExtension/MESampleCursor) object flexibility to read and unpack the samples from the media. The sample cursor needs to use the [`MEByteSource`](/documentation/MediaExtension/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:

1. The media stores the samples in groups interleaved among other samples.

The `MESampleCursor` object implements [`sampleLocation()`](/documentation/MediaExtension/MESampleCursor/sampleLocation()) and [`chunkDetails()`](/documentation/MediaExtension/MESampleCursor/chunkDetails()) to allow Core Media to locate the chunks and find samples inside the chunks.

1. The media stores the samples in blocks interleaved among other samples, but some blocks are non-contiguous.

The `MESampleCursor` object implements [`sampleLocation()`](/documentation/MediaExtension/MESampleCursor/sampleLocation()), [`chunkDetails()`](/documentation/MediaExtension/MESampleCursor/chunkDetails()), and [`loadSampleBufferContainingSamples(to:completionHandler:)`](/documentation/MediaExtension/MESampleCursor/loadSampleBufferContainingSamples(to:completionHandler:)). For contiguous samples, [`sampleLocation()`](/documentation/MediaExtension/MESampleCursor/sampleLocation()) returns the samples to read. For non-contiguous samples, [`sampleLocation()`](/documentation/MediaExtension/MESampleCursor/sampleLocation()) fails with the error [`MEError.Code.locationNotAvailable`](/documentation/MediaExtension/MEError-swift.struct/Code/locationNotAvailable) and Core Media then uses [`loadSampleBufferContainingSamples(to:completionHandler:)`](/documentation/MediaExtension/MESampleCursor/loadSampleBufferContainingSamples(to:completionHandler:)) to read the samples.

1. It’s not possible to determine sample location in one step.

The `MESampleCursor` object implements [`estimatedSampleLocation()`](/documentation/MediaExtension/MESampleCursor/estimatedSampleLocation()) and [`refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:)`](/documentation/MediaExtension/MESampleCursor/refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:)) (instead of [`sampleLocation()`](/documentation/MediaExtension/MESampleCursor/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:)`](/documentation/MediaExtension/MESampleCursor/loadSampleBufferContainingSamples(to:completionHandler:)) to directly deliver sample buffers.

1. 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:)`](/documentation/MediaExtension/MESampleCursor/loadSampleBufferContainingSamples(to:completionHandler:)) to read the data itself, unpack or prepare it, and deliver it in sample buffers.

## Topics

### Inspecting a sample cursor

[`presentationTimeStamp`](/documentation/MediaExtension/MESampleCursor/presentationTimeStamp)

The presentation timestamp (PTS) of the sample at the current position of the cursor.

[`decodeTimeStamp`](/documentation/MediaExtension/MESampleCursor/decodeTimeStamp)

The decode timestamp (DTS) of the sample at the current position of the cursor.

[`currentSampleDuration`](/documentation/MediaExtension/MESampleCursor/currentSampleDuration)

The decode duration of the sample at the current position.

[`currentSampleFormatDescription`](/documentation/MediaExtension/MESampleCursor/currentSampleFormatDescription)

The format description for the sample at the current position of the cursor.

[`syncInfo`](/documentation/MediaExtension/MESampleCursor/syncInfo)

Decoder synchronization information about the sample the cursor points to.

[`dependencyInfo`](/documentation/MediaExtension/MESampleCursor/dependencyInfo)

Dependency information about the sample the cursor points to.

[`hevcDependencyInfo`](/documentation/MediaExtension/MESampleCursor/hevcDependencyInfo)

Additional information that’s necessary to recover complete sample dependency information.

[`decodeTimeOfLastSampleReachableByForwardSteppingThatIsAlreadyLoadedByByteSource`](/documentation/MediaExtension/MESampleCursor/decodeTimeOfLastSampleReachableByForwardSteppingThatIsAlreadyLoadedByByteSource)

The duration of the playable content starting from the cursor position.

### Stepping through samples

[`-  samplesWithEarlierDTSsMayHaveLaterPTSsThanCursor:`](/documentation/MediaExtension/MESampleCursor/samplesWithEarlierDTSsMayHaveLaterPTSs(than:))

Tests for an earlier boundary in sample reordering.

[`-  samplesWithLaterDTSsMayHaveEarlierPTSsThanCursor:`](/documentation/MediaExtension/MESampleCursor/samplesWithLaterDTSsMayHaveEarlierPTSs(than:))

Tests for a later boundary in sample reordering.

[`-  estimatedSampleLocationReturningError:`](/documentation/MediaExtension/MESampleCursor/estimatedSampleLocation())

Returns an estimate of the sample location indicated by the cursor.

[`-  refineSampleLocation:refinementData:refinementDataLength:refinedLocation:error:`](/documentation/MediaExtension/MESampleCursor/refineSampleLocation(_:refinementData:refinementDataLength:refinedLocation:))

Produces an exact sample location based on the estimated sample location and refinement data that you specify.

[`-  stepByDecodeTime:completionHandler:`](/documentation/MediaExtension/MESampleCursor/stepByDecodeTime(_:completionHandler:))

Moves the cursor on the decode timeline by the delta decode time that you specify.

[`-  stepByPresentationTime:completionHandler:`](/documentation/MediaExtension/MESampleCursor/stepByPresentationTime(_:completionHandler:))

Moves the cursor on the presentation timeline by the delta presentation time that you specify.

[`-  stepInDecodeOrderByCount:completionHandler:`](/documentation/MediaExtension/MESampleCursor/stepInDecodeOrder(by:completionHandler:))

Moves the cursor a given number of samples in decode order.

[`-  stepInPresentationOrderByCount:completionHandler:`](/documentation/MediaExtension/MESampleCursor/stepInPresentationOrder(by:completionHandler:))

Moves the cursor a given number of samples in presentation order.

### Sending samples to a pipeline

[`-  chunkDetailsReturningError:`](/documentation/MediaExtension/MESampleCursor/chunkDetails())

Returns information about the chunk that holds the sample indicated by the cursor.

[`-  sampleLocationReturningError:`](/documentation/MediaExtension/MESampleCursor/sampleLocation())

Returns the location and byte source of the sample indicated by the cursor.

[`-  loadSampleBufferContainingSamplesToEndCursor:completionHandler:`](/documentation/MediaExtension/MESampleCursor/loadSampleBufferContainingSamples(to:completionHandler:))

Builds a sample buffer that contains the samples at the cursor that you specify.

### RAW processing metadata

[`-  loadPostDecodeProcessingMetadataWithCompletionHandler:`](/documentation/MediaExtension/MESampleCursor/loadPostDecodeProcessingMetadata(completionHandler:))

Asynchronously loads a dictionary that represents frame level metadata for post decode processing.

## Relationships

### Inherits From

[`NSObjectProtocol`](/documentation/ObjectiveC/NSObjectProtocol)

[`NSCopying`](/documentation/Foundation/NSCopying)

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)