iOS - автоматически изменяет размер CVPixelBufferRef - PullRequest
4 голосов
/ 19 декабря 2011

Я пытаюсь обрезать и масштабировать CMSampleBufferRef на основе введенных пользователем данных, на ratio приведенный ниже код принимает CMSampleBufferRef, преобразовывать его в CVImageBufferRef и использовать CVPixelBuffer для обрезки внутреннего изображения на основе его байтов.Цель этого процесса - обрезать и масштабировать 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");
}

. Я также пытался использовать разные подходы, используя CMSampleBufferRef и CGContext .Если вы можете предложить решение для любого подхода здесь, я могу дать вам полный балл

1 Ответ

1 голос
/ 21 декабря 2011

Попробуйте использовать флаг kCVPixelBufferLock_ReadOnly в обоих вызовах -CVPixelBufferLockBaseAddress и -CVPixelBufferUnlockBaseAddress.И иногда эту проблему можно решить путем копирования пиксельного буфера.Выполните выделение один раз:

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

После этого скопируйте данные из pixelBuffer в данные

size_t size = height * bytesPerRow;

memcpy (data, baseAddress, size);

После этого используйте данные.Надеюсь, это поможет.

...