2012-01-19 14 views
6

"setup_hardware_state में असमर्थित बनावट प्रारूप" वीडियो फ्रेम के बाद से YV12 में एन्कोड किए गए हैं और ओपनजीएल इस प्रारूप को प्रदर्शित करने का मूल तरीका प्रदान नहीं करता है। फिलहाल एक कोड है जो सीपीयू पर प्रदर्शित होता है ताकि छवि को जीपीयू को डिस्प्ले के लिए भेजा जाने से पहले वाईवी 12 से आरजीबी में परिवर्तित हो सके, और यह 100% सीपीयू प्रोसेसिंग का उपभोग करता है।glPopMatrix() चिल्लाता रहा लिनक्स प्रदर्शन में सुधार करने क्योंकि <strong>खेलने MP4 फ़ाइलों सीपीयू</strong> पर भारी हैं, लक्ष्य के लिए एक निजी वीडियो प्लेयर में कुछ अनुकूलन बनाने के लिए कोशिश कर रहा हूँ

मैं वर्तमान में की जांच कर रहा हूं, वाईवी 12 -> आरजीबी रूपांतरण करने के लिए शेडर लिखने के बिना वाईवी 12 फ्रेम को डीकोड कैसे करें। जहां तक ​​मैं समझता हूं, ऐसा करने का एक तरीका GL_MESA_ycbcr_texture के माध्यम से है, जो स्पष्ट रूप से मेरे सिस्टम द्वारा समर्थित है (glxinfo द्वारा रिपोर्ट किया गया)।

इस फेडोरा बॉक्स में मेरे पास एटीआई टेक्नोलॉजीज इंक आरवी 610 वीडियो डिवाइस [राडेन एचडी 2400 प्रो] है, जो एक सभ्य वीडियो कार्ड है। फिर, मैंने yuvrect परीक्षण डाउनलोड किया और इस कार्ड द्वारा समर्थित एक बनावट के लिए GL_TEXTURE_RECTANGLE_NV को प्रतिस्थापित करने के लिए कुछ बदलाव किए: GL_TEXTURE_RECTANGLE_ARB

हालांकि, जब मैं इस संशोधित आवेदन निष्पादित यह आउटपुट:

The MESA driver reports *unsupported texture format in setup_hardware_state* 

मैंने देखा है कि इस त्रुटि को दिखाता है जब glPopMatrix();Display() कॉलबैक से क्रियान्वित किया जाता है। अब, यह मेरे आवेदन में एक बग जैसा प्रतीत नहीं होता है क्योंकि मैंने एक और फेडोरा बॉक्स (उसी सिस्टम) पर यह सटीक कोड चलाया है जिसमें एक अलग वीडियो कार्ड है: इंटेल कॉर्पोरेशन सैंडी ब्रिज एकीकृत ग्राफिक्स नियंत्रक (rev 09) , और यह कड़ाई से काम करता है।

2 द्विआधारी के बीच एकमात्र दृश्य अंतर वे पुस्तकालय हैं जिनके साथ वे जुड़े हुए हैं। (समस्याग्रस्त) अति कार्ड पर ldd रिपोर्ट:

linux-gate.so.1 => (0x00da3000) 
libGL.so.1 => /usr/lib/libGL.so.1 (0x077bd000) 
libGLU.so.1 => /usr/lib/libGLU.so.1 (0x0783b000) 
libglut.so.3 => /usr/lib/libglut.so.3 (0x005a9000) 
libGLEW.so.1.5 => /usr/lib/libGLEW.so.1.5 (0x00aa3000) 
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x057e2000) 
libm.so.6 => /lib/libm.so.6 (0x004e4000) 
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0053f000) 
libc.so.6 => /lib/libc.so.6 (0x00358000) 
libX11.so.6 => /usr/lib/libX11.so.6 (0x0071b000) 
libXext.so.6 => /usr/lib/libXext.so.6 (0x009c5000) 
libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x00af7000) 
libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x00b76000) 
libXxf86vm.so.1 => /usr/lib/libXxf86vm.so.1 (0x0014e000) 
libdrm.so.2 => /usr/lib/libdrm.so.2 (0x00101000) 
libpthread.so.0 => /lib/libpthread.so.0 (0x00510000) 
libdl.so.2 => /lib/libdl.so.2 (0x0052d000) 
libXi.so.6 => /usr/lib/libXi.so.6 (0x00110000) 
/lib/ld-linux.so.2 (0x00337000) 
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00859000) 
librt.so.1 => /lib/librt.so.1 (0x00534000) 
libXau.so.6 => /usr/lib/libXau.so.6 (0x00854000) 

