AVFoundation: Compression property Quality is not supported for video codec type avc1

I think I'm looking for a way to check if a video settings key is valid, so I can exclude it if it isn't. But I'm more curious why some keys are valid sometimes, inconsistently. Let me explain.

With my macOS app, I'm trying to write a video with compression quality set, like so

 let videoWriter = AVAssetWriterInput(
			mediaType: .video,
			outputSettings:
				[
					AVVideoWidthKey: 1000,
					AVVideoHeightKey: 1000,
					AVVideoCodecKey: AVVideoCodecType.h264,
					AVVideoCompressionPropertiesKey: [
						AVVideoQualityKey: 0.4
					]
				]
		)

It works on my M1Max (13.4, 13.5), Intel Mac (12.0.1), but for one (for now?) of my users (on 13.5/Intel, Macbook16,1) this line throws an exception and crashes the app.

This is the output

*** -[AVAssetWriterInput initWithMediaType:outputSettings:sourceFormatHint:] 
Compression property Quality is not supported for video codec type avc1

Reproducing sample app

This tiny app reproduces the crash for my user (but still, not for me) https://github.com/mortenjust/CompressionCrashTest/blob/main/CompressionCrashTest/ContentView.swift

What I tried

I tried looking into catching objc exceptions (from AV Foundation) with Swift via a wrapper, but it looks like it's a bad idea, and not recommended by Apple.

I also tried changing the codec to .hevc and that also crashes, saying that Quality is not a supported key.

I tried asking my user to reboot, no effect.

I tried exporting a video with compression quality 0.1 on my Mac to verify that it's a valid key, and the output video was compressed, small file size and visually distorted.

I tried upgrading from 13.4 to 13.5 to match his specs, but it still doesn't crash for me.

I really wish there was a way to validate a video settings dictionary without crashing.

I found AVCaptureMovieFileOutput / supportedOutputSettingsKeys(for:) that vaguely resembles what I need, but it's made for recording from a camera.

Post not yet marked as solved Up vote post of mortenjust Down vote post of mortenjust
710 views

Replies

I have a hypothesis. Would love it if someone could confirm or add information.

Compression quality actually not supported by avc1/hvc1 (h264/h265) codecs. In some systems, like mine, AV Foundation translates compression quality to bitrate. In other systems, like my user's, AV Foundation crashes.

Testing the hypothesis

  1. Write a video with H264 at 40% compression quality
  2. Write the same video with H264 at 100% compression quality
  3. Compare the bitrates with ffprobe

The first video is encoded with a bitrate of 1000 kb/s The second video is encoded with a bitrate of 25841 kb/s

These results support the hypothesis. The next question is if bitrate is the only thing adjusted when passing a compression quality value. I haven't tested if it changes any of the other compression settings.

Another datapoint is that the docs explicitly say about the compression quality key, "A key to set the JPEG compression quality of the video." which does sound like it's only applicable if the JPEG codec is chosen.

Hat tip to this SO answer