iPhoneビデオ出力画像バッファをアクセスするときの低FP
-
27-09-2019 - |
質問
iPhoneで画像処理をしようとしています。私は使用しています http://developer.apple.com/library/ios/#qa/qa2010/qa1702.html カメラフレームをキャプチャします。
私の問題は、キャプチャされたバッファーにアクセスしようとしているとき、カメラのFPSが30から20に低下することです。誰かが私がそれを修正できる方法を知っていますか?
kcvpixelformattype_32bgra形式で、見つけることができる最低のキャプチャ品質(avcapturessessionpresetlow = 192x144)を使用します。誰かが私が使用できる低品質を知っているなら、私はそれを試してみてください。
Symbianのような他のプラットフォームで同じ画像アクセスを行うと、問題なく動作します。
これが私のコードです:
#pragma mark -
#pragma mark AVCaptureSession delegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
/*We create an autorelease pool because as we are not in the main_queue our code is
not executed in the main thread. So we have to create an autorelease pool for the thread we are in*/
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
//Lock the image buffer
if (CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess)
{
// calculate FPS and display it using main thread
[self performSelectorOnMainThread:@selector(updateFps:) withObject: (id) nil waitUntilDone:NO];
UInt8 *base = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer); //image buffer start address
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
int size = (height*width);
UInt8* pRGBtmp = m_pRGBimage;
/*
Here is the problem; m_pRGBimage is RGB image I want to process.
In the 'for' loop I convert the image from BGRA to RGB. As a resault, the FPS drops to 20.
*/
for (int i=0;i<size;i++)
{
pRGBtmp[0] = base[2];
pRGBtmp[1] = base[1];
pRGBtmp[2] = base[0];
base = base+4;
pRGBtmp = pRGBtmp+3;
}
// Display received action
[self performSelectorOnMainThread:@selector(displayAction:) withObject: (id) nil waitUntilDone:NO];
//[self displayAction:&eyePlayOutput];
//saveFrame( imageBuffer );
//unlock the image buffer
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
}
[pool drain];
}
回答のフォローオンとして、画像をリアルタイムで処理する必要があります。表示されています。
AvcaptureSessionSpreseTheTheTheTheTheTheThethethの使用を使用すると、次のようなものが最も簡単なことに気付きました。
for (int i=0;i<size;i++)
x = base[0];
フレームレートは4〜5 fpsに低下します。そのサイズの画像がキャッシュされていないからだと思います。
基本的に96x48画像が必要です。カメラの出力イメージをダウンスケールする簡単な方法、ハードウェアアクセラレーションを使用する方法はありますか?
解決
画像内のすべてのピクセルを繰り返すものはすべて、最速のiOSデバイスを除くすべてでかなり遅くなります。たとえば、640 x 480のビデオフレーム(307,200ピクセル)ですべてのピクセルを単純なピクセルのカラーテストでベンチマークし、これがiPhone 4で約4 fpsでしか動作しないことがわかりました。
ケースでは27,648ピクセルの処理を検討しています。これは、iPhone 4で30 fpsをヒットするのに十分な速さで実行されるはずですが、これは元のiPhoneおよびiPhone 3Gよりもはるかに高速なプロセッサです。 iPhone 3Gは、おそらくこの処理負荷に苦労するでしょう。また、Symbianデバイスのプロセッサがどれだけ速くなっているかは言いません。
カラースペースの変換を避けるために、処理アルゴリズムを再作成することをお勧めします。カラーコンポーネントを処理するために並べ替える必要はありません。
さらに、画像の行と列内で特定の間隔でサンプリングすることにより、数ピクセルのみを選択的に処理できます。
最後に、OpenGL ES 2.0(iPhone 3G以降)をサポートする新しいiOSデバイスをターゲットにしている場合、GLSLフラグメントシェーダーを使用してGPUでビデオフレームを完全に処理することを検討することをお勧めします。プロセスについて説明します ここ, 、リアルタイムカラーベースのオブジェクト追跡のためのサンプルコードとともに。 GPUは、私のベンチマークで、CPUの14〜28倍速いこの種の処理を処理できます。
他のヒント
免責事項:この答えは推測です:)
バッファーがロックされている間、あなたはかなり多くの作業を行っています。これは、カメラから画像をキャプチャしているスレッドを保持していますか?
作業中にデータをバッファーからコピーして、できるだけ早くロックを解除できます。
if (CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess) {
// Get the base address and size of the buffer
UInt8 *buffer_base = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer); //image buffer start address
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
// Copy it's contents out
Uint8 *base = malloc(width * height * 4);
memcpy(base, buffer_base, size);
// Unlock the buffer
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
// base now points to a copy of the buffers' data - do what you want to it . . .
...
// remember to free base once you're done ;)
free(base);
キャプチャを維持しているのがロックの場合、これは役立ちます。
NBすべてのバッファーがMallocを1回呼び出してメモリを取得するのと同じサイズであることがわかっている場合、これをスピードアップできます。
または、それが問題でない場合は、このスレッドの優先順位を下げてみることができます
[NSThread setThreadPriority:0.25];
カメラフレームの内容を専用バッファーにコピーし、そこから動作させます。これにより、私の経験が大幅に向上します。私の最良の推測では、カメラフレームが配置されているメモリの領域には、読書/書き込みアクセスが遅くなる特別な保護があります。
カメラフレームデータのメモリアドレスをご覧ください。私のデバイスでは、カメラバッファーがあります 0x63ac000
. 。それは私にとって何の意味もありませんが、他のヒープオブジェクトがに近いアドレスにあることを除いて 0x1300000
. 。ロックの提案は私の減速を解決しませんでしたが、 memcpy
やりました。