इस बीच, इंटेल कार्ड पर आप देख सकते हैं कि यह libv4l और कुछ अन्य पुस्तकालयों, जबकि अति नहीं था के साथ जुड़ा हुआ! मुझे आश्चर्य है अगर इस समस्या का सामना करना पड़ रहा हूँ के साथ कोई लेना देना:

linux-gate.so.1 => (0x008d6000) 
/usr/lib/libv4l/v4l1compat.so (0x00345000) 
libGL.so.1 => /usr/lib/libGL.so.1 (0x4fb85000) 
libGLU.so.1 => /usr/lib/libGLU.so.1 (0x4fc10000) 
libglut.so.3 => /usr/lib/libglut.so.3 (0x005a9000) 
libGLEW.so.1.5 => /usr/lib/libGLEW.so.1.5 (0x4fc82000) 
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x42ca7000) 
libm.so.6 => /lib/libm.so.6 (0x41fbc000) 
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x42017000) 
libc.so.6 => /lib/libc.so.6 (0x41e30000) 
libv4l1.so.0 => /usr/lib/libv4l1.so.0 (0x00110000) 
libX11.so.6 => /usr/lib/libX11.so.6 (0x421f8000) 
libXext.so.6 => /usr/lib/libXext.so.6 (0x424c0000) 
libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x42c0e000) 
libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x42d98000) 
libXxf86vm.so.1 => /usr/lib/libXxf86vm.so.1 (0x432a2000) 
libdrm.so.2 => /usr/lib/libdrm.so.2 (0x4247b000) 
libpthread.so.0 => /lib/libpthread.so.0 (0x41fe8000) 
libdl.so.2 => /lib/libdl.so.2 (0x42005000) 
libXi.so.6 => /usr/lib/libXi.so.6 (0x42748000) 
/lib/ld-linux.so.2 (0x41e0f000) 
libv4l2.so.0 => /usr/lib/libv4l2.so.0 (0x4217c000) 
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x42337000) 
librt.so.1 => /lib/librt.so.1 (0x4200c000) 
libv4lconvert.so.0 => /usr/lib/libv4lconvert.so.0 (0x42357000) 
libXau.so.6 => /usr/lib/libXau.so.6 (0x421f3000) 
libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x43317000) 

आप उदाहरण चलाने के लिए नीचे आप readtex.c, readtex.h और girl.rgb आवश्यकता होगी, और साथ यह संकलन चाहते हैं: g++ yuvrect.cpp -o yuvrect -lGL -lGLU -lglut -lGLEW

#include <assert.h> 
#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <GL/glew.h> 
#include <GL/glut.h> 

#include "readtex.c" /* I know, this is a hack. */ 

#define TEXTURE_FILE "girl.rgb" 

static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; 
static GLint ImgWidth, ImgHeight; 
static GLushort *ImageYUV = NULL; 


static void DrawObject(void) 
{ 
    glBegin(GL_QUADS); 

    glTexCoord2f(0, 0); 
    glVertex2f(-1.0, -1.0); 

    glTexCoord2f(ImgWidth, 0); 
    glVertex2f(1.0, -1.0); 

    glTexCoord2f(ImgWidth, ImgHeight); 
    glVertex2f(1.0, 1.0); 

    glTexCoord2f(0, ImgHeight); 
    glVertex2f(-1.0, 1.0); 

    glEnd(); 
} 


