Is it possible to find IDR frame (CMSampleBuffer) in AVAsset h264 video file?
Find IDR in AVAsset
I'm assuming you want the IDR info in decode order rather than presentation order. This makes a difference if your movie contains bidirectionally predicted frames. If your H.264 video file is a QuickTime movie, you can do something like this:
func getSyncInfo(url: URL) -> [Bool] {
var idrInfo = [Bool]()
let asset = AVURLAsset(url: url)
guard let reader = try? AVAssetReader(asset: asset) else {
return idrInfo
}
let videoTrack = asset.tracks(withMediaType: AVMediaType.video).first!
guard let cursor = videoTrack.makeSampleCursorAtFirstSampleInDecodeOrder() else {
return idrInfo
}
repeat {
let syncInfo = cursor.currentSampleSyncInfo
idrInfo.append(syncInfo.sampleIsFullSync.boolValue ? true : false)
} while cursor.stepInDecodeOrder(byCount: 1) == 1
return idrInfo
}
This is unlikely, but if the CMSampleBuffer contains an access unit of a raw Annex B bitstream, then you have to:
- Get the raw data bytes from the
CMBlockBuffers - Remove encapsulation prevention bytes
- Search for start codes the look like
0x00 0x00 0x01 - Parse the
nal_unit_typebyte following the start code - Mask out the higher 3 bits to get
nal_unit_type - Check that the
nal_unit_typeis 5.