2015-06-19 2 views
0

Я создаю приложение для потоковой передачи видео в формате iOS, а библиотека, с которой я работаю, требует, чтобы я отправлял видеоданные, передавая им данные YUV (или я думаю, YCbCr) индивидуально.Получение YUV из CMSampleBufferRef для потоковой передачи видео

У меня установлен делегат, но я не уверен, как добавить отдельные элементы YUV из CMSampleBufferRef. Из-за того, что я видел, многие из справочников Apple ссылаются на захват видеокадров на UIImages.

формат потока

- (BOOL)setupWithError:(NSError **)error 
{ 
    AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:error]; 

    if (! videoInput) { 
     return NO; 
    } 

    [self.captureSession addInput:videoInput]; 

    self.processingQueue = dispatch_queue_create("abcdefghijk", NULL); 

    [self.dataOutput setAlwaysDiscardsLateVideoFrames:YES]; 
    NSNumber *value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]; 

    [self.dataOutput setVideoSettings:[NSDictionary dictionaryWithObject:value 
                    forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; 
    [self.dataOutput setSampleBufferDelegate:self queue:self.processingQueue]; 

    return YES; 
} 

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

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 


    if (! imageBuffer) { 
     return; 
    } 



    uint16_t width = CVPixelBufferGetHeight(imageBuffer); 
    uint16_t height = CVPixelBufferGetHeight(imageBuffer); 

    uint8_t yPlane[??] = ??? 
    uint8_t uPlane[?] = ??? 
    uint8_t vPlane[?] = ??? 

    [self.library sendVideoFrametoFriend:self.friendNumber width:width height:height 
           yPlane:yPlane 
           uPlane:uPlane 
           vPlane:vPlane 
           error:nil]; 
} 

Кто-нибудь есть примеры или ссылки, где я могу понять это?

Обновление Согласно https://wiki.videolan.org/YUV там должно быть больше элементов Y, то есть U/V. Библиотека также не подтверждает это, а также, ничего ниже:

* Y - plane should be of size: height * width 
* U - plane should be of size: (height/2) * (width/2) 
* V - plane should be of size: (height/2) * (width/2) 

ответ

3

ОБНОВЛЕНО Я теперь прочитал, как YUV буфер состоит и это, как вы читаете это. Я также удостоверился, что я не нахожусь на каждом кадре.

Удачи! ;)

//int bufferWidth = CVPixelBufferGetWidth(pixelBuffer); 

int yHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer,0); 
int uvHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer,1); 

int yWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer,0); 
int uvWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer,1); 

int ybpr = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); 
int uvbpr = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1); 

int ysize = yHeight * ybpr ; 
int uvsize = uvHeight * uvbpr ; 

static unsigned char *ypane; 
if(!ypane) 
    ypane = (unsigned char*)malloc(ysize); 
static unsigned char *upane; 
if(!upane) 
    upane = (unsigned char*)malloc(uvsize); 
static unsigned char *vpane; 
if(!vpane) 
    vpane = (unsigned char*)malloc(uvsize); 

unsigned char *yBase = CVPixelBufferGetBaseAddressOfPlane(ypane, 0); 
unsigned char *uBase = CVPixelBufferGetBaseAddressOfPlane(upane, 1; 
unsigned char *vBase = CVPixelBufferGetBaseAddressOfPlane(vpane, 2); 

for(int y=0,y<yHeight;y++) 
{ 
    for(int x=0,x<yWidth;x++) 
    { 
     ypane[y*yWidth+x]=yBase[y*ybpr+x]; 
    } 
} 

for(int y=0,y<uvHeight;y++) 
{ 
    for(int x=0,x<uvWidth;x++) 
    { 
     upane[y*uvWidth+x]=uBase[y*uvbpr+x]; 
     vpane[y*uvWidth+x]=vBase[y*uvbpr+x]; 
    } 
} 
+0

Значит, в этом случае данные настроены так? '[y] [u] [v] [y] [u] [v]'. Это имеет смысл, хотя я не уверен, что я буду malloc во время видео в реальном времени. Благодаря! – cvu

+0

На самом деле количество элементов должно быть больше для Y. API также подтверждает это. Я обновлю свой исходный вопрос – cvu

+1

, вам не нужно malloc во время видео в реальном времени, вы можете просто сделать переменные static –

Смежные вопросы