これは、CCDカメラからキャプチャしたYUVフレームで行いました。残念ながら、さまざまなYUV形式があります。アップルがGL_YCBCR_422_APPLE
テクスチャ形式で使用しているものは、技術的に2VUY422だと私は信じている。2VUY422にIIDCのFireWireカメラによって生成されたYUV422フレームから画像を変換するために、私は次のように使用しました:YUVビデオソースの効率的な表示のために
void yuv422_2vuy422(const unsigned char *theYUVFrame, unsigned char *the422Frame, const unsigned int width, const unsigned int height)
{
int i =0, j=0;
unsigned int numPixels = width * height;
unsigned int totalNumberOfPasses = numPixels * 2;
register unsigned int y0, y1, y2, y3, u0, u2, v0, v2;
while (i < (totalNumberOfPasses))
{
u0 = theYUVFrame[i++]-128;
y0 = theYUVFrame[i++];
v0 = theYUVFrame[i++]-128;
y1 = theYUVFrame[i++];
u2 = theYUVFrame[i++]-128;
y2 = theYUVFrame[i++];
v2 = theYUVFrame[i++]-128;
y3 = theYUVFrame[i++];
// U0 Y0 V0 Y1 U2 Y2 V2 Y3
// Remap the values to 2VUY (YUYS?) (Y422) colorspace for OpenGL
// Y0 U Y1 V Y2 U Y3 V
// IIDC cameras are full-range y=[0..255], u,v=[-127..+127], where display is "video range" (y=[16..240], u,v=[16..236])
the422Frame[j++] = ((y0 * 240)/255 + 16);
the422Frame[j++] = ((u0 * 236)/255 + 128);
the422Frame[j++] = ((y1 * 240)/255 + 16);
the422Frame[j++] = ((v0 * 236)/255 + 128);
the422Frame[j++] = ((y2 * 240)/255 + 16);
the422Frame[j++] = ((u2 * 236)/255 + 128);
the422Frame[j++] = ((y3 * 240)/255 + 16);
the422Frame[j++] = ((v2 * 236)/255 + 128);
}
}
、あなたはApple's client storage extensionを使用したい場合があり、そのことができます
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 1);
glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, videoImageWidth * videoImageHeight * 2, videoTexture);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, videoImageWidth, videoImageHeight, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, videoTexture);
これは、各フレームが画面上に表示される前に、あなたはすぐにあなたのクライアント側のビデオテクスチャ内に格納されたデータを変更することができます:以下のようなものを使用して設定します。描画するには
、あなたは、次のようなコードを使用することができます。情報アダムのため
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glViewport(0, 0, [self frame].size.width, [self frame].size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
NSRect bounds = NSRectFromCGRect([self bounds]);
glOrtho((GLfloat)NSMinX(bounds), (GLfloat)NSMaxX(bounds), (GLfloat)NSMinY(bounds), (GLfloat)NSMaxY(bounds), -1.0, 1.0);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 1);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, videoImageWidth, videoImageHeight, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, videoTexture);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, videoImageHeight);
glTexCoord2f(0.0f, videoImageHeight);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(videoImageWidth, videoImageHeight);
glVertex2f(videoImageWidth, 0.0f);
glTexCoord2f(videoImageWidth, 0.0f);
glVertex2f(videoImageWidth, videoImageHeight);
glEnd();
おかげで多くのことを私は本当に感謝しています。これで、ハードディスクから生データファイルを抽出する方法を教えていただけますか?私はNSOpenPanelに精通していますが、データファイルのパスを抽出するために使用できますが、ファイルパスを使用してYUVファイルをアプリケーションにロードするにはどうすればよいですか? – ReachConnection
ファイルにピクセルだけが含まれていると仮定すると、NSDataまたはNSFileHandleを使用してすべてを読み取るだけです。ファイルにサイズ情報などのメタデータが含まれている場合は、標準のCポインタおよび/または構造体演算子を使用してその情報を解釈する必要があります。 –
この回答は間違っています。 MacOS 10.2以降では、すべてのAppleシステムがYUVデータを直接ロードして表示できるOpenGL拡張をサポートしています。詳細は「GL_YCBCR_422_APPLE」を検索してください。この拡張機能を使用すると、データがどこかに(ソフトウェアのドライバ、ハードウェアのGPUなどで)変換されるかどうかはわかりません(GPUがそれを変換しているとき、私を信じて、以上1000%以上) – Mecki