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 + -
显示快捷键?