2010-12-11 2 views
1

Я хочу получить пиксели изображения с камеры. Я использую CoreFoundation и OpenGL, и я могу отображать изображение, но я хочу делать другие вещи (в другом месте/потоке), поэтому мне нужно их скопировать.копирование пикселей с входа камеры

Это то, что я пробовал: (часть методы AVCaptureVideoDataOutputSampleBufferDelegate)

CVImageBufferRef tmpPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
CVPixelBufferLockBaseAddress(tmpPixelBuffer, 0); 

//APPROACH A 
CFRetain(tmpPixelBuffer); 
if(pixelBuffer!= 0) CFRelease(pixelBuffer); 
pixelBuffer = tmpPixelBuffer; 

//create and bind textureHandle 
if(m_textureHandle==0) m_textureHandle = [self _createVideoTextureUsingWidth:videoDimensions.width Height:videoDimensions.width]; 
glBindTexture(GL_TEXTURE_2D, m_textureHandle); 

unsigned char *linebase = (unsigned char *)CVPixelBufferGetBaseAddress(tmpPixelBuffer); 

//APPROACH B 
unsigned size = videoDimensions.width*videoDimensions.height*4;//since its BGRA 
unsigned char *imageData = malloc(size); 
memcpy(linebase, imageData, size); 
free(imageData); 

//map the texture 
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, videoDimensions.width, videoDimensions.height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, linebase); 

CVPixelBufferUnlockBaseAddress(tmpPixelBuffer, 0); 

В подходе AI попытался удержать буфер отверстия, так что я могу скопировать пиксели позже, когда это необходимо, но я всегда получаю NULL указатель (я не знаю почему)

В подходе BI попробуйте копировать пиксели каждый раз, но тогда opengl renderer покажет черное изображение. Я не знаю, почему, я не изменяю оригинальный буфер?

Заранее спасибо;)

Игнасио

ответ

0

В вашем подходе B, вы освободить ImageData сразу после того, как вы скопировали в буфер пикселя в него. Если вы работаете в режиме отладки, возможно, диспетчер памяти очистит память. В любом случае не вызывайте free(), пока вы не закончите с данными.

+0

Вы правы, но даже если я malloc память перед рукой и освободить ее в методе dealloc, я все равно получаю черный экран. Я понял, что если я положу B после glTexSubImage2D, он отобразит рамку, но мне интересно, почему? Я не обрабатываю исходные данные. Я копирую его. – nacho4d

+0

Ваш вызов memcpy выше фактически перезаписывает содержимое буфера пикселей вашей недавно выделенной памятью. Подпись: void * memcpy (void * destination, const void * source, size_t num); –