AVAssetReaderTrackOutput зависает на copyNextSampleBuffer

Я столкнулся с проблемой AVAssetWritter. Иногда случается, что мой сеанс видеозаписи просто зависает. После проверки потоков, которые в настоящее время работают на моем устройстве, я обнаружил, что вся обработка видео ждет возврата copyNextSampleBuffer. Я не знаю, что может вызвать эту проблему. Кто-нибудь успешно преодолел эту проблему?

Ниже приведена дампа потока, снятая с инструментов. Он заканчивается на mach_msg_trap. Стек потока

Цикл обработки видео

while ([self.assetWriterVideoInput isReadyForMoreMediaData] && !(*completedOrFailed) && !self.cancelled)
    {
        @autoreleasepool {


            CMSampleBufferRef sampleBuffer = [self.assetReaderVideoOutput copyNextSampleBuffer];



            CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
            CVPixelBufferRef croppedBuffer = NULL;
            NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                     [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                                     [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
            CVPixelBufferCreate(kCFAllocatorDefault, self.outputSize.width, self.outputSize.height, CVPixelBufferGetPixelFormatType(pixelBuffer), (__bridge CFDictionaryRef) options, &croppedBuffer);
            CIImage *img = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer];

            // img processing


            [self.context render:img toCVPixelBuffer:croppedBuffer];


            if (sampleBuffer != NULL)
            {

                BOOL success = [self.avPixelAdaptor appendPixelBuffer:croppedBuffer withPresentationTime:sampleTime];

                CFRelease(sampleBuffer);
                sampleBuffer = NULL;
                *completedOrFailed = !success;
            }
            else
            {
                *completedOrFailed = YES;
            }
            CVPixelBufferRelease(croppedBuffer);
        }
    }
}

Update

Исходный актив для считывателя активов AVMutableComposition, который состоит из нескольких AVURLAsset, которые указывают на библиотеку фотографий (например, url = "assets-library://asset/asset.MOV? id = 4CA9A2C6-F2D4-4FDF- AAEC-6335B9BD840A & внутр = MOV" ). Из каждого источника актива берется 2 секунды, которые начинаются после 0,6 с исходного ресурса. Если все исходные ресурсы начинаются с 0, тогда обработка видео никогда не зависает.

Резюме

Основной вопрос: каковы условия, которые могут привести к тому, что copyNextSampleBuffer будет ждать выхода навсегда. В документации не упоминается такая ситуация.

Ответ 1

Я не вижу, чтобы вы пометили ввод как завершенный и завершили сеанс в своем коде, как показано ниже. Вы называли эти финализаторы?

//Finish the session:
[writerInput markAsFinished];
[videoWriter endSessionAtSourceTime:totalDuration];

[videoWriter finishWritingWithCompletionHandler:^{

// Handle videoWriter.status here

}];