1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-12 18:07:12 +00:00

vo_corevideo: use generic aspect ratio code

The rescaling is rather silly. vo_get_src_dst_rects() doesn't return an
uncropped image, so the texture coordinates have to be recalculated,
which looks more complicated, but is actually what the other OpenGL VOs
also do.

Tested and fixed by Stefano Pigozzi.
This commit is contained in:
wm4 2013-03-14 15:50:19 +01:00
parent b424dacbe5
commit 5b6da6e286

View File

@ -51,7 +51,9 @@ struct priv {
unsigned int image_width;
unsigned int image_height;
struct mp_csp_details colorspace;
int ass_border_x, ass_border_y;
struct mp_rect src_rect;
struct mp_rect dst_rect;
struct mp_osd_res osd_res;
CVPixelBufferRef pixelBuffer;
CVOpenGLTextureCacheRef textureCache;
@ -61,33 +63,17 @@ struct priv {
struct mpgl_osd *osd;
};
static void resize(struct vo *vo, int width, int height)
static void resize(struct vo *vo)
{
struct priv *p = vo->priv;
GL *gl = p->mpglctx->gl;
gl->Viewport(0, 0, width, height);
gl->MatrixMode(GL_PROJECTION);
gl->LoadIdentity();
p->ass_border_x = p->ass_border_y = 0;
if (aspect_scaling(vo)) {
int new_w, new_h;
GLdouble scale_x, scale_y;
aspect(vo, &new_w, &new_h, A_WINZOOM);
panscan_calc_windowed(vo);
new_w += vo->panscan_x;
new_h += vo->panscan_y;
scale_x = (GLdouble)new_w / (GLdouble)width;
scale_y = (GLdouble)new_h / (GLdouble)height;
gl->Scaled(scale_x, scale_y, 1);
p->ass_border_x = (vo->dwidth - new_w) / 2;
p->ass_border_y = (vo->dheight - new_h) / 2;
}
gl->Ortho(0, p->image_width, p->image_height, 0, -1.0, 1.0);
gl->Viewport(0, 0, vo->dwidth, vo->dheight);
gl->MatrixMode(GL_MODELVIEW);
gl->LoadIdentity();
gl->Ortho(0, vo->dwidth, vo->dheight, 0, -1, 1);
vo_get_src_dst_rects(vo, &p->src_rect, &p->dst_rect, &p->osd_res);
gl->Clear(GL_COLOR_BUFFER_BIT);
vo->want_redraw = true;
@ -116,7 +102,7 @@ static int init_gl(struct vo *vo, uint32_t d_width, uint32_t d_height)
if (!p->osd)
p->osd = mpgl_osd_init(gl, true);
resize(vo, d_width, d_height);
resize(vo);
gl->ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -158,7 +144,7 @@ static void check_events(struct vo *vo)
struct priv *p = vo->priv;
int e = p->mpglctx->check_events(vo);
if (e & VO_EVENT_RESIZE)
resize(vo, vo->dwidth, vo->dheight);
resize(vo);
}
static void prepare_texture(struct vo *vo)
@ -178,35 +164,45 @@ static void prepare_texture(struct vo *vo)
q->upperRight, q->upperLeft);
}
static void do_render(struct vo *vo)
// map x/y (in range 0..1) to the video texture, and emit OpenGL vertexes
static void video_vertex(struct vo *vo, float x, float y)
{
struct priv *p = vo->priv;
struct quad *q = p->quad;
GL *gl = p->mpglctx->gl;
double tx0 = q->upperLeft[0];
double ty0 = q->upperLeft[1];
double tw = q->lowerRight[0] - tx0;
double th = q->lowerRight[1] - ty0;
double sx0 = p->src_rect.x0 / (double)p->image_width;
double sy0 = p->src_rect.y0 / (double)p->image_height;
double sw = (p->src_rect.x1 - p->src_rect.x0) / (double)p->image_width;
double sh = (p->src_rect.y1 - p->src_rect.y0) / (double)p->image_height;
gl->TexCoord2f(tx0 + (sx0 + x * sw) * tw,
ty0 + (sy0 + y * sh) * th);
gl->Vertex2f(p->dst_rect.x1 * x + p->dst_rect.x0 * (1 - x),
p->dst_rect.y1 * y + p->dst_rect.y0 * (1 - y));
}
static void do_render(struct vo *vo)
{
struct priv *p = vo->priv;
GL *gl = p->mpglctx->gl;
prepare_texture(vo);
float x0 = 0;
float y0 = 0;
float w = p->image_width;
float h = p->image_height;
// vertically flips the image
y0 += h;
h = -h;
float xm = x0 + w;
float ym = y0 + h;
gl->Enable(CVOpenGLTextureGetTarget(p->texture));
gl->BindTexture(
CVOpenGLTextureGetTarget(p->texture),
CVOpenGLTextureGetName(p->texture));
gl->Begin(GL_QUADS);
gl->TexCoord2fv(q->lowerLeft); gl->Vertex2f(x0, y0);
gl->TexCoord2fv(q->upperLeft); gl->Vertex2f(x0, ym);
gl->TexCoord2fv(q->upperRight); gl->Vertex2f(xm, ym);
gl->TexCoord2fv(q->lowerRight); gl->Vertex2f(xm, y0);
video_vertex(vo, 0, 0);
video_vertex(vo, 0, 1);
video_vertex(vo, 1, 1);
video_vertex(vo, 1, 0);
gl->End();
gl->Disable(CVOpenGLTextureGetTarget(p->texture));
@ -292,29 +288,9 @@ static int preinit(struct vo *vo, const char *arg)
static void draw_osd(struct vo *vo, struct osd_state *osd)
{
struct priv *p = vo->priv;
GL *gl = p->mpglctx->gl;
assert(p->osd);
gl->MatrixMode(GL_PROJECTION);
gl->PushMatrix();
gl->LoadIdentity();
gl->Ortho(0, vo->dwidth, vo->dheight, 0, -1, 1);
struct mp_osd_res res = {
.w = vo->dwidth,
.h = vo->dheight,
.display_par = vo->monitor_par,
.video_par = vo->aspdat.par,
};
if (aspect_scaling(vo)) {
res.ml = res.mr = p->ass_border_x;
res.mt = res.mb = p->ass_border_y;
}
mpgl_osd_draw_legacy(p->osd, osd, res);
gl->PopMatrix();
mpgl_osd_draw_legacy(p->osd, osd, p->osd_res);
}
static CFStringRef get_cv_csp_matrix(struct vo *vo)
@ -399,12 +375,12 @@ static int control(struct vo *vo, uint32_t request, void *data)
return VO_TRUE;
case VOCTRL_FULLSCREEN:
p->mpglctx->fullscreen(vo);
resize(vo, vo->dwidth, vo->dheight);
resize(vo);
return VO_TRUE;
case VOCTRL_GET_PANSCAN:
return VO_TRUE;
case VOCTRL_SET_PANSCAN:
resize(vo, vo->dwidth, vo->dheight);
resize(vo);
return VO_TRUE;
case VOCTRL_UPDATE_SCREENINFO:
p->mpglctx->update_xinerama_info(vo);