2011-12-19 80 views
4

我試圖裁剪和縮放CMSampleBufferRef根據用戶的輸入,在ratio,下面的代碼需要CMSampleBufferRef,將其轉換成CVImageBufferRef和使用CVPixelBuffer裁剪基於其字節的內部圖像。這一過程的目標是有一個裁剪和縮放CVPixelBufferRef寫信給視頻iOS的 - 自動調整CVPixelBufferRef

- (CVPixelBufferRef)modifyImage:(CMSampleBufferRef) sampleBuffer { 
    @synchronized (self) { 
     CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
     // Lock the image buffer 
     CVPixelBufferLockBaseAddress(imageBuffer,0); 

     // Get information about the image 
     uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
     size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
     size_t width = CVPixelBufferGetWidth(imageBuffer); 
     size_t height = CVPixelBufferGetHeight(imageBuffer); 

     CVPixelBufferRef pxbuffer; 
     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
           [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, 
           [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, 
           [NSNumber numberWithInt:720], kCVPixelBufferWidthKey, 
           [NSNumber numberWithInt:1280], kCVPixelBufferHeightKey, 
           nil]; 
     NSInteger tempWidth = (NSInteger) (width/ratio); 
     NSInteger tempHeight = (NSInteger) (height/ratio); 

     NSInteger baseAddressStart = 100 + 100 * bytesPerRow; 
     CVReturn status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, tempWidth, tempHeight, kCVPixelFormatType_32BGRA, &baseAddress[baseAddressStart], bytesPerRow, MyPixelBufferReleaseCallback, NULL, (CFDictionaryRef)options, &pxbuffer); 

     if (status != 0) { 
      CKLog(@"%d", status); 
      return NULL; 
     } 

     CVPixelBufferUnlockBaseAddress(imageBuffer,0); 

     return pxbuffer; 
    } 
} 

這一切工作正常,只是當我試圖用這種方法將它寫入到視頻的輸出中,它不斷地接受記憶警告。如果我保持相同的比例

- (void)writeBufferFrame:(CMSampleBufferRef)sampleBuffer pixelBuffer:(CVPixelBufferRef)pixelBuffer { 
    CMTime lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);  

    if(self.videoWriter.status != AVAssetWriterStatusWriting) 
    { 
     CKLog(@"%d", self.videoWriter.status); 
     [self.videoWriter startWriting]; 
     [self.videoWriter startSessionAtSourceTime:lastSampleTime]; 
    } 

    CVPixelBufferRef pxbuffer = [self modifyImage:sampleBuffer]; 
    BOOL success = [self.avAdaptor appendPixelBuffer:pxbuffer withPresentationTime:lastSampleTime]; 
    if (!success) 
     NSLog(@"Warning: Unable to write buffer to video"); 
} 

我也試過用CMSampleBufferRefCGContext不同的做法,是精細。如果您可以爲此處的任何方法提供解決方案,我可以給您滿分

+0

小疑惑我只是想調整CVpixcelcelbuffer的大小。這可能嗎?我剛剛使用你的代碼。但couln't得到它預期o/p.in選項dic我已經添加了原始大小和臨時大小我指出了我的expecetd大小,但哪些不起作用 – 2014-12-08 06:24:17

回答

1

嘗試在對-CVPixelBufferLockBaseAddress和-CVPixelBufferUnlockBaseAddress的調用中使用kCVPixelBufferLock_ReadOnly標誌。 有時候這個問題可以通過複製像素緩衝區來解決。執行分配一次:

unsigned char *data = (unsigned char*)malloc(ySize * sizeof(unsigned char)); 

之後,從pixelBuffer數據複製到數據

爲size_t大小=身高* bytesPerRow;

memcpy(data,baseAddress,size);

之後,使用數據。希望,這將有所幫助。

+0

但我需要寫我的pixelBuffer到視頻,我該怎麼做用'數據'? – vodkhang 2011-12-22 02:15:17

+0

我試圖使用kCVPixelBufferLock_ReadOnly。它不起作用 – vodkhang 2011-12-22 06:21:37

+0

什麼是示例代碼?無論如何,你正在創建CVReturn狀態= CVPixelBufferCreateWithBytes(kCFAllocatorDefault,tempWidth,tempHeight,kCVPixelFormatType_32BGRA,&baseAddress [baseAddressStart],bytesPerRow,MyPixelBufferReleaseCallback,NULL,(CFDictionaryRef)選項和&pxbuffer)的像素緩衝區; – 2011-12-22 06:32:23