1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| /// NV12 to I420 + (CVPixelBufferRef)I420PixelBufferWithNV12:(CVImageBufferRef)cvpixelBufferRef { CVPixelBufferLockBaseAddress(cvpixelBufferRef, 0); //图像宽度(像素) size_t pixelWidth = CVPixelBufferGetWidth(cvpixelBufferRef); //图像高度(像素) size_t pixelHeight = CVPixelBufferGetHeight(cvpixelBufferRef); //获取CVPixelBufferRef中的y数据 const uint8* y_frame = (uint8*)CVPixelBufferGetBaseAddressOfPlane(cvpixelBufferRef,0); //获取CMVImageBufferRef中的uv数据 const uint8* uv_frame = (uint8*)CVPixelBufferGetBaseAddressOfPlane(cvpixelBufferRef,1); //y stride size_t plane1_stride = CVPixelBufferGetBytesPerRowOfPlane (cvpixelBufferRef, 0); //uv stride size_t plane2_stride = CVPixelBufferGetBytesPerRowOfPlane (cvpixelBufferRef, 1); //yuv_size(内存空间) size_t frame_size = pixelWidth*pixelHeight*3/2; //开辟frame_size大小的内存空间用于存放转换好的i420数据 uint8* buffer = (unsigned char *)malloc(frame_size); //buffer为这段内存的首地址,plane1_size代表这一帧中y数据的长度 uint8* dst_u = buffer + pixelWidth*pixelHeight; //dst_u为u数据的首地,plane1_size/4为u数据的长度 uint8* dst_v = dst_u + pixelWidth*pixelHeight/4; //libyuv转换 int ret = NV12ToI420(y_frame, (int)plane1_stride, uv_frame, (int)plane2_stride, buffer, (int)pixelWidth, dst_u, (int)pixelWidth/2, dst_v, (int)pixelWidth/2, (int)pixelWidth, (int)pixelHeight ); if (ret) { return NULL; } NSDictionary *pixelAttributes = @{(id)kCVPixelBufferIOSurfacePropertiesKey : @{}}; CVPixelBufferRef pixelBuffer = NULL; CVReturn result = CVPixelBufferCreate(kCFAllocatorDefault, pixelWidth, pixelHeight, kCVPixelFormatType_420YpCbCr8Planar, (__bridge CFDictionaryRef)(pixelAttributes), &pixelBuffer); CVPixelBufferLockBaseAddress(pixelBuffer, 0); size_t d = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); size_t ud = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1); size_t vd = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 2); unsigned char* dsty = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); unsigned char* dstu = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); unsigned char* dstv = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 2); unsigned char* srcy = buffer; for (unsigned int rIdx = 0; rIdx < pixelHeight; ++rIdx, srcy += pixelWidth, dsty += d) { memcpy(dsty, srcy, pixelWidth); } unsigned char* srcu = buffer + pixelHeight*pixelWidth; for (unsigned int rIdx = 0; rIdx < pixelHeight/2; ++rIdx, srcu += pixelWidth/2, dstu += ud) { memcpy(dstu, srcu, pixelWidth/2); } unsigned char* srcv = buffer + pixelHeight*pixelWidth*5/4; for (unsigned int rIdx = 0; rIdx < pixelHeight/2; ++rIdx, srcv += pixelWidth/2, dstv += vd) { memcpy(dstv, srcv, pixelWidth/2); } CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); if (result != kCVReturnSuccess) { NSLog(@"Unable to create cvpixelbuffer %d", result); } free(buffer); // CVPixelBufferRelease(cvpixelBufferRef); return pixelBuffer; }
|