AVPlayer stutters when using AVPlayerItemVideoOutput

We’re trying to build a custom player for Unity. For this, we’re using AVPlayer with AVPlayerItemVideoOutput to get textures. However, we noticed that playback is not smooth and the stream often freezes.

For testing, we used this 8K video: https://deovr.com/nwfnq1

The video was played using the following code:

@objc public func playVideo(urlString: String) 
    {
        guard let url = URL(string: urlString) else { return }
        let pItem = AVPlayerItem(url: url)
        playerItem = pItem
        pItem.preferredForwardBufferDuration = 10.0

        let pixelBufferAttributes: [String: Any] = [
            kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
            kCVPixelBufferMetalCompatibilityKey as String: true,
        ]
        
        let output = AVPlayerItemVideoOutput( pixelBufferAttributes: pixelBufferAttributes )
        pItem.add(output)

        playerItemObserver = pItem.observe(\.status)
        {
            [weak self] pItem, _ in
            guard pItem.status == .readyToPlay else { return }
            self?.playerItemObserver = nil

            self?.player.play()
        }
        
        player = AVPlayer(playerItem: pItem)
        player.currentItem?.preferredPeakBitRate = 35_000_000
    }

When AVPlayerItemVideoOutput is attached, the video stutters and the log looks like this:

🟢 Playback likely to keep up
🟡 Buffer ahead: 4.08s | buffer: 4.08s
🟡 Buffer ahead: 4.08s | buffer: 4.08s
🟡 Buffer ahead: -0.07s | buffer: 0.00s
🟡 Buffer ahead: 2.94s | buffer: 3.49s
🟡 Buffer ahead: 2.50s | buffer: 4.06s
🟡 Buffer ahead: 1.74s | buffer: 4.30s
🟡 Buffer ahead: 0.74s | buffer: 4.30s
🟠 Playback may stall
🛑 Buffer empty
🟡 Buffer ahead: 0.09s | buffer: 4.30s
🟠 Playback may stall
🟠 Playback may stall
🛑 Buffer empty
🟠 Playback may stall
🟣 Buffer full
🟡 Buffer ahead: 1.41s | buffer: 1.43s
🟡 Buffer ahead: 1.41s | buffer: 1.43s
🟡 Buffer ahead: 1.07s | buffer: 1.43s
🟣 Buffer full
🟡 Buffer ahead: 0.47s | buffer: 1.65s
🟠 Playback may stall
🛑 Buffer empty
🟡 Buffer ahead: 0.10s | buffer: 1.65s
🟠 Playback may stall
🟡 Buffer ahead: 1.99s | buffer: 2.03s
🟡 Buffer ahead: 1.99s | buffer: 2.03s
🟣 Buffer full
🟣 Buffer full
🟡 Buffer ahead: 1.41s | buffer: 2.00s
🟡 Buffer ahead: 0.68s | buffer: 2.27s
🟡 Buffer ahead: 0.09s | buffer: 2.27s
🟠 Playback may stall
🛑 Buffer empty
🟠 Playback may stall

When we remove AVPlayerItemVideoOutput from the player, the video plays smoothly, and the output looks like this:

🟢 Playback likely to keep up
🟡 Buffer ahead: 1.94s | buffer: 1.94s
🟡 Buffer ahead: 1.94s | buffer: 1.94s
🟡 Buffer ahead: 1.22s | buffer: 2.22s
🟡 Buffer ahead: 1.05s | buffer: 3.05s
🟡 Buffer ahead: 1.12s | buffer: 4.12s
🟡 Buffer ahead: 1.18s | buffer: 5.18s
🟡 Buffer ahead: 0.72s | buffer: 5.72s
🟡 Buffer ahead: 1.27s | buffer: 7.28s
🟡 Buffer ahead: 2.09s | buffer: 3.03s
🟡 Buffer ahead: 4.16s | buffer: 6.10s
🟡 Buffer ahead: 6.66s | buffer: 7.09s
🟡 Buffer ahead: 5.66s | buffer: 7.09s
🟡 Buffer ahead: 4.66s | buffer: 7.09s
🟡 Buffer ahead: 4.02s | buffer: 7.45s
🟡 Buffer ahead: 3.62s | buffer: 8.05s
🟡 Buffer ahead: 2.62s | buffer: 8.05s
🟡 Buffer ahead: 2.49s | buffer: 3.53s
🟡 Buffer ahead: 2.43s | buffer: 3.38s
🟡 Buffer ahead: 1.90s | buffer: 3.85s

We’ve tried different attribute settings for AVPlayerItemVideoOutput. We also removed all logic related to reading frame data, but the choppy playback still remained.

Can you advise whether this is a player issue or if we’re doing something wrong?

Hello @rrenderr:

Can you elaborate on how you're using AVPlayerItemVideoOutput to drive frames in this custom player? I'd be especially curious to learn if you're custom player is working with lower-resolution content (e.g., 4k).

I'm also curious to learn if you've experimented with:

  1. Either specifying different values for preferredForwardBufferDuration & preferredPeakBitRate.
  2. Or refraining from specifying these values altogether?

Note that if preferredForwardBufferDuration is set to 0, the system will determine buffering. Moreover, preferredPeakBitRate is effectively a limit (i.e., ceiling).

Best, Steve

AVPlayer stutters when using AVPlayerItemVideoOutput
 
 
Q