Ich habe dies mit YUV Frames von einer CCD-Kamera aufgenommen. Leider gibt es eine Reihe verschiedener YUV-Formate. Ich glaube, dasjenige, das Apple für das GL_YCBCR_422_APPLE
Texturformat verwendet, ist technisch 2VUY422.Um ein Bild von einem YUV422 Rahmen zu konvertieren, erzeugt durch eine IIDC Firewire Kamera 2VUY422, habe ich folgende Zwecke verwendet:
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);
}
}
Für eine effiziente Anzeige einer YUV-Videoquelle, können Sie möchten Apple's client storage extension verwenden, die können Sie die im Anschluss an so etwas wie die Verwendung von:
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);
auf diese Weise können Sie schnell die Daten vor jedem Frame in Ihrer clientseitigen Videotextur gespeichert ändern heraus auf dem Bildschirm angezeigt werden. Um
zu ziehen, könnten Sie dann verwenden, um Code wie folgt aus:
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();
Vielen Dank für die Informationen Adam ich wirklich zu schätzen. Können Sie mir jetzt sagen, wie Sie die Rohdatendatei von der Festplatte extrahieren? Ich bin vertraut mit NSOpenPanel, ich kann das verwenden, um den Datendateipfad zu extrahieren, wie verwende ich jedoch einen Dateipfad und lade die YUV-Datei in die Anwendung ein? – ReachConnection
Angenommen, die Datei enthält nur Pixel, dann würden Sie einfach NSData oder NSFileHandle verwenden und alles lesen. Wenn die Datei Metadaten wie Größeninformationen enthält, müssen Sie diese mit den Standard-C-Pointer- und/oder Strukturoperatoren interpretieren. –
Diese Antwort ist falsch. Ab MacOS 10.2 unterstützt jedes Apple-System eine OpenGL-Erweiterung, die YUV-Daten direkt laden und anzeigen kann. Suchen Sie nach "GL_YCBCR_422_APPLE" für Details. Ob die Daten irgendwo konvertiert werden (vom Treiber in Software, auf der GPU in Hardware, etc.) geht Sie nichts an, wenn Sie diese Erweiterung benutzen (und wenn die GPU es konvertiert, glauben Sie mir, es kann Ihr Codeprobe von oben um mindestens 1000%) – Mecki