2013-09-06 10 views
7

Jestem nowicjuszem w zakresie programowania i multimediów iOS i przeglądałem przykładowy projekt o nazwie RosyWriter dostarczany przez firmę Apple pod numerem this link. Tutaj widziałem, że w kodzie jest funkcja o nazwie captureOutput:didOutputSampleBuffer:fromConnection w kodzie poniżej:Konwertuj CVImageBufferRef na CVPixelBufferRef

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
{ 
CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer); 

if (connection == videoConnection) { 

    // Get framerate 
    CMTime timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); 
    [self calculateFramerateAtTimestamp:timestamp]; 

    // Get frame dimensions (for onscreen display) 
    if (self.videoDimensions.width == 0 && self.videoDimensions.height == 0) 
     self.videoDimensions = CMVideoFormatDescriptionGetDimensions(formatDescription); 

    // Get buffer type 
    if (self.videoType == 0) 
     self.videoType = CMFormatDescriptionGetMediaSubType(formatDescription); 

    CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

    // Synchronously process the pixel buffer to de-green it. 
    [self processPixelBuffer:pixelBuffer]; 

    // Enqueue it for preview. This is a shallow queue, so if image processing is taking too long, 
    // we'll drop this frame for preview (this keeps preview latency low). 
    OSStatus err = CMBufferQueueEnqueue(previewBufferQueue, sampleBuffer); 
    if (!err) {   
     dispatch_async(dispatch_get_main_queue(), ^{ 
      CMSampleBufferRef sbuf = (CMSampleBufferRef)CMBufferQueueDequeueAndRetain(previewBufferQueue); 
      if (sbuf) { 
       CVImageBufferRef pixBuf = CMSampleBufferGetImageBuffer(sbuf); 
       [self.delegate pixelBufferReadyForDisplay:pixBuf]; 
       CFRelease(sbuf); 
      } 
     }); 
    } 
} 

CFRetain(sampleBuffer); 
CFRetain(formatDescription); 
dispatch_async(movieWritingQueue, ^{ 

    if (assetWriter) { 

     BOOL wasReadyToRecord = (readyToRecordAudio && readyToRecordVideo); 

     if (connection == videoConnection) { 

      // Initialize the video input if this is not done yet 
      if (!readyToRecordVideo) 
       readyToRecordVideo = [self setupAssetWriterVideoInput:formatDescription]; 

      // Write video data to file 
      if (readyToRecordVideo && readyToRecordAudio) 
       [self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeVideo]; 
     } 
     else if (connection == audioConnection) { 

      // Initialize the audio input if this is not done yet 
      if (!readyToRecordAudio) 
       readyToRecordAudio = [self setupAssetWriterAudioInput:formatDescription]; 

      // Write audio data to file 
      if (readyToRecordAudio && readyToRecordVideo) 
       [self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeAudio]; 
     } 

     BOOL isReadyToRecord = (readyToRecordAudio && readyToRecordVideo); 
     if (!wasReadyToRecord && isReadyToRecord) { 
      recordingWillBeStarted = NO; 
      self.recording = YES; 
      [self.delegate recordingDidStart]; 
     } 
    } 
    CFRelease(sampleBuffer); 
    CFRelease(formatDescription); 
}); 
} 

tutaj funkcja o nazwie pixelBufferReadyForDisplay nazywa których oczekuje parametr typu CVPixelBufferRef

prototyp pixelBufferReadyForDisplay

- (void)pixelBufferReadyForDisplay:(CVPixelBufferRef)pixelBuffer; 

Ale w powyższym kodzie podczas wywoływania tej funkcji przekazuje zmienną pixBuf wh Ich jest typu CVImageBufferRef

Tak więc moje pytanie jest to, że nie jest wymagane, aby użyć dowolnej funkcji lub typ publikacji w celu konwersji CVImageBufferRef do CVPixelBufferRef lub jest to wykonywane niejawnie przez kompilator?

Dzięki.

Odpowiedz

20

Jeśli nie szukaj w CVPixelBufferRef w docs Xcode, przekonasz się, co następuje:

typedef CVImageBufferRef CVPixelBufferRef; 

Więc CVImageBufferRef jest synonimem CVPixelBufferRef. Są wymienne.

Patrzysz na jakiś ładny, gnarly kod. RosyWriter i kolejna przykładowa aplikacja o nazwie "Chromakey" wykonują całkiem niskopoziomowe przetwarzanie buforów pikseli. Jeśli dopiero zaczynasz tworzyć iOS i nowe multimedia, możesz nie chcieć kopać tak głęboko, tak szybko. To trochę jak pierwszy student medycyny próbujący wykonać przeszczep serca płuc.

+0

Dlaczego można utworzyć CIImage z CVPixelBuffer na iOS, ale nie na OSX? CIImage (CVPixelBuffer: currPixelBuffer) działa na iOS, ale nie na OSX. CIImage (CVImageBuffer: currPixelBuffer) działa na OSX. – Adam

+0

Istnieje pewna różnica typów danych między platformami. Czasami nie ma ku temu żadnego dobrego powodu. –