Способ в реальном времени извлечь все видеокадры в формате YV12 (YUV420) из фильма QuickTime?

У меня QTMovie открыт в QTKit.

Мне нужно получить каждый кадр этого видео в формате YV12 (kYUV420PixelFormat) в реальном времени (т. Е. Я передаю его внешнему коду, который принимает только YV12 и должен воспроизводить видео в реальном времени. ).

Кажется, как это должно быть сделано - это вызвать [movie frameImageAtTime: [movie currentTime] withAttributes: error:] для текущего кадра, а затем [movie stepForward ], чтобы перейти к следующему кадру, и так далее, пока я не получу все кадры. Однако, насколько я это понимаю, я не могу найти способ заставить QTKit предоставлять мне данные в формате YV12 или любом другом формате YUV. Вызов frameImageAtTime: может преобразовать его в:

  • NSImage (но NSImage не может хранить планарный YUV),
  • CGImage (то же самое),
  • CIImage (то же самое),
  • CVPixelBuffer (он может хранить YUV, но, похоже, нет способа настроить вызов для получения от него YUV. По умолчанию он возвращает данные ARGB32)
  • Текстура OpenGL (возможно, это тоже можно настроить, но мне не нужны эти данные в OpenGL, они нужны мне в памяти)

Таким образом, кажется, что единственный способ использовать эту якобы новую и оптимизированную технологию QTKit - это получить из нее данные ARGB, преобразовать каждый кадр в YV12 с помощью специального кода и надеяться, что это будет достаточно быстро для работы в реальном времени. Или я что-то упускаю?

В старом QuickTime было относительно легко настроить GWorld с помощью kYUV420PixelFormat, добавить к нему рендеринг фильма, и это просто работало. Но старые вызовы QuickTime являются устаревшими, устаревшими вызовами, которые больше не должны использоваться ...

Что делать, чтобы получить планарные рамки YUV420 без лишних преобразований?


person Krystian Gałaj    schedule 14.04.2011    source источник
comment
В конце концов, я выбрал «старый, устаревший способ, который больше не используется», который дает мне 30 кадров в секунду с легкостью при использовании GWorldPtrs. Обратная совместимость или технология Apple - выберите один.   -  person Krystian Gałaj    schedule 16.05.2011


Ответы (1)


Основываясь на этой ветке в одном из старых списков рассылки Apple, я бы сказал, что, по крайней мере, раньше это было невозможно. Сейчас я пытаюсь выяснить, можно ли это сделать с помощью API более низкого уровня.

http://lists.apple.com/archives/quicktime-api/2008/Nov/msg00049.html

5 ноября 2008 г. в 12:08 Нил Клейтон написал:

Я хотел бы получить кадр YUV из фильма (фильм закодирован в YUV, кадры изначально были k2vuyPixelFormat, и формат кодировщика был бы совместим с этим - например: H264 или AIC и т. Д.).

Когда я это сделаю:

NSError *error = nil;
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
    QTMovieFrameImageTypeCVPixelBufferRef, QTMovieFrameImageType,
    [NSNumber numberWithBool:YES], QTMovieFrameImageHighQuality,
    nil];
CVPixelBufferRef buffer = [qtMovie frameImageAtTime:QTMakeTime(lastFrame, movie.timeScale)
    withAttributes:dict error:&error];

Рамка выглядит действительной. Он имеет правильную ширину и высоту. Но, похоже, он имеет тип k32ARGBPixelFormat, когда я делаю:

OSType type = CVPixelBufferGetPixelFormatType(buffer);

Предполагая, что я делаю это неправильно - каков правильный метод получения кадра типа k2vuyPixelFormat из фильма? Или, если это невозможно, как проще всего выполнить преобразование RGB-YUV в CVPixelBuffer типа k2vuyPixelFormat? Скорость здесь мне не нужна (это разовая, однокадровая операция).

7 ноября 20008 Тим Монро из QuickTime Engineering отвечает:

В настоящее время нет возможности делать то, что вы хотите, через frameImageAtTime. Я бы посоветовал подать заявку на улучшение.

person Pierre Houston    schedule 04.09.2011