VTDecompressionSession - распределение IOS-поверхности постепенно увеличивается - PullRequest
0 голосов
/ 18 февраля 2019

Я использую VTDecompressionSession для декодирования потока .h264.Декодер работает как положено, и я получаю обратно правильно декодированные буферы.Тем не менее, я вижу постепенное увеличение «Созданных и постоянных» выделений в инструменте XCode «Распределения».Как показано на скриншоте, их можно отнести к буферам IOSurface, которые декодер выделяет внутри, и они не будут освобождены даже после освобождения VTDecompressionSession.Я видел, как это происходило как в синхронном декодировании, так и в асинхронных обратных вызовах decompressionSessionDecodeFrameCallback.Количество оставшихся кадров является случайным по появлению и времени.Размер этих буферов в точности равен размеру декодированного кадра.Я вызываю VTDecompressionSessionWaitForAsynchronousFrames перед тем, как аннулировать сеанс декодера, но эти выделения не исчезают. Есть ли способ освободить эти буферы IOSurface по окончании сеанса декодера?

Это схема моей работы декодера.Создать сеанс декодера

const void *values[] = { CFNumberCreate(NULL, kCFNumberSInt32Type, &v) };       
attrs                = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);


VTDecompressionOutputCallbackRecord callBackRecord;
callBackRecord.decompressionOutputCallback = decompressionSessionDecodeFrameCallback;
callBackRecord.decompressionOutputRefCon = (__bridge void *)self;
VTDecompressionSessionCreate(kCFAllocatorDefault,
                                          _decoderFormatDescription,
                                          NULL,   
                                          attrs,
                                          &callBackRecord,
                                          &_decoderSession);

Вызов для выполнения декодирования, когда готов пакет NALU

CMSampleBufferRef sampleBuffer = nil;
const size_t sampleSizeArray[] = {packetLen};    
CMSampleTimingInfo sampleTimeinfo ={CMTimeMake(1,FPS), CMTimeMake(presentationTS, 1000000), kCMTimeInvalid};
CMSampleBufferCreateReady(kCFAllocatorDefault, blockBuffer, _decoderFormatDescription ,
                                       1, 1, &sampleTimeinfo, 1, sampleSizeArray, &sampleBuffer);
flags = kVTDecodeFrame_EnableAsynchronousDecompression;

VTDecompressionSessionDecodeFrame(_decoderSession,
                                          sampleBuffer,
                                          flags,
                                          &sampleBuffer,
                                          &flagOut);

Обратный вызов

void decompressionSessionDecodeFrameCallback{

    CVPixelBufferLockBaseAddress(imageBuffer,0);
    .... 
    send to display
    ....
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
}

Завершение сеанса декодера

VTDecompressionSessionWaitForAsynchronousFrames(_decoderSession);
VTDecompressionSessionInvalidate(_decoderSession);
CFRelease(_decoderSession);

enter image description here

...