4

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");
}

また、 CMSampleBufferRefCGContextを使用してさまざまなアプローチを試しました。ここで任意のアプローチの解決策を提供できれば、私はあなたにフルスコアを与えることができます

4

1 に答える 1

1

-CVPixelBufferLockBaseAddressと-CVPixelBufferUnlockBaseAddressの両方の呼び出しでkCVPixelBufferLock_ReadOnlyフラグを使用してみてください。また、この問題は、ピクセルバッファをコピーすることで解決できる場合があります。割り当てを1回実行します。

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

その後、pixelBufferからdataにデータをコピーします

size_t size = height * bytesPerRow;

memcpy(data、baseAddress、size);

その後、データを使用します。願っています、それが役立つでしょう。

于 2011-12-21T17:40:34.170 に答える