Я пытался сделать обратный вызов сжатия, который отправляет сжатые данные в другую часть процесса, но когда я помещаю строку для отправки данных, я возвращаю эту ошибку
Член экземпляра «ptManager» не может использоваться для типа «SampleHandler».
Вот код обратного вызова:
let vtCallback : @convention(c) (UnsafeMutableRawPointer?, UnsafeMutableRawPointer?, OSStatus, VTEncodeInfoFlags, CMSampleBuffer?) -> Swift.Void =
{
(outputCallbackRefCon, sourceFrameRefCon, status, infoFlags, sampleBuffer) -> Swift.Void in
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer!)
CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
let height = CVPixelBufferGetHeight(imageBuffer!)
let src_buff = CVPixelBufferGetBaseAddress(imageBuffer!)
let data = NSData(bytes: src_buff, length: bytesPerRow * height)
CVPixelBufferUnlockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
NSLog("Size: " + String((data as Data).count))
ptManager.sendObject(object: data, type: 102)
}
Я просмотрел другие решения для этого, но не нашел ничего, что работало бы, потому что, если я установлю ptManager
на static, это вызовет гораздо больше проблем, чем решит, и то же самое с удалением =
.
Вся помощь в этом будет оценена!
Редактировать
Вот некоторые из более ранних кодов, которые я пробовал, которые могли работать, но никогда не вызывались, когда я назначал их обратному вызову:
func compressionOutputCallback(
outputCallbackRefCon:UnsafeMutableRawPointer?,
sourceFrameRefCon:UnsafeMutableRawPointer?,
status:OSStatus,
infoFlags:VTEncodeInfoFlags,
sampleBuffer:CMSampleBuffer) {
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
let height = CVPixelBufferGetHeight(imageBuffer!)
let src_buff = CVPixelBufferGetBaseAddress(imageBuffer!)
let data = NSData(bytes: src_buff, length: bytesPerRow * height)
CVPixelBufferUnlockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
NSLog("Size: " + String((data as Data).count))
ptManager.sendObject(object: data, type: 102)
if status != noErr{
NSLog("SBC: Error encoding video", status)
print("SBC: Error encoding video", status)
return
}
print("SBC: compressionOutputCallback dataBuffer", status)
}
//Does not get called at all
Редактировать 2:
Вот где используется обратный вызов:
VTCompressionSessionCreate(allocator: nil, width: 1080, height: 1920, codecType: kCMVideoCodecType_H264,encoderSpecification: nil, imageBufferAttributes: nil, compressedDataAllocator: nil, outputCallback: vtCallback as? VTCompressionOutputCallback, refcon: nil, compressionSessionOut: sessionOut)
@convention(c)
. Функции C в некотором смысле глобальны. Они не похожи на замыкания, которые размещаются в своей собственной памяти и может захватывать переменные Таким образом, функции C не могут получить доступ к неглобальным (или нестатическим) значениям, таким какptManager
, потому что негде хранить эту заключенную ссылку. - person Alexander   schedule 15.10.2020void *userInfo
. Этот указатель можно передать в вызов функции, а API передаст его в указатель функции обратного вызова в качестве одного из аргументов. Затем вы можете преобразовать этотvoid *userInfo
в конкретный тип, который вы установили. ЭтотuserInfo
позволяет вам захватывать и передавать контекст, подобно тому, как замыкания автоматически заключают в себе переменные и дают вам доступ к ним. Не похоже, чтобы этот обратный вызов имел такой параметр, хотя. - person Alexander   schedule 15.10.2020ptManager = self
позже, что вызывает проблемы. Я также разместил часть кода, который я пробовал ранее, но он вообще не вызывался на случай, если это поможет. - person Z3R0   schedule 15.10.2020ptManager
? Вы должны показать контекст, где фактически используетсяvtCallback
- person Alexander   schedule 15.10.2020vtCallback
. - person Z3R0   schedule 15.10.2020void *outputCallbackRefCon
дляVTCompressionSessionCreate
- это именно тот механизмuserInfo
, о котором я говорил.VTCompressionSessionCreate
примет это значение и передаст его в ваш обратный вызов какvoid *sourceFrameRefCon
. Вы можете использовать это для контрабанды в любом контексте, напримерself
илиself.ptManager
. Дайте мне знать, если дублированный вопрос не полностью отвечает на ваши вопросы. - person Alexander   schedule 15.10.2020Unmanaged.passUnretained(self).toOpaque()
выдает ошибку:Cannot invoke 'passUnretained' with an agrument list of type '((SampleHandler) -> () -> (SampleHandler))'
. - person Z3R0   schedule 15.10.2020