2012-02-17 17 views
14

iPhoneでローカルmpeg-4ビデオのフレームをデコードする最速の方法を探しています。私は、単に10番目のフレームごとのピクセルの輝度値に興味があります。私はどこにビデオをレンダリングする必要はありません。iPhoneでビデオフレームをデコードするGPU

私はffmpeg、AVAssetReader、ImageAssetGenerator、OpenCV、およびMPMoviePlayerを試しましたが、すべて遅すぎます。私が得ることができる最も速いスピードは〜2x(分でスキャンされたビデオの2分)です。私は10xに近いものを望みます。

私の試みではGPUを使用しなかったと仮定して、GPU上で動作するもので自分の目標を達成する方法はありますか? OpenGLは主にレンダリング出力のようですが、着信ビデオのフィルタとして使用されています。多分それはオプションですか?

ありがとうございます!

答えて

3

iOS 5のみのソリューションを使用する場合は、AVCaputureSessionの2011 WWDCセッションのサンプルアプリChromaKeyをご覧ください。

このデモでは、内蔵カメラから30 FPSのビデオをキャプチャし、各フレームをOpenGLにテクスチャとして渡します。その後、OpenGLを使用してフレームを操作し、結果を出力ビデオファイルに書き出すこともできます。

このコードでは、Core Video PixelバッファをAVCaptureSessionからOpenGLにバインドするために深刻な低レベルの魔法を使用し、グラフィックスハードウェアでメモリを共有しています。

カメラ入力ではなくムービーファイルを入力として使用するようにAVCaptureSessionを変更するのはかなり簡単です。

おそらく、Y成分が輝度であるRGBではなく、Y/UV形式でフレームを配信するようにセッションを設定することができます。それに失敗すると、各ピクセルのRGB値を輝度値に変換するシェーダーを書くのはかなり簡単なことです。

すべてのフレームで、10番目のフレームだけでなく、これをすべて実行できるはずです。

+0

私はそのサンプルを入手するためにWWDC 2011出席者である必要があるように見えます。私はまだ効果的にこれがリアルタイムのトランスコードであると心配しています。私は15倍速(1分で15分のビデオスキャン)を得たいと思っています。ボトルネックはフレームのデコードにあると思います。 @サイモン@ –

+0

。d - ここでは、ChromaKeyの例で使用しているテクニックについて説明しています。http://stackoverflow.com/a/9704392/19679、GPUImageコードを取得して、動画をエンコードする際にこれを確認できます。私は、高速テクスチャのアップロードを使用するために私の映画の読書コードをまだ更新していない。 iOSデバイスにはH.264をデコードするための専用ハードウェアが搭載されているため、iOS 5.0の高速テクスチャアップロードでAVFoundationを使用するよりも、映画の解析を高速化することはできません。 –

+0

AppleのRosyWriterのサンプルコードでは、このAVCaptureSession - > OpenGLリンクも示しています。 [here](https://developer.apple.com/library/ios/samplecode/RosyWriter/Introduction/Intro.html)を参照してください。 – bcattle

0

iOS 5を使用できると仮定すると、vImageは適切かもしれません.10フレームごとに、vImageなどのフレームワークを使用する理由があるようです。しかし、どのようなタイプの実際のリアルタイム処理でも、ほぼ確実にOpenGLが必要になります。

+0

ありがとう@LucasTizma。私はvImageを見ていきます。しかし、私の目標は、リアルタイム処理より高速です。だからこそ私は10番目のフレームごとにやりたいと思っています。ビデオがすでに電話に録画されていて、今スキャンしたいと思っています。それはvImageを除外しますか? –

+0

vImageはイメージ処理操作を迅速に実行する手段に過ぎません。私はあなたが大丈夫だろうと思う。 OpenGLを除いて、これはあなたの最速の解決策です。私が間違っている場合、他の人は、私を修正するために自由に感じる。 – LucasTizma

+0

しかし、フレームをデコードしたらvImageは役に立ちますか?もしそうなら、私はそれが必要なのか分からない。作品の90%は実際にはフレームをデコードしており、ピクセルを処理していません。 –

0

アプリケーションのボトルネックは、ビデオフレームを表示可能な形式(RGBなど)に変換するコードにあると仮定すると、convert one .mp4 frame (encoded as YV12) to RGB using Qt and OpenGLに使用されていた共有コードに興味があるかもしれません。このアプリケーションはフレームをGPUにアップロードし、YV12からRGBへの変換を行うためGLSL fragment shaderを有効にするので、QImageに表示することができます。

static const char *p_s_fragment_shader = 
    "#extension GL_ARB_texture_rectangle : enable\n" 
    "uniform sampler2DRect tex;" 
    "uniform float ImgHeight, chromaHeight_Half, chromaWidth;" 
    "void main()" 
    "{" 
    " vec2 t = gl_TexCoord[0].xy;" // get texcoord from fixed-function pipeline 
    " float CbY = ImgHeight + floor(t.y/4.0);" 
    " float CrY = ImgHeight + chromaHeight_Half + floor(t.y/4.0);" 
    " float CbCrX = floor(t.x/2.0) + chromaWidth * floor(mod(t.y, 2.0));" 
    " float Cb = texture2DRect(tex, vec2(CbCrX, CbY)).x - .5;" 
    " float Cr = texture2DRect(tex, vec2(CbCrX, CrY)).x - .5;" 
    " float y = texture2DRect(tex, t).x;" // redundant texture read optimized away by texture cache 
    " float r = y + 1.28033 * Cr;" 
    " float g = y - .21482 * Cb - .38059 * Cr;" 
    " float b = y + 2.12798 * Cb;" 
    " gl_FragColor = vec4(r, g, b, 1.0);" 
    "}" 
関連する問題