static void Display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 

    glPushMatrix(); 
     glRotatef(Xrot, 1.0, 0.0, 0.0); 
     glRotatef(Yrot, 0.0, 1.0, 0.0); 
     glRotatef(Zrot, 0.0, 0.0, 1.0); 
     DrawObject(); 
    glPopMatrix(); // <--- error message comes from this call 

    glutSwapBuffers(); 
} 


static void Reshape(int width, int height) 
{ 
    glViewport(0, 0, width, height); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(-1.0, 1.0, -1.0, 1.0, 10.0, 100.0); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glTranslatef(0.0, 0.0, -15.0); 
} 


static void Key(unsigned char key, int x, int y) 
{ 
    (void) x; 
    (void) y; 
    switch (key) { 
     case 27: 
     exit(0); 
     break; 
    } 
    glutPostRedisplay(); 
} 


static void SpecialKey(int key, int x, int y) 
{ 
    float step = 3.0; 
    (void) x; 
    (void) y; 

    switch (key) { 
     case GLUT_KEY_UP: 
     Xrot += step; 
     break; 
     case GLUT_KEY_DOWN: 
     Xrot -= step; 
     break; 
     case GLUT_KEY_LEFT: 
     Yrot += step; 
     break; 
     case GLUT_KEY_RIGHT: 
     Yrot -= step; 
     break; 
    } 
    glutPostRedisplay(); 
}   

static void Init(int argc, char *argv[]) 
{ 
    GLuint texObj = 100; 
    const char *file; 

    printf("Checking GL_ARB_texture_rectangle\n"); 
    if (!glutExtensionSupported("GL_ARB_texture_rectangle")) { 
     printf("Sorry, GL_NV_texture_rectangle is required\n"); 
     exit(0); 
    } 

    printf("Checking GL_MESA_ycbcr_texture\n"); 
    if (!glutExtensionSupported("GL_MESA_ycbcr_texture")) { 
     printf("Sorry, GL_MESA_ycbcr_texture is required\n"); 
     exit(0); 
    } 

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj); 
#ifdef LINEAR_FILTER 
    /* linear filtering looks much nicer but is much slower for Mesa */ 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
#else 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
#endif 

    if (argc > 1) 
     file = argv[1]; 
    else 
     file = TEXTURE_FILE; 

    ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight); 
    if (!ImageYUV) { 
     printf("Couldn't read %s\n", TEXTURE_FILE); 
     exit(0); 
    } 

    printf("Image: %dx%d\n", ImgWidth, ImgHeight); 

    printf("Calling glTexImage2D\n"); 
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 
       GL_YCBCR_MESA, ImgWidth, ImgHeight, 0, 
       GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV); 
    printf("Called glTexImage2D\n"); 
    assert(glGetError() == GL_NO_ERROR); 
    printf("* Assert #1\n"); 

    glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 
        0, 0, ImgWidth, ImgHeight, 
        GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV); 

    assert(glGetError() == GL_NO_ERROR); 
    printf("* Assert #2\n"); 

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 

    glEnable(GL_TEXTURE_RECTANGLE_ARB); 

    glShadeModel(GL_FLAT); 
    glClearColor(0.3, 0.3, 0.4, 1.0); 

    if (argc > 1 && strcmp(argv[1], "-info")==0) { 
     printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 
     printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 
     printf("GL_VENDOR  = %s\n", (char *) glGetString(GL_VENDOR)); 
     printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); 
    } 
} 


int main(int argc, char *argv[]) 
{ 
    glutInit(&argc, argv); 
    glutInitWindowSize(300, 300); 
    glutInitWindowPosition(0, 0); 
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 
    glutCreateWindow(argv[0]); 
    glewInit(); 

    Init(argc, argv); 

    glutReshapeFunc(Reshape); 
    glutKeyboardFunc(Key); 
    glutSpecialFunc(SpecialKey); 
    glutDisplayFunc(Display); 

    glutMainLoop(); 
    return 0; 
} 

इस समस्या को हल करने के लिए कोई सुझाव, दोस्तों?

