I am making a simple pipeline that gets images from AVCaptureSession, processes them in OpenCV, and then renders them in OpenGL. It is based on RosyWriter but without the audio and recording capabilities. The OpenCV processing looks like
- (void)processPixelBuffer: (CVImageBufferRef)pixelBuffer
{
CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
int bufferWidth = CVPixelBufferGetWidth(pixelBuffer);
int bufferHeight = CVPixelBufferGetHeight(pixelBuffer);
unsigned char *pixel = (unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer);
cv::Mat image = cv::Mat(bufferWidth,bufferHeight,CV_8UC4,pixel);
//do any processing
[self setDisplay_matrix:image];
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
}
In this function thus far I have not copied any memory and I would like to keep it that way. The issue is that pixelBuffer may still own the memory contained in display_image. The processing code may or may not allocate new memory and store it in image. If the processing did not allocate new memory I have to pass pixelBuffer around with display_matrix to keep the data from being erased. Is there a way for me to take ownership of the memory? I want to destroy pixelBuffer without destroying the memory it points too.
On a related note, what exactly does LockBaseAddress do? If I were passing around a cv::Mat, CVImageBufferRef pair would I have to lock the base address every time i want to modify/use the data with cv::Mat?
You can create data provider from base address data without copying, and then create UIImage from this data provider. To avoid buffer reusing while you referring this image you need to retain sample buffer and lock base address. They should be unlocked and released automatically when you will forget this image object:
I've got
imageFromData
from this project https://github.com/k06a/UIImage-DecompressAndMap/blob/master/UIImage%2BDecompressAndMap.m and adopted it a little bit:You also need to provide
unlock_function
: