Захват представления OpenGL в AVAssetWriterInputPixelBufferAdaptor - PullRequest
0 голосов
/ 10 ноября 2011

Я пытаюсь создать AVAssetWriter для захвата экрана проекта openGL.Я никогда не писал AVAssetWriter или AVAssetWriterInputPixelBufferAdaptor, поэтому я не уверен, правильно ли я что-то сделал.

- (id) initWithOutputFileURL:(NSURL *)anOutputFileURL {
    if ((self = [super init])) {
        NSError *error;
        movieWriter = [[AVAssetWriter alloc] initWithURL:anOutputFileURL fileType:AVFileTypeMPEG4 error:&error];
        NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                       AVVideoCodecH264, AVVideoCodecKey,
                                       [NSNumber numberWithInt:640], AVVideoWidthKey,
                                       [NSNumber numberWithInt:480], AVVideoHeightKey,
                                       nil];
        writerInput = [[AVAssetWriterInput
                        assetWriterInputWithMediaType:AVMediaTypeVideo
                        outputSettings:videoSettings] retain];
        writer = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:writerInput sourcePixelBufferAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey,nil]];

        [movieWriter addInput:writerInput];
        writerInput.expectsMediaDataInRealTime = YES;
    }

    return self;
}

Другие части класса:

- (void)getFrame:(CVPixelBufferRef)SampleBuffer:(int64_t)frame{
    frameNumber = frame;
    [writer appendPixelBuffer:SampleBuffer withPresentationTime:CMTimeMake(frame, 24)]; 
}

- (void)startRecording {
   [movieWriter startWriting];
   [movieWriter startSessionAtSourceTime:kCMTimeZero];
}

- (void)stopRecording {
   [writerInput markAsFinished];
   [movieWriter endSessionAtSourceTime:CMTimeMake(frameNumber, 24)];
   [movieWriter finishWriting];
}

Инициатор ресурсов инициированпо:

    NSURL *outputFileURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mov"]];
    recorder = [[GLRecorder alloc] initWithOutputFileURL:outputFileURL];

Вид записывается следующим образом:

    glReadPixels(0, 0, 480, 320, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    for(int y = 0; y <320; y++) {
    for(int x = 0; x <480 * 4; x++) {
        int b2 = ((320 - 1 - y) * 480 * 4 + x);
        int b1 = (y * 4 * 480 + x);
        buffer2[b2] = buffer[b1];
    }
}    
pixelBuffer = NULL;
CVPixelBufferCreateWithBytes (NULL,480,320,kCVPixelFormatType_32BGRA,buffer2,1920,NULL,0,NULL,&pixelBuffer);
[recorder getFrame:pixelBuffer :framenumber];
    framenumber++;

Примечание:

pixelBuffer является CVPixelBufferRef.
framenumberint64_t.
buffer и buffer2: GLubyte.

Я не получаю ошибок, но когда я заканчиваю запись, файла нет.Любая помощь или ссылки, чтобы помочь, будет принята с благодарностью.OpenGL имеет прямую трансляцию с камеры.Я смог сохранить экран как UIImage, но хочу получить фильм о том, что я создал.

Ответы [ 2 ]

0 голосов
/ 10 декабря 2011

Нашел ответ здесь: Сохранение в библиотеке Я никогда не сохранял видео в рулон Carmera.

Мне пришлось использовать время, чтобы изменить имя файла, созданного в рулоне камеры, чтобы он постоянно не сохранялся поверх себя или сохранял один и тот же файл снова и снова.

0 голосов
/ 11 ноября 2011

Если вы пишете кадры RGBA, я думаю, вам может понадобиться использовать AVAssetWriterInputPixelBufferAdaptor для их записи. Предполагается, что этот класс управляет пулом буферов пикселей, но у меня сложилось впечатление, что он фактически массирует ваши данные в YUV.

Если это сработает, то, я думаю, вы обнаружите, что все ваши цвета поменялись местами, и в этот момент вам, вероятно, придется написать пиксельный шейдер, чтобы преобразовать их в BGRA. Или (вздрогнуть) сделать это на процессоре. До вас.

...