Я получил декодированный AVFrame, формат которого показывает 160/Videotoolbox_vld
. После того, как погуглил несколько статей (здесь) и просмотрела исходный код FFmpeg (здесь и здесь), дескриптор CVBuffer
должен быть в AVFrame.data[3]
. Но CVBuffer
, которое я получил, кажется недействительным, любая функция CVPixelBufferGetXXX()
возвращает 0 или ноль.
Если бы я использовал av_hwframe_transfer_data()
, как example/hw_decode. c семпл можно загрузить из буфера HW в SW. Его AVFrame.format
будет nv12
. После преобразования с помощью sws_scale
в bgra
образец может быть показан для просмотра с правильным содержанием.
Я думаю, что декодированный кадр VideoToolbox в порядке. То, как я конвертирую AVFrame.data[3]
в CVBuffer
, может быть неправильным. Только что научился обращаться к указателю c в Swift, но я не уверен, как правильно читать дескриптор ресурса (CVBuffer) в указателе.
Ниже показано, как я пытаюсь извлечь CVBuffer из AVFrame.
var pFrameOpt: UnsafeMutablePointer<AVFrame>? = av_frame_alloc()
avcodec_receive_frame(..., pFrameOpt)
let data3: UnsafeMutablePointer<UInt8>? = pFrameOpt?.pointee.data.3
data3?.withMemoryRebound(to: CVBuffer.self, capacity: 1) { pCvBuf in
let fW = pFrameOpt!.pointee.width // print 3840
let fH = pFrameOpt!.pointee.height // print 2160
let fFmt = pFrameOpt!.pointee.format // print 160
let cvBuf: CVBuffer = pCvBuf.pointee
let a1 = CVPixelBufferGetDataSize(cvBuf) // print 0
let a2 = CVPixelBufferGetPixelFormatType(cvBuf) // print 0
let a3 = CVPixelBufferGetWidth(cvBuf) // print 0
let a4 = CVPixelBufferGetHeight(cvBuf) // print 0
let a5 = CVPixelBufferGetBytesPerRow(cvBuf) // print 0
let a6 = CVPixelBufferGetBytesPerRowOfPlane(cvBuf, 0) // print 0
let a7 = CVPixelBufferGetWidthOfPlane(cvBuf, 0) // print 0
let a8 = CVPixelBufferGetHeightOfPlane(cvBuf, 0) // print 0
let a9 = CVPixelBufferGetPlaneCount(cvBuf) // print 0
let a10 = CVPixelBufferIsPlanar(cvBuf) // print false
let a11 = CVPixelBufferGetIOSurface(cvBuf) // print nil
let a12 = CVPixelBufferGetBaseAddress(cvBuf) // print nil
let a13 = CVPixelBufferGetBaseAddressOfPlane(cvBuf, 0) // print nil
let b1 = CVImageBufferGetCleanRect(cvBuf) // print 0, 0, 0, 0
let b2 = CVImageBufferGetColorSpace(cvBuf) // print nil
let b3 = CVImageBufferGetDisplaySize(cvBuf) // print 0, 0, 0, 0
let b4 = CVImageBufferGetEncodedSize(cvBuf) // print 0, 0, 0, 0
let b5 = CVImageBufferIsFlipped(cvBuf) // print false
// bad exec
var cvTextureOut: CVMetalTexture?
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, ..., cvBuf, nil, .bgra8Unorm, 3840, 2160, 0, ...)
}