2010-10-02 9 views
7

Ben bununla deliriyorum - her yere baktım ve bir şey denedim ve düşündüğüm her şeyi.AVCapture appendSampleBuffer

iPhone kamerayı kullanarak AVFoundation - özellikle AVCapture kullanan bir iPhone uygulaması yapıyorum.

Kayıtta yer alan video beslemesinde yer alan özel bir görüntünün olması gerekir.

Şimdiye kadar AVCapture oturumunu kurdum, beslemeyi görüntüleyebilir, kareye erişebilir, bir UIImage olarak kaydedebilir ve bindirme resmini üzerine taşıyabilir. Ardından bu yeni UIImage'ı bir CVPixelBufferRef'e dönüştürün. bufferRef'in çalıştığını iki kez kontrol etmek için bir UIImage'a dönüştürdüm ve görüntüyü hala iyi görünüyor.

CVCixelBufferRef'i AVCaptureSessions assetWriterInput'a eklemek için CMSampleBufferRef'e dönüştürmeye çalıştığımda sorun başlıyor. Oluşturmaya çalıştığımda CMSampleBufferRef her zaman NULL döndürüyor. (Boşluk) captureOutput fonksiyonunu

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

UIImage *botImage = [self imageFromSampleBuffer:sampleBuffer]; 
UIImage *wheel = [self imageFromView:wheelView]; 

UIImage *finalImage = [self overlaidImage:botImage :wheel]; 
//[previewImage setImage:finalImage]; <- works -- the image is being merged into one UIImage 

CVPixelBufferRef pixelBuffer = NULL; 
CGImageRef cgImage = CGImageCreateCopy(finalImage.CGImage); 
CFDataRef image = CGDataProviderCopyData(CGImageGetDataProvider(cgImage)); 
int status = CVPixelBufferCreateWithBytes(NULL, 
      self.view.bounds.size.width, 
      self.view.bounds.size.height, 
      kCVPixelFormatType_32BGRA, 
      (void*)CFDataGetBytePtr(image), 
      CGImageGetBytesPerRow(cgImage), 
      NULL, 
      0, 
      NULL, 
      &pixelBuffer); 
if(status == 0){ 
    OSStatus result = 0; 

    CMVideoFormatDescriptionRef videoInfo = NULL; 
    result = CMVideoFormatDescriptionCreateForImageBuffer(NULL, pixelBuffer, &videoInfo); 
    NSParameterAssert(result == 0 && videoInfo != NULL); 

    CMSampleBufferRef myBuffer = NULL; 
    result = CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, 
      pixelBuffer, true, NULL, NULL, videoInfo, NULL, &myBuffer); 
    NSParameterAssert(result == 0 && myBuffer != NULL);//always null :S 

    NSLog(@"Trying to append"); 

    if (!CMSampleBufferDataIsReady(myBuffer)){ 
    NSLog(@"sampleBuffer data is not ready"); 
    return; 
    } 

    if (![assetWriterInput isReadyForMoreMediaData]){ 
    NSLog(@"Not ready for data :("); 
    return; 
    } 

    if (![assetWriterInput appendSampleBuffer:myBuffer]){ 
    NSLog(@"Failed to append pixel buffer"); 
    } 



} 

} 

Ben Dağınık CMSampleBufferRef sarma yapmak için ihtiyacı ortadan kaldıran bir AVAssetWriterInputPixelBufferAdaptor kullanıyor hakkında işitme tutmak Başka bir çözüm - İşte

olduğunu. Bununla birlikte, yığınlanmış ve Apple geliştirici forumları ve dokümanlarını inceledim ve bunun nasıl ayarlanacağına veya nasıl kullanılacağına dair net bir açıklama veya örnek bulamıyorum. Herhangi birinin üzerinde çalışan bir örneği varsa, lütfen bana şunu gösterebilir veya yukarıdaki sorunun cevabını vermeme yardımcı olabilirsiniz - bir hafta boyunca bu non-stop üzerinde çalışıyorum ve sonuçta bekliyorum.

