1

gl_readPixels を使用して openGL レイヤー (irrlicht エンジン) をキャプチャし、ビデオ .mp4 ファイルを出力するビデオ レンダラーを使用しています。これは 2 つの段階で行われます。最初の段階ではビデオをキャプチャして保存し (AVAssetWriter)、2 番目の段階では保存したビデオを取得してオーディオ トラックと結合します (AVMutableCompositionTrack および AVAssetExportSession)。

ただし、このビデオを再生すると (非クイックタイム)、反転しようとしても逆さまに表示されます。

私は第2段階で使用してみました:

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

また、Appleデバイスではビデオを正しく反転しますが、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 と 2 つのバッファーを使用した最適化されたソリューション:

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 に答える