1

我正在使用一个视频渲染器,它使用 gl_readPixels 捕获一个 openGL 层(irrlicht 引擎)并输出一个视频 .mp4 文件。这发生在两个阶段,第一个阶段捕获视频并保存(AVAssetWriter),第二个阶段获取保存的视频并将其与音轨组合(AVMutableCompositionTrack 和 AVAssetExportSession)。

然而,当这个视频被播放(非快速时间)时,它看起来是颠倒的,尽管我试图翻转它。

我尝试在第二阶段使用:

AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:nextClipStartTime error:nil];

// Flip
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, self.frame.size.height);
a_compositionVideoTrack.preferredTransform = flipVertical;

这可以在 iPad 上翻转视频(正确播放),但是当复制到另一台设备时,视频仍然出现颠倒。

我还尝试使用以下方法翻转 AVAssetWriterInput:

videoInput.expectsMediaDataInRealTime = YES;
videoInput.transform = CGAffineTransformMakeScale(1, -1);

这也可以在苹果设备上正确翻转视频,但不能在 pc、youtube、facebook 上正确翻转。是否有我缺少的设置或标志来定义 PC 上的旋转?

编辑:我也在以右旋转模式使用设备(模拟器或 iPad)(我最初使用左)。录制视频时,主页按钮位于右侧。但是,对于我的视频输出,使用任一旋转都不会影响视频旋转。

编辑 2:我现在也尝试翻转与上述两个更改具有相同影响的视图。

captureView.transform = CGAffineTransformMakeRotation(180.0f * M_PI / 180.0f)
4

2 回答 2

2

我通过在 glReadPixels 阶段执行交换操作解决了我的问题。我之前尝试过的大多数事情的问题在于,它们往往只是与视频元数据打包在一起,而不是移动任何像素。尤其是变换函数实际上并没有做任何繁重的工作。

为需要反转像素的其他任何人提供的代码。使用一些更优化的代码可能有更好的方法,如果您知道方法,请分享!

    // OpenGL
    unsigned int* pixelBufferData = (unsigned int*)CVPixelBufferGetBaseAddress(pixelBuffer);
    glReadPixels(0, 0, self.screen.size.width, self.screen.size.height, GL_BGRA, GL_UNSIGNED_BYTE, pixelBufferData);

    unsigned int base;
    unsigned int top;
    int width = self.screen.size.width;
    int height = self.screen.size.height;
    int half_height = height / 2;
    int base_row_index = height * width;
    int top_row_index = 0;

    for(int y = 0; y < half_height; y++) {
        base_row_index -= width;
        top_row_index += width;

        for(int x = 0; x < width; x++) {
            base = pixelBufferData[top_row_index + x];
            top = pixelBufferData[base_row_index + x];
            pixelBufferData[top_row_index + x] = top;
            pixelBufferData[base_row_index + x] = base;
        }
    }

使用 memcpy 和两个缓冲区的优化解决方案:

for (int row = 0; row < height; ++row){
    memcpy(dstBuffer + (height - row - 1) * width * 4, srcBuffer + row * width * 4, width * 4);
}
于 2014-06-10T14:54:47.817 回答
0

试试这个,preferedTransfort与比例结合使用并转换为中心变换以将您的视频放在正确的位置

祝你好运。

AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.frameDuration = CMTimeMake(1, 30);
videoComposition.renderSize = CGSizeMake([self multiplyBy16: size.width] ,[self multiplyBy16: size.height]);
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack];
CGAffineTransform finalTransform ;
CGAffineTransform videoTransform = clipVideoTrack.preferredTransform;

finalTransform = CGAffineTransformConcat(videoTransform,CGAffineTransformMakeTranslation("scale and translate to center transform"));

instruction.layerInstructions = [NSArray arrayWithObjects:transformer,nil];
videoComposition.instructions = [NSArray arrayWithObject: instruction];
于 2014-06-10T11:37:23.897 回答