Сложность записи пиксельного буфера в Asset Writer на некоторых устройствах

Я работаю над функцией в своем приложении для записи изображений из моего буфера образцов в AVAssetWriter. Любопытно, что это прекрасно работает на 10,5-дюймовом iPad Pro, но вызывает сбой на 7,9-дюймовом iPad Mini 2. Я не могу понять, как один и тот же код может быть проблематичным на двух разных устройствах. Но вот мой код;

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

    // Setup the pixel buffer image
    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!

    // Setup the format description
    let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer)!

    // Setup the current video dimensions
    self.currentVideoDimensions = CMVideoFormatDescriptionGetDimensions(formatDescription)

    // Setup the current sample time
    self.currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer)

    // Handle record
    if self.isCapturing {

        // Setup auto release pool
        autoreleasepool {

            // Setup the output image
            let outputImage = CIImage(cvPixelBuffer: pixelBuffer)

            // Ensure the video writer is ready for more data
            if self.videoWriter?.assetWriterPixelBufferInput?.assetWriterInput.isReadyForMoreMediaData == true {

                // Setup the new pixel buffer (THIS IS WHERE THE ERROR OCCURS)
                var newPixelBuffer: CVPixelBuffer? = nil

                // Setup the pixel buffer pool
                CVPixelBufferPoolCreatePixelBuffer(nil, (self.videoWriter?.assetWriterPixelBufferInput!.pixelBufferPool!)!, &newPixelBuffer)

                // Render the image to context
                self.context.render(outputImage, to: newPixelBuffer!, bounds: outputImage.extent, colorSpace: nil)

                // Setup a success case
                let success = self.videoWriter?.assetWriterPixelBufferInput?.append(newPixelBuffer!, withPresentationTime: self.currentSampleTime!)

                // Ensure the success case exists
                guard let mySuccess = success else { return }

                // If unsuccessful, log
                if !mySuccess {
                    print("Error with the sample buffer.  Check for dropped frames.")
                }
            }
        }
    }
}

Я получаю сообщение об ошибке, что newPixelBuffer равен нулю, но опять же, только на 7,9-дюймовом iPad. iPad Pro работает без ошибок. Есть мысли? Спасибо!


person ZbadhabitZ    schedule 15.02.2018    source источник
comment
Каково возвращаемое значение вызова CVPixelBufferPoolCreatePixelBuffer?   -  person Valérian    schedule 16.02.2018
comment
Все, что я получаю, это Thread 3: Unexpectedly found nil while unwrapping an Optional value при запуске на проблемном устройстве.   -  person ZbadhabitZ    schedule 16.02.2018
comment
Придется задать тот же вопрос, что и Валериан. Что возвращает CFPixelBufferPoolCreatePixelBuffer? Согласно документации, эта функция возвращает CVReturn, содержащее значение ошибки, которое предположительно объясняет, почему она не работает. Что это такое?   -  person Charles Srstka    schedule 26.04.2018
comment
Не уверен, что я делаю это правильно, но я установил var status:CVReturn = CVPixelBufferPoolCreatePixelBuffer(nil, (self.videoWriter?.assetWriterPixelBufferInput!.pixelBufferPool!)!, &newPixelBuffer). При сбое возвращается 65552448. Дайте мне знать, если это может быть неправильно.   -  person ZbadhabitZ    schedule 26.04.2018


Ответы (1)


В конце концов я решил эту проблему, отследив проблему до выбранного мной кодека в настройках видеовыхода моего Asset Writer. У меня был установлен кодек:

let codec: AVVideoCodecType = AVVideoCodecType.hevc

Проведя небольшое исследование, я нашел эту статью, в которой указано, что только определенные устройства могут < em>захват мультимедиа в формате HEVC. Поскольку моим первым устройством был 10,5-дюймовый iPad Pro, он захватывал мультимедиа без проблем. Моим вторым устройством был iPad Mini, из-за чего исходная проблема возникала каждый раз, когда я пытался захватить.

С тех пор я изменил свой выбор кодека на:

let codec: AVVideoCodecType = AVVideoCodecType.h264, и теперь проблема исчезла.

person ZbadhabitZ    schedule 17.05.2018