如何解决在SwiftUI中捕获期间CVPixelBuffer缩放调整大小
我正在使用TwilioVideo
捕获图像会话并转换为视频。
检查下面的班级代码,
import SwiftUI
import TwilioVideo
class RemoteVideoUIView: UIImageView {
var delegate: VideoViewDelegate?
init(frame: CGRect,delegate: VideoViewDelegate) {
self.delegate = delegate
super.init(frame: frame)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func updateContentMode(for orientation: UIDeviceOrientation) {
self.contentMode = .scaleAspectFill
}
}
extension RemoteVideoUIView: VideoRenderer {
func renderFrame(_ frame: VideoFrame) {
let cgImageOrientation: CGImagePropertyOrientation
cgImageOrientation = .up
DispatchQueue.main.async {
var pixelBuffer: CVPixelBuffer? = nil
CVPixelBufferCreate(
nil,frame.width,frame.height,kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,nil,&pixelBuffer
)
// this is convert to pixelbuffer
if VideoFrameConverter.convertI420toNV12(fromFrame: frame,toPixelBuffer: pixelBuffer!) {
let ciImage = CIImage(cvPixelBuffer: pixelBuffer!)
// here,image is displaying
self.image = UIImage(ciImage: ciImage.oriented(cgImageOrientation))
}
}
}
func updateVideoSize(_ videoSize: CMVideoDimensions,orientation: VideoOrientation) {
print("RemoteVideoView: updateVideoSize called with dimensions \(videoSize.width) x \(videoSize.height)")
}
}
struct RemoteVideoView: UIViewRepresentable {
@EnvironmentObject var sessionManager: SessionManager
func makeUIView(context: Context) -> RemoteVideoUIView {
let remoteView = RemoteVideoUIView(
frame: UIScreen.main.bounds,delegate: self.sessionManager
)
remoteView.backgroundColor = .black
self.sessionManager.addRemotePartecipantView(remoteView)
return remoteView
}
func updateUIView(_ uiView: RemoteVideoUIView,context: Context) {
print("Updating instance of RemoteVideoView")
}
}
#if DEBUG
struct RemoteVideoView_Previews: PreviewProvider {
static var sessionManager = SessionManager()
static var previews: some View {
RemoteVideoView()
.environmentObject(sessionManager)
.padding(.all)
}
}
#endif
第一次完美运行。
但是,当其他终端用户刷新或重新连接视频时,此时“图像”将放大并看起来像是布局损坏。
我不明白为什么它会缩小。
我已经设置了视图固定高度。
另外,我正在使用下面的libyuv
转换为CVPixelBuffer
检查此类:
struct VideoFrameConverter {
// ...
@discardableResult
static func convertI420toNV12(fromFrame frame: VideoFrame,toPixelBuffer pixelBuffer: CVPixelBuffer) -> Bool {
//let sourceFormat = frame.imageBuffer.pixelFormat
let sourceFormat = CVPixelBufferGetPixelFormatType(frame.imageBuffer)
let destinationFormat = CVPixelBufferGetPixelFormatType(pixelBuffer)
guard destinationFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange else {
preconditionFailure("Destination format is not bi-planar! Check the attributes of the pixelBufferPool.")
}
guard sourceFormat == kCVPixelFormatType_420YpCbCr8Planar || sourceFormat == kCVPixelFormatType_420YpCbCr8PlanarFullRange else {
preconditionFailure("Source is not planar! Can't pack or copy these pixels!")
}
CVPixelBufferLockBaseAddress(frame.imageBuffer,CVPixelBufferLockFlags(rawValue: 0))
CVPixelBufferLockBaseAddress(pixelBuffer,CVPixelBufferLockFlags(rawValue: 0))
defer {
CVPixelBufferUnlockBaseAddress(frame.imageBuffer,CVPixelBufferLockFlags(rawValue: 0))
CVPixelBufferUnlockBaseAddress(pixelBuffer,CVPixelBufferLockFlags(rawValue: 0))
}
let src_yAddress = CVPixelBufferGetBaseAddressOfPlane(frame.imageBuffer,0)?.assumingMemoryBound(to: UInt8.self)
let src_uAddress = CVPixelBufferGetBaseAddressOfPlane(frame.imageBuffer,1)?.assumingMemoryBound(to: UInt8.self)
let src_vAddress = CVPixelBufferGetBaseAddressOfPlane(frame.imageBuffer,2)?.assumingMemoryBound(to: UInt8.self)
let dst_yAddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer,0)?.assumingMemoryBound(to: UInt8.self)
let dst_uvAddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer,1)?.assumingMemoryBound(to: UInt8.self)
let src_yBytesPerRow = Int32(CVPixelBufferGetBytesPerRowOfPlane(frame.imageBuffer,0))
let src_uBytesPerRow = Int32(CVPixelBufferGetBytesPerRowOfPlane(frame.imageBuffer,1))
let src_vBytesPerRow = Int32(CVPixelBufferGetBytesPerRowOfPlane(frame.imageBuffer,2))
let dst_yBytesPerRow = Int32(CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer,0))
let dst_uvBytesPerRow = Int32(CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer,1))
let width = Int32(frame.width)
let height = Int32(frame.height)
let success = I420ToNV12(src_yAddress,src_yBytesPerRow,src_uAddress,src_uBytesPerRow,src_vAddress,src_vBytesPerRow,dst_yAddress,dst_yBytesPerRow,dst_uvAddress,dst_uvBytesPerRow,width,height
)
return success == 0
}
我尝试了很多事情,但是结果还是一样,有什么办法可以解决这个问题?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。