У меня есть проект, в котором мне нужно декодировать видео h264 из живого сетевого потока и в конечном итоге получить текстуру, которую я могу отобразить в другом фреймворке (Unity3D) на устройствах iOS. Я могу успешно декодировать видео с помощью VTDecompressionSession, а затем получить текстуру с помощью CVMetalTextureCacheCreateTextureFromImage (или варианта OpenGL). Он отлично работает, когда я использую кодировщик с малой задержкой, и буферы изображений выводятся в порядке отображения, однако, когда я использую обычный кодировщик, буферы изображений не выводятся в порядке отображения, и изменение порядка буферов изображений, по-видимому, намного сложнее, чем Я ожидал.
Первая попытка состояла в том, чтобы установить VTDecodeFrameFlags с помощью kVTDecodeFrame_EnableAsynchronousDecompression и kVTDecodeFrame_EnableTemporalProcessing... Однако оказывается, что VTDecompressionSession может игнорировать флаг и делать все, что захочет... и в моем случае он предпочитает игнорировать флаг и по-прежнему выводит буфер в порядке кодирования (не в порядке отображения). По сути бесполезен.
Следующая попытка состояла в том, чтобы связать буферы изображения с отметкой времени презентации, а затем передать их в вектор, который позволил бы мне получить нужный мне буфер изображения при создании текстуры. Проблема, по-видимому, заключается в том, что буфер изображения, который входит в VTDecompressionSession, который связан с отметкой времени, больше не является тем же самым буфером, который выходит, что по существу делает отметку времени бесполезной.
Например, вход в декодер...
VTDecodeFrameFlags flags = kVTDecodeFrame_EnableAsynchronousDecompression;
VTDecodeInfoFlags flagOut;
// Presentation time stamp to be passed with the buffer
NSNumber *nsPts = [NSNumber numberWithDouble:pts];
VTDecompressionSessionDecodeFrame(_decompressionSession, sampleBuffer, flags,
(void*)CFBridgingRetain(nsPts), &flagOut);
На стороне обратного вызова...
void decompressionSessionDecodeFrameCallback(void *decompressionOutputRefCon, void *sourceFrameRefCon, OSStatus status, VTDecodeInfoFlags infoFlags, CVImageBufferRef imageBuffer, CMTime presentationTimeStamp, CMTime presentationDuration)
{
// The presentation time stamp...
// No longer seems to be associated with the buffer that it went in with!
NSNumber* pts = CFBridgingRelease(sourceFrameRefCon);
}
При упорядочении метки времени на стороне обратного вызова монотонно увеличиваются с ожидаемой скоростью, но буферы располагаются не в правильном порядке. Кто-нибудь видит, где я делаю ошибку здесь? Или умеете определять порядок буферов на стороне обратного вызова? На данный момент я перепробовал практически все, о чем только мог подумать.