[MPlayer-dev-eng] [PATCH] Add support for rotating the video via OpenGL.
Reimar Döffinger
Reimar.Doeffinger at gmx.de
Thu May 9 08:59:09 CEST 2013
---
Changelog | 2 ++
DOCS/man/en/mplayer.1 | 7 +++++++
cfg-mplayer.h | 1 +
libvo/aspect.c | 30 ++++++++++++++++++++++++++----
libvo/video_out.c | 1 +
libvo/video_out.h | 8 ++++++++
libvo/vo_gl.c | 48 +++++++++++++++++++++++++++++++-----------------
7 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/Changelog b/Changelog
index 1110ace..953edd8 100644
--- a/Changelog
+++ b/Changelog
@@ -9,6 +9,8 @@ MPlayer
* 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
diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1
index 461be5f..4da08a0 100644
--- a/DOCS/man/en/mplayer.1
+++ b/DOCS/man/en/mplayer.1
@@ -3628,6 +3628,13 @@ E.g.\& \-panscanrange \-3 allows a zoom factor of up to 4.
This feature is experimental.
.
.TP
+.B \-rotate <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.
diff --git a/cfg-mplayer.h b/cfg-mplayer.h
index bd97d7d..8af12e4 100644
--- a/cfg-mplayer.h
+++ b/cfg-mplayer.h
@@ -173,6 +173,7 @@ const m_option_t mplayer_opts[]={
{"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},
+ {"rotate", &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},
diff --git a/libvo/aspect.c b/libvo/aspect.c
index bd568b9..5b2a2ea 100644
--- a/libvo/aspect.c
+++ b/libvo/aspect.c
@@ -46,25 +46,44 @@ static struct {
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_save_screenres(int scrw, int scrh){
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 @@ static void get_max_dims(int *w, int *h, int zoom)
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 @@ static void panscan_calc_internal(int zoom)
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) {
diff --git a/libvo/video_out.c b/libvo/video_out.c
index d361669..6470f2a 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -65,6 +65,7 @@ int vo_vsync = 0;
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;
diff --git a/libvo/video_out.h b/libvo/video_out.h
index eb9a030..a9e5ce1 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -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
@@ -224,6 +231,7 @@ extern int vo_vsync;
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;
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 3294168..ab397a2 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -120,6 +120,7 @@ static int yuvconvtype;
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 int did_render;
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 @@ static void resize(void) {
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 @@ static void resize(void) {
} 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 @@ static void resize(void) {
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 @@ static void do_render_osd(int type) {
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 @@ static void do_render_osd(int type) {
}
// 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 @@ static void draw_osd(void)
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 @@ static int control(uint32_t request, void *data)
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;}
--
1.7.10.4
More information about the MPlayer-dev-eng
mailing list