diff options
author | wm4 <wm4@nowhere> | 2013-03-14 15:50:19 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-03-17 19:07:29 +0100 |
commit | 5b6da6e286d96d48ce79bbb08dfba3fcc6684eb9 (patch) | |
tree | b7c907d94e28867df41fbecbd7c8b96e67842914 | |
parent | b424dacbe5cfef3cdd72e446672ee417a8cb6fe7 (diff) | |
download | mpv-5b6da6e286d96d48ce79bbb08dfba3fcc6684eb9.tar.bz2 mpv-5b6da6e286d96d48ce79bbb08dfba3fcc6684eb9.tar.xz |
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.
-rw-r--r-- | video/out/vo_corevideo.m | 100 |
1 files changed, 38 insertions, 62 deletions
diff --git a/video/out/vo_corevideo.m b/video/out/vo_corevideo.m index 08dd8e8a25..1fec262ae5 100644 --- a/video/out/vo_corevideo.m +++ b/video/out/vo_corevideo.m @@ -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,24 +164,34 @@ 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; - prepare_texture(vo); - float x0 = 0; - float y0 = 0; - float w = p->image_width; - float h = p->image_height; + double tx0 = q->upperLeft[0]; + double ty0 = q->upperLeft[1]; + double tw = q->lowerRight[0] - tx0; + double th = q->lowerRight[1] - ty0; - // vertically flips the image - y0 += h; - h = -h; + 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; - float xm = x0 + w; - float ym = y0 + h; + 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); gl->Enable(CVOpenGLTextureGetTarget(p->texture)); gl->BindTexture( @@ -203,10 +199,10 @@ static void do_render(struct vo *vo) 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); |