8d7 < 17c16,17 < #include --- > #include > #include 21a22,24 > #include > #include > 24a28,29 > uint8_t *AGPmem; > int page=0; 42a48,53 > /* global Cg vars / decls */ > CGcontext cg_context; > CGprogram yuv2rgbFP; > CGparameter texture0; > CGparameter texture1; > CGparameter texture2; 58a70,71 > GLuint texture_id[10]; > 136a150,152 > char msg[80]; > sprintf( msg, "gl_texfmt: %d\n", gl_texfmt ); > mp_msg(MSGT_VO, MSGL_ERR, msg); 161,162c177,178 < vo_dwidth = d_width; < vo_dheight = d_height; --- > vo_dwidth = d_width; > vo_dheight = d_height; 230a247,266 > > if( !vo_config_count) { /* initialize Cg */ > mp_msg(MSGT_VO, MSGL_ERR, "CG INIT"); > printf( "CG init phase."); > cg_context = cgCreateContext(); > GLenum err = glGetError(); > if( err ) { > const GLubyte * errorMessage = gluErrorString( err ); > mp_msg(MSGT_VO, MSGL_ERR, (const char *) errorMessage); > } > yuv2rgbFP = cgCreateProgramFromFile(cg_context, CG_SOURCE, > "yuv2rgb.fp", > CG_PROFILE_FP30, > "yuv2rgb", NULL ); > > if( yuv2rgbFP == 0 ) { > mp_msg(MSGT_VO, MSGL_ERR, "Error loading fragment program:"); > } > } > 241,242d276 < ImageData=malloc(texture_width*texture_height*image_bytes); < memset(ImageData,128,texture_width*texture_height*image_bytes); 244,247c278,304 < glDisable(GL_BLEND); < glDisable(GL_DEPTH_TEST); < glDepthMask(GL_FALSE); < glDisable(GL_CULL_FACE); --- > /* set up the extensions for the nVidia PDR stuff */ > glXAllocateMemoryNV = (PFNGLXALLOCATEMEMORYNVPROC) > glXGetProcAddressARB((const GLubyte *)"glXAllocateMemoryNV"); > glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC) > glXGetProcAddressARB((const GLubyte *)"glFlushPixelDataRangeNV"); > glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC) > glXGetProcAddressARB((const GLubyte *)"glPixelDataRangeNV"); > > /* I'm being sloppy here, should allocate depending on image size */ > AGPmem = (GLubyte *) glXAllocateMemoryNV( 1024 * 1024 * 3, 0.0, 0.1, 1.0); > glPixelDataRangeNV( GL_WRITE_PIXEL_DATA_RANGE_NV, 1024 * 1024 * 3, > (void *) AGPmem ); > glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV); > if( NULL == AGPmem ) { > mp_msg(MSGT_VO, MSGL_ERR, "Could not allocate AGP memory.\n"); > exit(0); > } > else { > mp_msg(MSGT_VO, MSGL_ERR, "Allocated AGP memory.\n"); > } > > GLenum err = glGetError(); > if( err ) { > const GLubyte * errorMessage = gluErrorString( err ); > mp_msg(MSGT_VO, MSGL_ERR, (const char *) errorMessage); > } > 253,254c310,317 < #if 1 < // glBindTexture(GL_TEXTURE_2D, texture_id); --- > glGenTextures(4, &texture_id[0]); > > /* Y texture, full res */ > glBindTexture(GL_TEXTURE_2D, texture_id[0]); > glDisable(GL_BLEND); > glDisable(GL_DEPTH_TEST); > glDepthMask(GL_FALSE); > glDisable(GL_CULL_FACE); 257,262c320,370 < glTexImage2D(GL_TEXTURE_2D, 0, gl_texfmt, texture_width, texture_height, 0, < gl_format, gl_type, ImageData); < #endif < < free (ImageData); < --- > glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8, texture_width, texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); > > /* U texture, 1/2 x 1/2 res */ > glBindTexture(GL_TEXTURE_2D, texture_id[1]); > glDisable(GL_BLEND); > glDisable(GL_DEPTH_TEST); > glDepthMask(GL_FALSE); > glDisable(GL_CULL_FACE); > > err = glGetError(); > if( err ) { > const GLubyte * errorMessage = gluErrorString( err ); > mp_msg(MSGT_VO, MSGL_ERR, (const char *) errorMessage); > } > > glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); > glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); > glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8, texture_width / 2, texture_height / 2, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); > > /* V texture, 1/2 x 1/2 res */ > glBindTexture(GL_TEXTURE_2D, texture_id[2]); > glDisable(GL_BLEND); > glDisable(GL_DEPTH_TEST); > glDepthMask(GL_FALSE); > glDisable(GL_CULL_FACE); > > glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); > glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); > glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8, texture_width / 2, texture_height / 2, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); > > /* now configure the fragment program parms, etc */ > cgGLLoadProgram( yuv2rgbFP ); > cgGLEnableProfile( CG_PROFILE_FP30 ); // EEK! Overkill. Only new cards. > cgGLBindProgram(yuv2rgbFP); > texture0 = cgGetNamedParameter( yuv2rgbFP, "texture0" ); > texture1 = cgGetNamedParameter( yuv2rgbFP, "texture1" ); > texture2 = cgGetNamedParameter( yuv2rgbFP, "texture2" ); > cgGLSetTextureParameter( texture0, texture_id[0] ); > cgGLEnableTextureParameter( texture0 ); > cgGLSetTextureParameter( texture1, texture_id[1] ); > cgGLEnableTextureParameter( texture1 ); > cgGLSetTextureParameter( texture2, texture_id[2] ); > cgGLEnableTextureParameter( texture2 ); > > err = glGetError(); > if( err ) { > const GLubyte * errorMessage = gluErrorString( err ); > mp_msg(MSGT_VO, MSGL_ERR, (const char *) errorMessage); > exit(0); > } > 268d375 < // printf("OpenGL setup OK!\n"); 289c396 < flip_page(void) --- > flip_page(void) 290a398,407 > glEnable(GL_TEXTURE_2D); > > /* moved glFinish to the top of the func to allow for more concurrency > * it gives about 25% overall speedup on my hardware. > * (VO % is reduced from 27% to about 4%) > * This is all great for me, but it may (?) mess with MPlayer's timing > * code since this func will return before the image has actually > * been displayed. > */ > glFinish(); 292,293c409,422 < // glEnable(GL_TEXTURE_2D); < // glBindTexture(GL_TEXTURE_2D, texture_id); --- > void *pageMem = AGPmem + page *( image_width * image_height * 3) / 2; > > int uOffset = image_width * image_height; > int vOffset = uOffset + ( image_width * image_height ) / 4; > > glBindTexture(GL_TEXTURE_2D, texture_id[0]); > glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, > GL_LUMINANCE, GL_UNSIGNED_BYTE, pageMem); > glBindTexture(GL_TEXTURE_2D, texture_id[1]); > glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width/2, image_height/2, > GL_LUMINANCE, GL_UNSIGNED_BYTE, pageMem + uOffset); > glBindTexture(GL_TEXTURE_2D, texture_id[2]); > glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width/2, image_height/2, > GL_LUMINANCE, GL_UNSIGNED_BYTE, pageMem + vOffset); 295a425,428 > /* need to rebind the Y texture or the Cg program will see the V > * texture for texture0 (VUV). Not totally clear on why... ? > */ > glBindTexture(GL_TEXTURE_2D, texture_id[0]); 296a430 > 300a435,461 > > /* some FP profiles don't allow using a texture coordinate > * to access different textures. In this case you would have > * to add multiple texture parameters to the FP and specify > * multiple texture coordinates like so: > */ > /* > glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0,0); > glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0,0); > glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0,0); > glVertex2i(0,0); > > glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0,1); > glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0,1); > glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0,1); > glVertex2i(0,texture_height); > > glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1,1); > glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1,1); > glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1,1); > glVertex2i(texture_width,texture_height); > > glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1,0); > glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1,0); > glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1,0); > glVertex2i(texture_width,0); > */ 303,304d463 < // glFlush(); < glFinish(); 305a465,468 > page++; > if(page == 2) { > page=0; > } 310c473 < static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y) --- > static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w,int h,int x,int y) 312c475,506 < return 0; --- > /* since I moved the glFinish() call in the flip_page() function, > * we have to double buffer the texture data, else we run the > * risk of overwriting the memory before OpenGL is done with it. > * (glTexSubImage2D etc do *not* block when using the PDR extension) > */ > void *memPage = AGPmem + page * (image_width * image_height * 3 ) / 2; > void *dst = memPage + image_width * y + x; > void *src = srcimg[0]; > int i; > for( i=0; i < h; i++) { > memcpy(dst, src, w); > src += stride[0]; > dst += image_width; > } > > int imgstride = image_width >> 1; > uint8_t *src1 = srcimg[1]; > uint8_t *src2 = srcimg[2]; > int uoffset = image_width*image_height; > int voffset = uoffset + (image_width / 2) * (image_height / 2); > uint8_t *dstu = memPage + uoffset + (image_width / 2) * (y >> 1) + (x >> 1); > uint8_t *dstv = memPage + voffset + (image_width / 2) * (y >> 1) + (x >> 1); > for (i = 0; i < h / 2; i++) { > memcpy(dstu, src1 , w >> 1); > memcpy(dstv, src2, w >> 1); > src1 += stride[1]; > src2 += stride[2]; > dstu += imgstride; > dstv += imgstride; > } > > return 0; 318a513,516 > /* WARNING: I don't know if this works or not. I always use the draw_slice > * routine, so I abandoned this code. > */ > 320c518 < uint8_t *ImageData=src[0]; --- > uint8_t *ImageData = src[0]; 321a520,531 > if ( NULL != AGPmem ) { > char message[120]; > sprintf( message, "image width: %d image_height: %d image_bytes: %d\n", image_width, image_height, image_bytes); > mp_msg(MSGT_VO, MSGL_ERR, message); > > memcpy( AGPmem, src[0], image_width * image_height * image_bytes); > ImageData=AGPmem; > } > char message[120]; > sprintf( message, "image width: %d image_height: %d image_bytes: %d\n", image_width, image_height, image_bytes); > mp_msg(MSGT_VO, MSGL_ERR, message); > 324c534 < gl_format, gl_type, ImageData); --- > GL_BGRA_EXT, GL_UNSIGNED_BYTE, ImageData); 334,335c544,545 < gl_format, < gl_type, --- > GL_BGRA_EXT, > GL_UNSIGNED_BYTE, 344a555,562 > /* not sure about the I420, but the YV12 works. > * WARNING: Since this whole thing is a total hack-job, if a > * codec ends up trying to use an RGB format, who knows what will > * happen. > */ > if ((format == IMGFMT_YV12) || (format == IMGFMT_I420)) { > return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; > } 361c579 < static uint32_t preinit(const char *arg) --- > static uint32_t preinit( const char *arg) 362a581 > 367,368c586,588 < { < char *parse_pos = &arg[0]; --- > { > int addr = (int) &arg[0]; > char *parse_pos = (char *) addr;