2015-01-29 1 views
4

iOS 용 WebRTC 앱에서 작업하고 있습니다. 내 목표는 WebRTC 개체의 비디오를 녹화하는 것입니다.RTCI420Frame이 이미지 또는 텍스처에 적용됩니다.

이 메서드를 제공하는 대리자 RTCVideoRenderer가 있습니다.

-(void)renderFrame:(RTCI420Frame *)frame{ 
} 

내 질문은 : 나는 쇼 이미지에 대한 유용한 객체의 객체 RTCI420Frame를 변환하거나 디스크에 저장할 수있는 방법.

답변

2

RTCI420 프레임은 YUV420 형식을 사용합니다. OpenCV를 사용하여 RGB로 쉽게 변환 한 다음 UIImage로 변환 할 수 있습니다. 있는지 확인 #import <RTCI420Frame.h>

-(void) processFrame:(RTCI420Frame *)frame { 
    cv::Mat mYUV((int)frame.height + (int)frame.chromaHeight,(int)frame.width, CV_8UC1, (void*) frame.yPlane); 
    cv::Mat mRGB((int)frame.height, (int)frame.width, CV_8UC1); 
    cvtColor(mYUV, mRGB, CV_YUV2RGB_I420); 

    UIImage *image = [self UIImageFromCVMat:mRGB]; 
} 

-(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat 
{ 
    NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()]; 
    CGColorSpaceRef colorSpace; 

    if (cvMat.elemSize() == 1) { 
     colorSpace = CGColorSpaceCreateDeviceGray(); 
    } else { 
     colorSpace = CGColorSpaceCreateDeviceRGB(); 
    } 

    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 

    // Creating CGImage from cv::Mat 
    CGImageRef imageRef = CGImageCreate(cvMat.cols, 
             cvMat.rows, 
             8, 
             8 * cvMat.elemSize(), 
             cvMat.step[0], 
             colorSpace, 
             kCGImageAlphaNone|kCGBitmapByteOrderDefault, 
             provider, 
             NULL, 
             false, 
             kCGRenderingIntentDefault 
             ); 


    // Getting UIImage from CGImage 
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef]; 
    CGImageRelease(imageRef); 
    CGDataProviderRelease(provider); 
    CGColorSpaceRelease(colorSpace); 

    return finalImage; 
} 

당신이 어떤 비디오 프로세싱을하고, 특히 당신은 별도의 스레드에서이 작업을 수행 할 수 있습니다. 또한 .mm 파일 확장명을 사용하여 C++을 사용할 수 있도록하십시오.

OpenCV를 사용하지 않으려면 수동으로 수행 할 수 있습니다. 다음 코드는 작동하지만 색상이 엉망이고 몇 초 후에 충돌이 발생합니다.

int width = (int)frame.width; 
int height = (int)frame.height; 

uint8_t *data = (uint8_t *)malloc(width * height * 4); 

const uint8_t* yPlane = frame.yPlane; 
const uint8_t* uPlane = frame.uPlane; 
const uint8_t* vPlane = frame.vPlane; 

for (int i = 0; i < width * height; i++) { 
    int rgbOffset = i * 4; 
    uint8_t y = yPlane[i]; 
    uint8_t u = uPlane[i/4]; 
    uint8_t v = vPlane[i/4]; 

    uint8_t r = y + 1.402 * (v - 128); 
    uint8_t g = y - 0.344 * (u - 128) - 0.714 * (v - 128); 
    uint8_t b = y + 1.772 * (u - 128); 

    data[rgbOffset] = r; 
    data[rgbOffset + 1] = g; 
    data[rgbOffset + 2] = b; 
    data[rgbOffset + 3] = UINT8_MAX; 
} 

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef gtx = CGBitmapContextCreate(data, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast); 
CGImageRef cgImage = CGBitmapContextCreateImage(gtx); 
UIImage *uiImage = [[UIImage alloc] initWithCGImage:cgImage]; 

free(data); 
관련 문제