summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/vo_corevideo.m100
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);