IOS实时视频聊天问题
因为项目需要,在视频聊天时,要对视频流进行处理,看到CallViewController.m里面的captureOutput方法,似乎对视频输出进行了压缩和旋转,能否大概解释一下这块的逻辑?还用为什么要调用YUV420spRotate90方法,进行旋转?
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
if (_callSession.status != eCallSessionStatusAccepted) {
return;
}
#warning 捕捉数据输出,根据自己需求可随意更改
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
if(CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess)
{
// UInt8 *bufferbasePtr = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer);
UInt8 *bufferPtr = (UInt8 *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
UInt8 *bufferPtr1 = (UInt8 *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 1);
// printf("addr diff1:%d,diff2:%d\n",bufferPtr-bufferbasePtr,bufferPtr1-bufferPtr);
// size_t buffeSize = CVPixelBufferGetDataSize(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
// size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t bytesrow0 = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0);
size_t bytesrow1 = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 1);
// size_t bytesrow2 = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 2);
// printf("buffeSize:%d,width:%d,height:%d,bytesPerRow:%d,bytesrow0 :%d,bytesrow1 :%d,bytesrow2 :%d\n",buffeSize,width,height,bytesPerRow,bytesrow0,bytesrow1,bytesrow2);
if (_imageDataBuffer == nil) {
_imageDataBuffer = (UInt8 *)malloc(width * height * 3 / 2);
}
UInt8 *pY = bufferPtr;
UInt8 *pUV = bufferPtr1;
UInt8 *pU = _imageDataBuffer + width * height;
UInt8 *pV = pU + width * height / 4;
for(int i =0; i < height; i++)
{
memcpy(_imageDataBuffer + i * width, pY + i * bytesrow0, width);
}
for(int j = 0; j < height / 2; j++)
{
for(int i = 0; i < width / 2; i++)
{
*(pU++) = pUV[i<<1];
*(pV++) = pUV[(i<<1) + 1];
}
pUV += bytesrow1;
}
YUV420spRotate90(bufferPtr, _imageDataBuffer, width, height);
[[EaseMob sharedInstance].callManager processPreviewData:(char *)bufferPtr width:width height:height];
/*We unlock the buffer*/
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
}
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
if (_callSession.status != eCallSessionStatusAccepted) {
return;
}
#warning 捕捉数据输出,根据自己需求可随意更改
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
if(CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess)
{
// UInt8 *bufferbasePtr = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer);
UInt8 *bufferPtr = (UInt8 *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
UInt8 *bufferPtr1 = (UInt8 *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 1);
// printf("addr diff1:%d,diff2:%d\n",bufferPtr-bufferbasePtr,bufferPtr1-bufferPtr);
// size_t buffeSize = CVPixelBufferGetDataSize(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
// size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t bytesrow0 = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0);
size_t bytesrow1 = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 1);
// size_t bytesrow2 = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 2);
// printf("buffeSize:%d,width:%d,height:%d,bytesPerRow:%d,bytesrow0 :%d,bytesrow1 :%d,bytesrow2 :%d\n",buffeSize,width,height,bytesPerRow,bytesrow0,bytesrow1,bytesrow2);
if (_imageDataBuffer == nil) {
_imageDataBuffer = (UInt8 *)malloc(width * height * 3 / 2);
}
UInt8 *pY = bufferPtr;
UInt8 *pUV = bufferPtr1;
UInt8 *pU = _imageDataBuffer + width * height;
UInt8 *pV = pU + width * height / 4;
for(int i =0; i < height; i++)
{
memcpy(_imageDataBuffer + i * width, pY + i * bytesrow0, width);
}
for(int j = 0; j < height / 2; j++)
{
for(int i = 0; i < width / 2; i++)
{
*(pU++) = pUV[i<<1];
*(pV++) = pUV[(i<<1) + 1];
}
pUV += bytesrow1;
}
YUV420spRotate90(bufferPtr, _imageDataBuffer, width, height);
[[EaseMob sharedInstance].callManager processPreviewData:(char *)bufferPtr width:width height:height];
/*We unlock the buffer*/
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
}
}
没有找到相关结果
已邀请:
2 个回复
lizg - ……
赞同来自: bzhd333
酷酷宾