Mercurial > mplayer.hg
changeset 36171:94979f661d38
Add support for rotating the video via OpenGL.
author | reimar |
---|---|
date | Mon, 13 May 2013 19:34:43 +0000 |
parents | 4fc911fa5366 |
children | 7bf03a973142 |
files | Changelog DOCS/man/en/mplayer.1 cfg-mplayer.h libvo/aspect.c libvo/video_out.c libvo/video_out.h libvo/vo_gl.c |
diffstat | 7 files changed, 76 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/Changelog Mon May 13 19:34:40 2013 +0000 +++ b/Changelog Mon May 13 19:34:43 2013 +0000 @@ -9,6 +9,8 @@ * support for XYZ color space in -vo gl * -vo gl now supports OSD (not EOSD though) with GLES backend. * GLES backend now uses GLES v2 with YUV support via shaders + * -vo gl supports rotated display without needing video filters via + -rotate command-line option. * -vo gl now has an OSX/Cocoa backend, so it should be a better alternative to -vo corevideo now. * -vo gl2 renamed to -vo gl_tiled to stop people from assuming it is
--- a/DOCS/man/en/mplayer.1 Mon May 13 19:34:40 2013 +0000 +++ b/DOCS/man/en/mplayer.1 Mon May 13 19:34:43 2013 +0000 @@ -3628,6 +3628,13 @@ This feature is experimental. . .TP +.B \-monitor\-orientation <0-3> (experimental) +Rotate display by 90, 180 or 270 degrees. +Rotates also the OSD, not just the video image itself. +Currently only supported by the gl video output driver. +For all other video outputs -vf ass,expand=osd=1,rotate=n can be used, in the future this might even happen automatically. +. +.TP .B \-refreshrate <Hz> Set the monitor refreshrate in Hz. Currently only supported by \-vo directx combined with the \-vm option.
--- a/cfg-mplayer.h Mon May 13 19:34:40 2013 +0000 +++ b/cfg-mplayer.h Mon May 13 19:34:43 2013 +0000 @@ -173,6 +173,7 @@ {"novsync", &vo_vsync, CONF_TYPE_FLAG, 0, 1, 0, NULL}, {"panscan", &vo_panscan, CONF_TYPE_FLOAT, CONF_RANGE, -1.0, 1.0, NULL}, {"panscanrange", &vo_panscanrange, CONF_TYPE_FLOAT, CONF_RANGE, -19.0, 99.0, NULL}, + {"monitor-orientation", &vo_rotate, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL}, {"grabpointer", &vo_grabpointer, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"nograbpointer", &vo_grabpointer, CONF_TYPE_FLAG, 0, 1, 0, NULL},
--- a/libvo/aspect.c Mon May 13 19:34:40 2013 +0000 +++ b/libvo/aspect.c Mon May 13 19:34:43 2013 +0000 @@ -46,25 +46,44 @@ int orgh; // real height int prew; // prescaled width int preh; // prescaled height + int orgw_norot; + int orgh_norot; + int prew_norot; + int preh_norot; int scrw; // horizontal resolution int scrh; // vertical resolution float asp; } aspdat; +static void aspect_rotate(void) { + int i; + if (vo_rotate & 1) { + aspdat.orgw = aspdat.orgh_norot; + aspdat.orgh = aspdat.orgw_norot; + aspdat.prew = aspdat.preh_norot; + aspdat.preh = aspdat.prew_norot; + } else { + aspdat.orgw = aspdat.orgw_norot; + aspdat.orgh = aspdat.orgh_norot; + aspdat.prew = aspdat.prew_norot; + aspdat.preh = aspdat.preh_norot; + } +} + void aspect_save_orig(int orgw, int orgh){ #ifdef ASPECT_DEBUG printf("aspect_save_orig %dx%d \n",orgw,orgh); #endif - aspdat.orgw = orgw; - aspdat.orgh = orgh; + aspdat.orgw_norot = orgw; + aspdat.orgh_norot = orgh; } void aspect_save_prescale(int prew, int preh){ #ifdef ASPECT_DEBUG printf("aspect_save_prescale %dx%d \n",prew,preh); #endif - aspdat.prew = prew; - aspdat.preh = preh; + aspdat.prew_norot = prew; + aspdat.preh_norot = preh; } void aspect_save_screenres(int scrw, int scrh){ @@ -92,6 +111,7 @@ void aspect_fit(int *srcw, int *srch, int fitw, int fith){ int tmpw; + aspect_rotate(); #ifdef ASPECT_DEBUG printf("aspect(0) fitin: %dx%d screenaspect: %.2f\n",aspdat.scrw,aspdat.scrh, monitor_aspect); @@ -139,6 +159,7 @@ void aspect(int *srcw, int *srch, int zoom){ int fitw; int fith; + aspect_rotate(); get_max_dims(&fitw, &fith, zoom); if( !zoom && geometry_wh_changed ) { #ifdef ASPECT_DEBUG @@ -161,6 +182,7 @@ int fwidth,fheight; int vo_panscan_area; int max_w, max_h; + aspect_rotate(); get_max_dims(&max_w, &max_h, zoom); if (vo_panscanrange > 0) {
--- a/libvo/video_out.c Mon May 13 19:34:40 2013 +0000 +++ b/libvo/video_out.c Mon May 13 19:34:43 2013 +0000 @@ -65,6 +65,7 @@ int vo_fs = 0; int vo_fsmode = 0; float vo_panscan = 0.0f; +int vo_rotate; int vo_ontop = 0; int vo_adapter_num=0; int vo_refresh_rate=0;
--- a/libvo/video_out.h Mon May 13 19:34:40 2013 +0000 +++ b/libvo/video_out.h Mon May 13 19:34:43 2013 +0000 @@ -30,6 +30,13 @@ #include "libmpcodecs/img_format.h" //#include "vidix/vidix.h" + +#define ROTATE(t, x, y) do { \ + t rot_tmp = x; \ + x = y; \ + y = -rot_tmp; \ +} while(0) + #define VO_EVENT_EXPOSE 1 #define VO_EVENT_RESIZE 2 #define VO_EVENT_KEYPRESS 4 @@ -225,6 +232,7 @@ extern int vo_fs; extern int vo_fsmode; extern float vo_panscan; +extern int vo_rotate; extern int vo_adapter_num; extern int vo_refresh_rate; extern int vo_keepaspect;
--- a/libvo/vo_gl.c Mon May 13 19:34:40 2013 +0000 +++ b/libvo/vo_gl.c Mon May 13 19:34:43 2013 +0000 @@ -120,6 +120,7 @@ static int use_rectangle; static int using_tex_rect; static int err_shown; +static int draw_width, draw_height; static uint32_t image_width; static uint32_t image_height; static uint32_t image_format; @@ -176,8 +177,12 @@ static void redraw(void); static float video_matrix[16]; +static float osd_matrix[16]; static void resize(void) { + int i; + draw_width = (vo_rotate & 1) ? vo_dheight : vo_dwidth; + draw_height = (vo_rotate & 1) ? vo_dwidth : vo_dheight; // simple orthogonal projection for 0-image_width;0-image_height memset(video_matrix, 0, sizeof(video_matrix)); video_matrix[0] = 2.0/image_width; @@ -185,6 +190,12 @@ video_matrix[12] = -1; video_matrix[13] = 1; video_matrix[15] = 1; + memcpy(osd_matrix, video_matrix, sizeof(osd_matrix)); + if (!scaled_osd) { + // simple orthogonal projection for 0-vo_dwidth;0-vo_dheight + osd_matrix[0] = 2.0/draw_width; + osd_matrix[5] = -2.0/draw_height; + } mp_msg(MSGT_VO, MSGL_V, "[gl] Resize: %dx%d\n", vo_dwidth, vo_dheight); if (WinID >= 0) { int left = 0, top = 0, w = vo_dwidth, h = vo_dheight; @@ -194,6 +205,14 @@ } else mpglViewport(0, 0, vo_dwidth, vo_dheight); + for (i = 0; i < (vo_rotate & 3); i++) { + int j; + for (j = 0; j < 16; j += 4) { + ROTATE(float, video_matrix[j], video_matrix[j+1]); + ROTATE(float, osd_matrix[j], osd_matrix[j+1]); + } + } + ass_border_x = ass_border_y = 0; if (aspect_scaling() && use_aspect) { int new_w, new_h; @@ -205,11 +224,16 @@ scale_x = (double)new_w / (double)vo_dwidth; scale_y = (double)new_h / (double)vo_dheight; video_matrix[0] *= scale_x; + video_matrix[4] *= scale_x; video_matrix[12] *= scale_x; + video_matrix[1] *= scale_y; video_matrix[5] *= scale_y; video_matrix[13] *= scale_y; - ass_border_x = (vo_dwidth - new_w) / 2; - ass_border_y = (vo_dheight - new_h) / 2; + if (vo_rotate & 1) { + int tmp = new_w; new_w = new_h; new_h = tmp; + } + ass_border_x = (draw_width - new_w) / 2; + ass_border_y = (draw_height - new_h) / 2; } mpglLoadMatrixf(video_matrix); @@ -831,16 +855,7 @@ if (!draw_osd && !draw_eosd) return; // set special rendering parameters - if (!scaled_osd) { - // simple orthogonal projection for 0-vo_dwidth;0-vo_dheight - float matrix[16] = { - 2.0/vo_dwidth, 0, 0, 0, - 0, -2.0/vo_dheight, 0, 0, - 0, 0, 0, 0, - -1, 1, 0, 1 - }; - mpglLoadMatrixf(matrix); - } + mpglLoadMatrixf(osd_matrix); mpglEnable(GL_BLEND); if (draw_eosd) { mpglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); @@ -874,8 +889,7 @@ } // set rendering parameters back to defaults mpglDisable(GL_BLEND); - if (!scaled_osd) - mpglLoadMatrixf(video_matrix); + mpglLoadMatrixf(video_matrix); mpglBindTexture(gl_target, 0); } @@ -885,8 +899,8 @@ if (vo_osd_changed(0)) { int osd_h, osd_w; clearOSD(); - osd_w = scaled_osd ? image_width : vo_dwidth; - osd_h = scaled_osd ? image_height : vo_dheight; + osd_w = scaled_osd ? image_width : draw_width; + osd_h = scaled_osd ? image_height : draw_height; vo_draw_text_ext(osd_w, osd_h, ass_border_x, ass_border_y, ass_border_x, ass_border_y, image_width, image_height, create_osd_texture); } @@ -1463,7 +1477,7 @@ case VOCTRL_GET_EOSD_RES: { struct mp_eosd_settings *r = data; - r->w = vo_dwidth; r->h = vo_dheight; + r->w = draw_width; r->h = draw_height; r->srcw = image_width; r->srch = image_height; r->mt = r->mb = r->ml = r->mr = 0; if (scaled_osd) {r->w = image_width; r->h = image_height;}