vo_gl.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,019 行 · 第 1/3 页
C
1,019 行
} if (!gl_bufferptr) gl_bufferptr = MapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); mpi->planes[0] = gl_bufferptr; BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); if (mpi->planes[0] == NULL) { if (!err_shown) mp_msg(MSGT_VO, MSGL_ERR, "[gl] could not aquire buffer for dr\n" "Expect a _major_ speed penalty\n"); err_shown = 1; return VO_FALSE; } if (mpi->imgfmt == IMGFMT_YV12) { // YV12 mpi->flags |= MP_IMGFLAG_COMMON_STRIDE | MP_IMGFLAG_COMMON_PLANE; mpi->stride[0] = mpi->width; mpi->planes[1] = mpi->planes[0] + mpi->stride[0] * mpi->height; mpi->stride[1] = mpi->width >> 1; mpi->planes[2] = mpi->planes[1] + mpi->stride[1] * (mpi->height >> 1); mpi->stride[2] = mpi->width >> 1; } mpi->flags |= MP_IMGFLAG_DIRECT; return VO_TRUE;}static uint32_t draw_image(mp_image_t *mpi) { int slice = slice_height; int stride[3] = {mpi->stride[0], mpi->stride[1], mpi->stride[2]}; unsigned char *planes[3] = {mpi->planes[0], mpi->planes[1], mpi->planes[2]}; if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) return VO_TRUE; mpi_flipped = (stride[0] < 0); if (mpi->flags & MP_IMGFLAG_DIRECT) { intptr_t base = (intptr_t)planes[0]; if (mpi_flipped) base += (mpi->h - 1) * stride[0]; planes[0] -= base; planes[1] -= base; planes[2] -= base; BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer); UnmapBuffer(GL_PIXEL_UNPACK_BUFFER); gl_bufferptr = NULL; slice = 0; // always "upload" full texture } glUploadTex(gl_target, gl_format, gl_type, planes[0], stride[0], mpi->x, mpi->y, mpi->w, mpi->h, slice); if (mpi->imgfmt == IMGFMT_YV12) { ActiveTexture(GL_TEXTURE1); glUploadTex(gl_target, gl_format, gl_type, planes[1], stride[1], mpi->x / 2, mpi->y / 2, mpi->w / 2, mpi->h / 2, slice); ActiveTexture(GL_TEXTURE2); glUploadTex(gl_target, gl_format, gl_type, planes[2], stride[2], mpi->x / 2, mpi->y / 2, mpi->w / 2, mpi->h / 2, slice); ActiveTexture(GL_TEXTURE0); } if (mpi->flags & MP_IMGFLAG_DIRECT) BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); return VO_TRUE;}static intdraw_frame(uint8_t *src[]){ return VO_ERROR; }static intquery_format(uint32_t format){ int caps = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_FLIP | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE; if (use_osd) caps |= VFCAP_OSD | VFCAP_EOSD | (scaled_osd ? 0 : VFCAP_EOSD_UNSCALED); if ((format == IMGFMT_RGB24) || (format == IMGFMT_RGBA)) return caps; if (use_yuv && format == IMGFMT_YV12) return caps; // HACK, otherwise we get only b&w with some filters (e.g. -vf eq) // ideally MPlayer should be fixed instead not to use Y800 when it has the choice if (!use_yuv && (format == IMGFMT_Y8 || format == IMGFMT_Y800)) return 0; if (many_fmts && glFindFormat(format, NULL, NULL, NULL, NULL)) return caps; return 0;}static voiduninit(void){ if ( !vo_config_count ) return; uninitGl(); releaseGlContext(&gl_vinfo, &gl_context); if (custom_prog) free(custom_prog); custom_prog = NULL; if (custom_tex) free(custom_tex); custom_tex = NULL; vo_uninit();}static opt_t subopts[] = { {"manyfmts", OPT_ARG_BOOL, &many_fmts, NULL}, {"osd", OPT_ARG_BOOL, &use_osd, NULL}, {"scaled-osd", OPT_ARG_BOOL, &scaled_osd, NULL}, {"aspect", OPT_ARG_BOOL, &use_aspect, NULL}, {"slice-height", OPT_ARG_INT, &slice_height, (opt_test_f)int_non_neg}, {"rectangle", OPT_ARG_INT, &use_rectangle,(opt_test_f)int_non_neg}, {"yuv", OPT_ARG_INT, &use_yuv, (opt_test_f)int_non_neg}, {"lscale", OPT_ARG_INT, &lscale, (opt_test_f)int_non_neg}, {"cscale", OPT_ARG_INT, &cscale, (opt_test_f)int_non_neg}, {"glfinish", OPT_ARG_BOOL, &use_glFinish, NULL}, {"swapinterval", OPT_ARG_INT, &swap_interval,NULL}, {"customprog", OPT_ARG_MSTRZ,&custom_prog, NULL}, {"customtex", OPT_ARG_MSTRZ,&custom_tex, NULL}, {"customtlin", OPT_ARG_BOOL, &custom_tlin, NULL}, {"customtrect", OPT_ARG_BOOL, &custom_trect, NULL}, {"osdcolor", OPT_ARG_INT, &osd_color, NULL}, {NULL}};static int preinit(const char *arg){ // set defaults many_fmts = 1; use_osd = 1; scaled_osd = 0; use_aspect = 1; use_yuv = 0; lscale = 0; cscale = 0; use_rectangle = 0; use_glFinish = 0; swap_interval = 1; slice_height = 0; custom_prog = NULL; custom_tex = NULL; custom_tlin = 1; custom_trect = 0; osd_color = 0xffffff; if (subopt_parse(arg, subopts) != 0) { mp_msg(MSGT_VO, MSGL_FATAL, "\n-vo gl command line help:\n" "Example: mplayer -vo gl:slice-height=4\n" "\nOptions:\n" " nomanyfmts\n" " Disable extended color formats for OpenGL 1.2 and later\n" " slice-height=<0-...>\n" " Slice size for texture transfer, 0 for whole image\n" " noosd\n" " Do not use OpenGL OSD code\n" " noaspect\n" " Do not do aspect scaling\n" " rectangle=<0,1,2>\n" " 0: use power-of-two textures\n" " 1: use texture_rectangle\n" " 2: use texture_non_power_of_two\n" " glfinish\n" " Call glFinish() before swapping buffers\n" " swapinterval=<n>\n" " Interval in displayed frames between to buffer swaps.\n" " 1 is equivalent to enable VSYNC, 0 to disable VSYNC.\n" " Requires GLX_SGI_swap_control support to work.\n" " yuv=<n>\n" " 0: use software YUV to RGB conversion.\n" " 1: use register combiners (nVidia only, for older cards).\n" " 2: use fragment program.\n" " 3: use fragment program with gamma correction.\n" " 4: use fragment program with gamma correction via lookup.\n" " 5: use ATI-specific method (for older cards).\n" " 6: use lookup via 3D texture.\n" " lscale=<n>\n" " 0: use standard bilinear scaling for luma.\n" " 1: use improved bicubic scaling for luma.\n" " 2: use cubic in X, linear in Y direction scaling for luma.\n" " cscale=<n>\n" " as lscale but for chroma (2x slower with little visible effect).\n" " customprog=<filename>\n" " use a custom YUV conversion program\n" " customtex=<filename>\n" " use a custom YUV conversion lookup texture\n" " nocustomtlin\n" " use GL_NEAREST scaling for customtex texture\n" " customtrect\n" " use texture_rectangle for customtex texture\n" " osdcolor=<0xRRGGBB>\n" " use the given color for the OSD\n" "\n" ); return -1; } if (use_rectangle == 1) gl_target = GL_TEXTURE_RECTANGLE; else gl_target = GL_TEXTURE_2D; yuvconvtype = use_yuv | lscale << YUV_LUM_SCALER_SHIFT | cscale << YUV_CHROM_SCALER_SHIFT; if (many_fmts) mp_msg (MSGT_VO, MSGL_INFO, "[gl] using extended formats. " "Use -vo gl:nomanyfmts if playback fails.\n"); mp_msg (MSGT_VO, MSGL_V, "[gl] Using %d as slice height " "(0 means image height).\n", slice_height); if( !vo_init() ) return -1; // Can't open X11 return 0;}static int control(uint32_t request, void *data, ...){ switch (request) { case VOCTRL_PAUSE: return (int_pause=1); case VOCTRL_RESUME: return (int_pause=0); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_GET_IMAGE: return get_image(data); case VOCTRL_DRAW_IMAGE: return draw_image(data); case VOCTRL_DRAW_EOSD: if (!data) return VO_FALSE; genEOSD(data); return VO_TRUE; case VOCTRL_GET_EOSD_RES: { mp_eosd_res_t *r = data; r->mt = r->mb = r->ml = r->mr = 0; if (scaled_osd) {r->w = image_width; r->h = image_height;} else if (vo_fs) { r->w = vo_screenwidth; r->h = vo_screenheight; r->ml = r->mr = ass_border_x > 0 ? ass_border_x : 0; r->mt = r->mb = ass_border_y > 0 ? ass_border_y : 0; } else { r->w = vo_dwidth; r->h = vo_dheight; } } return VO_TRUE; case VOCTRL_GUISUPPORT: return VO_TRUE; case VOCTRL_ONTOP: vo_ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: vo_fullscreen(); resize(vo_dwidth, vo_dheight); return VO_TRUE;#ifdef GL_WIN32 case VOCTRL_BORDER: vo_w32_border(); return VO_TRUE;#endif case VOCTRL_GET_PANSCAN: if (!use_aspect) return VO_NOTIMPL; return VO_TRUE; case VOCTRL_SET_PANSCAN: if (!use_aspect) return VO_NOTIMPL; resize (vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_GET_EQUALIZER: if (image_format == IMGFMT_YV12) { va_list va; int *value; va_start(va, data); value = va_arg(va, int *); va_end(va); if (strcasecmp(data, "brightness") == 0) { *value = eq_bri; if (use_yuv == YUV_CONVERSION_COMBINERS) break; // not supported } else if (strcasecmp(data, "contrast") == 0) { *value = eq_cont; if (use_yuv == YUV_CONVERSION_COMBINERS) break; // not supported } else if (strcasecmp(data, "saturation") == 0) { *value = eq_sat; } else if (strcasecmp(data, "hue") == 0) { *value = eq_hue; } else if (strcasecmp(data, "gamma") == 0) { *value = eq_rgamma; if (use_yuv == YUV_CONVERSION_COMBINERS || use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported } else if (strcasecmp(data, "red_gamma") == 0) { *value = eq_rgamma; if (use_yuv == YUV_CONVERSION_COMBINERS || use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported } else if (strcasecmp(data, "green_gamma") == 0) { *value = eq_ggamma; if (use_yuv == YUV_CONVERSION_COMBINERS || use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported } else if (strcasecmp(data, "blue_gamma") == 0) { *value = eq_bgamma; if (use_yuv == YUV_CONVERSION_COMBINERS || use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported } return VO_TRUE; } break; case VOCTRL_SET_EQUALIZER: if (image_format == IMGFMT_YV12) { va_list va; int value; va_start(va, data); value = va_arg(va, int); va_end(va); if (strcasecmp(data, "brightness") == 0) { eq_bri = value; if (use_yuv == YUV_CONVERSION_COMBINERS) break; // not supported } else if (strcasecmp(data, "contrast") == 0) { eq_cont = value; if (use_yuv == YUV_CONVERSION_COMBINERS) break; // not supported } else if (strcasecmp(data, "saturation") == 0) { eq_sat = value; } else if (strcasecmp(data, "hue") == 0) { eq_hue = value; } else if (strcasecmp(data, "gamma") == 0) { eq_rgamma = eq_ggamma = eq_bgamma = value; if (use_yuv == YUV_CONVERSION_COMBINERS || use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported } else if (strcasecmp(data, "red_gamma") == 0) { eq_rgamma = value; if (use_yuv == YUV_CONVERSION_COMBINERS || use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported } else if (strcasecmp(data, "green_gamma") == 0) { eq_ggamma = value; if (use_yuv == YUV_CONVERSION_COMBINERS || use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported } else if (strcasecmp(data, "blue_gamma") == 0) { eq_bgamma = value; if (use_yuv == YUV_CONVERSION_COMBINERS || use_yuv == YUV_CONVERSION_FRAGMENT) break; // not supported } update_yuvconv(); return VO_TRUE; } break; case VOCTRL_UPDATE_SCREENINFO: update_xinerama_info(); return VO_TRUE; } return VO_NOTIMPL;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?