Michael Sen AVAssetWriterInputPixelBufferAdaptor ihtiyaç

+0

Kod biçimlendirmesi eksikliğinden dolayı üzgünüz - önizlemede sorun çıkmış: S –

cevap

6

, önceden herhangi bir başka bilgileri The

Teşekkür gerekiyorsa bana bildirin, burada onu oluşturmak için kodu şöyledir:

// Create dictionary for pixel buffer adaptor 
NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, nil]; 

// Create pixel buffer adaptor 
m_pixelsBufferAdaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:assetWriterInput sourcePixelBufferAttributes:bufferAttributes]; 

Ve Kullanılacak kod:

// If ready to have more media data 
if (m_pixelsBufferAdaptor.assetWriterInput.readyForMoreMediaData) { 
    // Create a pixel buffer 
    CVPixelBufferRef pixelsBuffer = NULL; 
    CVPixelBufferPoolCreatePixelBuffer(NULL, m_pixelsBufferAdaptor.pixelBufferPool, &pixelsBuffer); 

    // Lock pixel buffer address 
    CVPixelBufferLockBaseAddress(pixelsBuffer, 0); 

    // Create your function to set your pixels data in the buffer (in your case, fill with your finalImage data) 
    [self yourFunctionToPutDataInPixelBuffer:CVPixelBufferGetBaseAddress(pixelsBuffer)]; 

    // Unlock pixel buffer address 
    CVPixelBufferUnlockBaseAddress(pixelsBuffer, 0); 

    // Append pixel buffer (calculate currentFrameTime with your needing, the most simplest way is to have a frame time starting at 0 and increment each time you write a frame with the time of a frame (inverse of your framerate)) 
    [m_pixelsBufferAdaptor appendPixelBuffer:pixelsBuffer withPresentationTime:currentFrameTime]; 

    // Release pixel buffer 
    CVPixelBufferRelease(pixelsBuffer); 
} 

Ve pikselleriniziBufferAdaptor'nuzu bırakmayı unutmayın.

+0

Bu gerçekten çalışıyor mu? OP'in yaptığı gibi piksel arabelleğini oluşturmayı denedim ve bir piksel arabellek havuzuyla denedim. Yukarıda tanımlandığı gibi bir piksel arabellek havuzu ile çalıştığımda, simülatörde çalışır, ancak aygıt üzerinde çalışırken piksel arabellek havuzunu hiçbir zaman ayırma. –

1

Bunu CMSampleBufferCreateForImageBuffer() kullanarak yapıyorum.

OSStatus ret = 0; 
CMSampleBufferRef sample = NULL; 
CMVideoFormatDescriptionRef videoInfo = NULL; 
CMSampleTimingInfo timingInfo = kCMTimingInfoInvalid; 
timingInfo.presentationTimeStamp = pts; 
timingInfo.duration = duration; 

ret = CMVideoFormatDescriptionCreateForImageBuffer(NULL, pixel, &videoInfo); 
if (ret != 0) { 
    NSLog(@"CMVideoFormatDescriptionCreateForImageBuffer failed! %d", (int)ret); 
    goto done; 
} 
ret = CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixel, true, NULL, NULL, 
             videoInfo, &timingInfo, &sample); 
if (ret != 0) { 
    NSLog(@"CMSampleBufferCreateForImageBuffer failed! %d", (int)ret); 
    goto done; 
} 
+0

Zamanlama bilgisini nasıl belirlediğinizi belirtebilir misiniz? Görüyorum ki "pts" ve "süre" bu değerler sabit mi? ya da bunlar nelerdir .. onları nasıl kurarsınız? – omarojo

+0

Benim durumumda çalışmıyor ... Ancak Hata null ... ama CMVideoFormatDescriptionRef .... aldığımda geri dönen. –