Как получить буферы изображений в их исходном формате из видеопотока с помощью AVFoundation?

В документации Apple для AVAssetReaderTrackOutput указано следующее о параметре для outputSettings при создании экземпляра с использованием +[AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:outputSettings:].

Значение nil настраивает вывод на продажу семплов в их исходном формате, сохраненном указанной дорожкой.

При использовании, например. видеоресурс MP4, он, по-видимому, будет проходить через кадры в порядке декодирования (т. е. не в порядке отображения), однако все запросы к доставленным CMSampleBufferRef объектам с использованием CMSampleBufferGetImageBuffer дают NULL CVImageBufferRef объектов.

Единственный способ обеспечить доставку объектов буфера изображения — предоставить формат пиксельного буфера для outputSettings:, например kCVPixelFormatType_32ARGB для записи словаря kCVPixelBufferPixelFormatTypeKey.

Еще одним интересным побочным эффектом этого является то, что кадры затем доставляются в порядке отображения, а лежащий в основе порядок декодирования кадров абстрагируется/скрывается.

Любые идеи, почему это так?


person Dan    schedule 05.05.2018    source источник
comment
Как понять, что рамы вышли из строя? Из временных меток презентации? Вы уверены, что это рамки? p.s. что вы имеете в виду под оригинальным форматом?   -  person Rhythmic Fistman    schedule 05.05.2018
comment
Кадры выглядят не по порядку из-за отметок времени презентации, да. Я не уверен, содержат ли они кадры, но они отслеживают порядок декодирования кадров в противном случае, например, через другие API, такие как QuickTime. Под исходным форматом я цитировал то, что указано в документации Apple, и идея состоит в том, чтобы избежать любых ненужных преобразований формата пикселей между тем, что было естественным для закодированного потока, и тем, что я в конечном итоге получил в будущем.   -  person Dan    schedule 06.05.2018
comment
Может быть, B-кадры GOP могут объяснить неправильные временные метки? Как не по порядку мы говорим? en.wikipedia.org/wiki/Video_compression_picture_types   -  person Rhythmic Fistman    schedule 06.05.2018


Ответы (1)


Как и вы, я ожидал, что установка outputSettings из nil приведет к выводу видеокадров в собственном формате, но это не так, вы должны указать что-то, чтобы получить действительный CVSampleBufferRef.

Не все потеряно, с помощью словаря "едва ли" кажется, что кадры выводятся в их родном формате,

AVAsset asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetTrack *videoTrack = [[asset tracksWithMediaCharacteristic:AVMediaCharacteristicVisual] objectAtIndex:0];

NSDictionary *decompressionSettings =
     @{ (id)kCVPixelBufferIOSurfacePropertiesKey : [NSDictionary dictionary] };
AVAssetReaderTrackOutput trackOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:decompressionSettings];
...

IOSurfaceOptions просто заданы по умолчанию — дальнейшее чтение для справки: https://developer.apple.com/documentation/corevideo/kcvpixelbuffiosurfacepropertieskey?language=objc

person koan    schedule 17.07.2019