+0

क्या यह वास्तव में ** glPopMatrix ** त्रुटि उत्पन्न कर रहा है, या त्रुटि संदेश केवल ** DrawObject ** के बाद फ़्लश किया गया है? फेडोरा पर, आपको lib4vl-devel पैकेज और/या पैच (अपग्रेड) मेसा प्राप्त करने की आवश्यकता हो सकती है। ऐसा लगता है कि मेसा की रंगीन एन्कोडिंग की निर्भरता होगी, लेकिन शायद यह एक कोशिश के लायक है। –

+0

जीडीबी मुझे बताता है कि यह 'glPopMatrix()' है जो त्रुटि संदेश का कारण बनता है। – karlphillip

उत्तर

5

यह संभवतः किसी ड्राइवर त्रुटि या कुछ के लिए जिम्मेदार ठहराया जा सकता है। मैं इसके साथ आपकी मदद नहीं करूंगा। हालांकि, शेडर्स से दूर शर्मनाक नहीं है। शेडर्स का उपयोग करके, आप GL_MESA_ycbcr_texture के बारे में भूल सकते हैं और अपना ऐप अधिक संगत बना सकते हैं।

हम सादे पुराने GL_LUMINANCE_ALPHA स्वरूप का उपयोग करने जा रहे हैं, तो छवि लोड हो जाते हैं:

glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 
      GL_LUMINANCE_ALPHA, ImgWidth, ImgHeight, 0, 
      GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, ImageYUV); 

glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 
       0, 0, ImgWidth, ImgHeight, 
       GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, ImageYUV); 
shaders के बारे में

तब:

static const char *p_s_vertex_shader = 
    "varying vec2 t;" 
    "void main()" 
    "{" 
    " t = gl_MultiTexCoord0.xy;" 
    " gl_Position = ftransform();" 
    "}"; 
static const char *p_s_fragment_shader = 
    "#extension GL_ARB_texture_rectangle : enable\n" 
    "varying vec2 t;" 
    "uniform sampler2DRect tex;" 
    "void main()" 
    "{" 
    " vec2 tcEven = vec2(floor(t.x * .5) * 2.0, t.y);" 
    " vec2 tcOdd = vec2(tcEven.x + 1.0, t.y);" 
    " float Cb = texture2DRect(tex, tcEven).x - .5;" 
    " float Cr = texture2DRect(tex, tcOdd).x - .5;" 
    " float y = texture2DRect(tex, t).w;" // 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);" 
    "}"; 
int v = glCreateShader(GL_VERTEX_SHADER); 
int f = glCreateShader(GL_FRAGMENT_SHADER); 
int p = glCreateProgram(); 
glShaderSource(v, 1, &p_s_vertex_shader, 0); 
glShaderSource(f, 1, &p_s_fragment_shader, 0); 
glCompileShader(v); 
//CheckShader(v); 
glCompileShader(f); 
//CheckShader(f); 
glAttachShader(p, v); 
glAttachShader(p, f); 
glLinkProgram(p); 
glUseProgram(p); 
glUniform1i(glGetUniformLocation(p, "tex"), 0); 

यह कहीं के अंत में बनावट के बाद आते हैं, में इस()। और यह है, एक आकर्षण की तरह काम करता है। डिबगिंग के लिए, यह CheckShader() को भी शामिल करना शायद बेहतर है (यह shaders में त्रुटियों संकलन रिपोर्ट):

bool CheckShader(int n_shader_object) 
{ 
    int n_tmp; 
    glGetShaderiv(n_shader_object, GL_COMPILE_STATUS, &n_tmp); 
    bool b_compiled = n_tmp == GL_TRUE; 
    int n_log_length; 
    glGetShaderiv(n_shader_object, GL_INFO_LOG_LENGTH, &n_log_length); 
    // query status ... 

    if(n_log_length > 1) { 
     char *p_s_temp_info_log; 
     if(!(p_s_temp_info_log = (char*)malloc(n_log_length))) 
      return false; 
     int n_tmp; 
     glGetShaderInfoLog(n_shader_object, n_log_length, &n_tmp, 
      p_s_temp_info_log); 
     assert(n_tmp <= n_log_length); 

     fprintf(stderr, "%s\n", p_s_temp_info_log); 
     free(p_s_temp_info_log); 
    } 
    // get/concat info-log 

    return b_compiled; 
} 

