2011-05-31 10 views
24

Am Captuing usando marco de trabajo AVFoundation .Con la ayuda de la documentación de Apple http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/03_MediaCapture.html%23//apple_ref/doc/uid/TP40010188-CH5-SW2Como llegar Bytes de CMSampleBufferRef, enviar a través de la red de vídeo

Ahora que hice Siguiendo cosas

1.Created videoCaptureDevice
2.Created AVCaptureDeviceInput y conjunto videoCaptureDevice
3.Created AVCaptureVideoDataOutput e implementado Delegate
4.Created AVCaptureSession - s et entrada como de salida AVCaptureDeviceInput y establecer como método AVCaptureVideoDataOutput

5.In AVCaptureVideoDataOutput Delegado

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 

tengo CMSamplebuffer y convertida en UIImage y probado para imprimir usando UIImageView

[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES]; 

Cada cosa ha ido bien hasta esto ........

MI problema ES, Necesito enviar video fra mes a través de Socket UDP. Aunque seguir uno es una mala idea, lo intenté, UIImage a NSData y Send a través de UDP Pocket. Pero nos dieron por lo Retraso en vídeo Processing.Mostly problema debido a UIImage NSDate

Así que por favor me dan solución para mi problema

1) Cualquier forma de convertir CMSampleBUffer o CVImageBuffer a NSData ??
2) Me gusta el servicio de cola de audio y la cola de video para almacenar UIImage y hacer UIImage a NSDate y enviar ???

si estoy montando detrás del algoritmo incorrecto Por favor camino me en la dirección de escritura

Gracias por adelantado

Respuesta

30

Aquí hay un código para obtener en el búfer. Este código supone una imagen plana (por ejemplo, BGRA).

NSData* imageToBuffer(CMSampleBufferRef source) { 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(source); 
    CVPixelBufferLockBaseAddress(imageBuffer,0); 

    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 
    void *src_buff = CVPixelBufferGetBaseAddress(imageBuffer); 

    NSData *data = [NSData dataWithBytes:src_buff length:bytesPerRow * height]; 

    CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 
    return [data autorelease]; 
} 

Un enfoque más eficiente sería utilizar un NSMutableData o un grupo de búferes.

Enviar una imagen de 480x360 por segundo requerirá una conexión de 4.1Mbps asumiendo 3 canales de color.

+0

Gracias por su respuesta. CVimagebuffer a NSdata está bien.Tengo una pequeña duda, en el receptor i No pude recuperar el CVimagebuffer, bcoz que necesita alto, ancho por separado y bytes por fila también –

+0

Puede enviar esto en el 'encabezado' de datos si lo desea. [ancho: 16bits] [altura: 16bits] [número de secuencia: 16bits] [count: 16bit] [data fragment]. Hay otros problemas con su configuración. Incluso asumiendo una MTU de 1500, sus imágenes se distribuirán en muchos paquetes UDP. Vas a perder paquetes dada la velocidad de bits que necesitas. Sugiero que uses TCP. No veo ninguna ventaja en el uso de UDP, ya que no podrá enviar más de 2 fotogramas por segundo desde el teléfono a través de una LAN/Wifi (@ 480x360). Y a este ritmo, debe preocuparse por la pérdida de datos de video. –

+0

Alternativamente, podría enviar la información del video con anticipación al receptor o en el primer paquete UDP. Todavía necesitará alguna forma de identificar fragmentos de imágenes. –

2

Uso CMSampleBufferGetImageBuffer para obtener CVImageBufferRef del tampón de muestra, a continuación, obtener los datos de mapa de bits de ella con CVPixelBufferGetBaseAddress. Esto evita copiar innecesariamente la imagen.

+0

Gracias por su respuesta. ¿Ya utilicé CVPixelBufferGetBaseAddress pero puedo usar eso como bytes? y usando solo eso, ¿puedo dibujar la imagen en el lado del receptor? –

+0

Sí, esos son bytes. Hay CVPixelBufferGetHeight() * CVPixelBufferGetBytesPerRow() de ellos. Y si lo haces bien, podrás reconstruir la imagen en el otro extremo. –

+0

¿Funciona esto igual para el formato planar? ¿O es necesario usar CVPixelBufferGetHeightOfPlane y CVPixelBufferGetBytesPerRowOfPlane en su lugar? –

Cuestiones relacionadas