objective-cmacoscocoaavfoundationavassetimagegenerator

AVAssetImageGenerator copyCGImageAtTime:actualTime:error: generates 8-bit images from 10-bit video


I've got a 10-bit video on my Mac that I want to extract frames in full 10-bit/channel data. I load my asset, and verify that it's 10-bit:

CMFormatDescriptionRef formatDescriptions = (__bridge CMFormatDescriptionRef)(track.formatDescriptions[0]);
float frameRate = track.nominalFrameRate;     
int bitDepth = ((NSNumber*)CMFormatDescriptionGetExtension(formatDescriptions, (__bridge CFStringRef)@"BitsPerComponent")).intValue;

bitDepth is 8 for many videos, but 10 for this video (that I know that I recorded in 10-bit anyway), so AVFoundation recognizes the channel bit depth correctly.

However, I want to generate single frames from the video using AVAssetImageGenerator's copyCGImageAtTime:actualTime:error: method:

NSError *err;
NSImage *img = [[NSImage alloc] initWithCGImage:[imageGenerator copyCGImageAtTime:time actualTime:NULL error:&err] size:dimensions];

The image is generated successfully with no errors, but when I check it I see that it's 8 bits/channel:

(lldb) po img
<NSImage 0x600001793f80 Size={3840, 2160} Reps=(
    "<NSCGImageSnapshotRep:0x6000017a5a40 cgImage=<CGImage 0x100520800> 
    (DP)\n\t<<CGColorSpace 0x60000261ae80> (kCGColorSpaceICCBased; 
      kCGColorSpaceModelRGB; Composite NTSC)>\n\t\twidth = 3840, height = 2160,
      bpc = 8, bpp = 32, row bytes = 15360 
      \n\t\tkCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Big  |
      kCGImagePixelFormatPacked \n\t\tis mask? No, has masking color? No, 
      has soft mask? No, has matte? No, should interpolate? Yes>"
)>

How do I generate full, lossless 10-bit (or, for compatibility, 16-bit or 32-bit) frames from a 10-bit video?

I'm on macOS 10.14.


Solution

  • Due to lack of any information about this, I've given up on AVAssetImageGenerator and went with embedding ffmpeg in my app and invoking that to extract 10-bit frames.