I'm building a video export feature for one of my apps. In essence, the video is a series of one of six different images lasting for different (short) durations.
The export works fine when I export something containing 283 images of varying durations, but when I try to export one of 803, I get the dreaded "The operation could not be completed" error (A.K.A. "we have no idea what just blew up because AVFoundation error reporting is awful").
When I try to add the 754th frame (always the 754th frame) using my AVAssetWriterInputPixelBufferAdaptor
, appendPixelBuffer:withPresentationTime:
returns NO
, the AVAssetWriter
's status is failed and its error is this:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x17ab2050 {Error Domain=NSOSStatusErrorDomain Code=-16364 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-16364)}
I can't for the life of me figure out what that underlying error (OSStatus
-16364) is. www.osstatus.com has no idea, macerror
says no such thing exists, and this Python script for searching the SDK headers finds nothing. It's also not a four character code like some OSStatus errors (unless I messed up checking this).
I've ruled out every common cause of "The operation cannot be completed" errors I've found. It's not related to filesystem permissions or overwriting, no two calls of appendPixelBuffer
have the same presentation time.
It's not a memory thing (memory usage stays flat at 165MB during video export), and CPU stays near 3%.
If it's of any importance, I reuse the same 6 CVPixelBuffer
s over and over again for the 6 images instead of creating new ones from UIImage
s each time. This seems to help performance, and changing it to new ones each time doesn't seem to change anything (except make it fail on frame 753 instead), but who knows.
Does anyone have any idea what this could be?
OK. Finally figured this out.
Because of rounding (rounding small duration values into the timescale of 30 FPS, which caused them to become 0/30), appendPixelBuffer:withPresentationTime:
was being called twice with the same presentationTime
under specific circumstances. AVFoundation didn't notice the problem till 7 frames later when it throws the error:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x17ab2050 {Error Domain=NSOSStatusErrorDomain Code=-16364 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-16364)}
Using 60 FPS in place of 30 FPS prevented this particular situation from rounding to a zero duration, but the general solution was to drop frames with durations that rounded to zero.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With