शेडर संस्करण शायद एक छोटा सा हार्डवेयर अनुकूलित संस्करण की तुलना में धीमी हो जाएगा, लेकिन मैं कहेंगे इसके बारे में चिंता करने के लिए कुछ भी नहीं है।

आप कोड आजमाइए, और इसके साथ कोई समस्या है, का फैसला करते हैं, मुझे पता है ...

संपादित: वहाँ वास्तव में एक समस्या अति पर इस चल रहा था, अंत में यह पता चला कि त्रुटि एक अलग चर "टी" गुजर रही थी, दूसरे शब्दों में यह काम नहीं करता:

static const char *p_s_vertex_shader = 
    "varying vec2 t;" 
    "void main()" 
    "{" 
    " t = gl_MultiTexCoord0.xy;" 
    " gl_Position = ftransform();" 
    "}"; 
static const char *p_s_fragment_shader = 
    "#extension GL_ARB_texture_rectangle : enable\n" 
    "varying vec2 t;" 
    "uniform sampler2DRect tex;" 
    "void main()" 
    "{" 
    " gl_FragColor = texture2DRect(tex, t);" 
    "}"; 

और आसानी से इसे ठीक करने के लिए, एक बस शिखर शेडर को हटा दें और तय पाइप लाइन लिखने बनावट निर्देशांक दे सकते हैं। तो यह एटीआई पर भी काम करता है:

static const char *p_s_vertex_shader = null; // no vertex shader 
static const char *p_s_fragment_shader = 
    "#extension GL_ARB_texture_rectangle : enable\n" 
    "uniform sampler2DRect tex;" 
    "void main()" 
    "{" 
    " vec2 t = gl_TexCoord[0];" // use fixed pipeline output 
    " gl_FragColor = texture2DRect(tex, t);" 
    "}"; 
+0

मुझे इस सामान का उपयोग करके अपने प्रश्न में कोड देखना अच्छा लगेगा। मैंने खुद की कोशिश की लेकिन मेरा संस्करण काम नहीं किया, मुझे स्क्रीन में हल्का पीला आयताकार ड्रॉ मिला, और 'चेकशेडर()' कॉल ने कोई त्रुटि नहीं दी। – karlphillip

+0

हाय, आपका मतलब पूर्ण स्रोत कोड है? यहां देखें: http://www.luki.webzdarma.cz/up/YCbCrShader.cpp (यह एक फ़ाइल में सभी कोड है, गन्दा प्रकार है लेकिन मेरे लिए काम करता है)। मुझे यकीन नहीं है कि मैंने कुछ बदल दिया है ... तो इसे चलाने का प्रयास करें और यदि यह काम नहीं करता है, तो मैं कुछ और सोचने की कोशिश करूंगा ... –

+0

आपका कोड अन्य मशीनों पर काम करता है * NVIDIA GeForce 7300 * (विंडोज़) और * इंटेल कॉर्पोरेशन सैंडी ब्रिज इंटीग्रेटेड ग्राफिक्स कंट्रोलर (रेव 09) * (फेडोरा लिनक्स), लेकिन यह * एटीआई टेक्नोलॉजीज इंक आरवी 610 वीडियो डिवाइस [राडेन एचडी 2400 प्रो] * (फेडोरा लिनक्स) पर कुछ भी प्रदर्शित नहीं करता है, जो बहुत अजीब है। यह अब त्रुटियों को प्रिंट नहीं करता है। यह समस्या शायद मेरे वीडियो कार्ड ड्राइवर या एक दोषपूर्ण जीपीयू से संबंधित है। क्या आप सहमत हैं? – karlphillip