iOS зум для записи фильмов

Я использую AVAssetWriter записывать кадры фильма.

Мне было интересно, как я буду делать масштабирование / масштабирование кадра (это можно установить в начале фильма, оно не должно быть для каждого кадра..)

Я полагаю, что смогу сделать это с CMSampleBuffer что добавить к assetWriterInput

Psydocode:

CMSampleBufferRef scaledSampleBuffer = [self scale:sampleBuffer];
[_videoWriterInput appendSampleBuffer:scaledSampleBuffer];

Я нашел несколько вопросов об стеке потока:

Этот должен создать vImage_Buffer, но я понятия не имею, как я получаю это в мой _videoWriterInput:

Переполнение стека

Я попытался преобразовать его обратно примерно так:

    NSInteger cropX0 = 100,
        cropY0 = 100,
        cropHeight = 100,
        cropWidth = 100,
        outWidth = 480,
        outHeight = 480;

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer,0);
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);

    vImage_Buffer inBuff;
    inBuff.height = cropHeight;
    inBuff.width = cropWidth;
    inBuff.rowBytes = bytesPerRow;

    NSInteger startpos = cropY0*bytesPerRow+4*cropX0;
    inBuff.data = baseAddress+startpos;

    unsigned char *outImg= (unsigned char*)malloc(4*outWidth*outHeight);
    vImage_Buffer outBuff = {outImg, outHeight, outWidth, 4*outWidth};

    vImage_Error err = vImageScale_ARGB8888(&inBuff, &outBuff, NULL, 0);
    if (err != kvImageNoError) NSLog(@" error %ld", err);


    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    CVPixelBufferRef pixelBuffer;
    CVPixelBufferCreate(kCFAllocatorSystemDefault, 480, 480, kCVPixelFormatType_32BGRA, NULL, &pixelBuffer);

    CVPixelBufferLockBaseAddress( pixelBuffer, 0 );

    vImage_CGImageFormat format = {
        .bitsPerComponent = 8,
        .bitsPerPixel = 32,
        .bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,  //BGRX8888
        .colorSpace = NULL,    //sRGB
    };

    vImageBuffer_CopyToCVPixelBuffer(&outBuff,
                                     &format,
                                     pixelBuffer,
                                     NULL,
                                     NULL,
                                     kvImageNoFlags);


    CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );

    CMSampleTimingInfo sampleTime = {
        .duration = CMSampleBufferGetDuration(sampleBuffer),
        .presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer),
        .decodeTimeStamp = CMSampleBufferGetDecodeTimeStamp(sampleBuffer)
    };

    CMVideoFormatDescriptionRef videoInfo = NULL;
    CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, &videoInfo);

    CMSampleBufferRef oBuf;
    CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, true, NULL, NULL, videoInfo, &sampleTime, &oBuf);

Но это тоже не работает (поврежденные кадры)

Скопированные вместе из других статей Stackru, я придумал этот код, но это приводит к неработающему видео:

    CGAffineTransform transform = CGAffineTransformMakeScale(2, 2); // zoom 2x

    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:CMSampleBufferGetImageBuffer(sampleBuffer)
                                               options:[NSDictionary dictionaryWithObjectsAndKeys:[NSNull null], kCIImageColorSpace, nil]];
    ciImage = [[ciImage imageByApplyingTransform:transform] imageByCroppingToRect:CGRectMake(0, 0, 480, 480)];

    CVPixelBufferRef pixelBuffer;
    CVPixelBufferCreate(kCFAllocatorSystemDefault, 480, 480, kCVPixelFormatType_32BGRA, NULL, &pixelBuffer);

    CVPixelBufferLockBaseAddress( pixelBuffer, 0 );

    CIContext * ciContext = [CIContext contextWithOptions: nil];
    [ciContext render:ciImage toCVPixelBuffer:pixelBuffer];
    CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );

    CMSampleTimingInfo sampleTime = {
        .duration = CMSampleBufferGetDuration(sampleBuffer),
        .presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer),
        .decodeTimeStamp = CMSampleBufferGetDecodeTimeStamp(sampleBuffer)
    };

    CMVideoFormatDescriptionRef videoInfo = NULL;
    CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, &videoInfo);

    CMSampleBufferRef oBuf;
    CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, true, NULL, NULL, videoInfo, &sampleTime, &oBuf);

Есть идеи?

0 ответов

Другие вопросы по тегам