audio: fill small AO buffers more often in audio-only case
[mplayer.git] / libvo / aspect.c
blobdfe1041660a10b0eb0efc9b437295da64f1aa4e5
1 /*
2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 /* Stuff for correct aspect scaling. */
20 #include "aspect.h"
21 #include "geometry.h"
22 #include "video_out.h"
23 //#ifndef ASPECT_TEST
24 #include "mp_msg.h"
25 #include "options.h"
26 //#endif
28 //#define ASPECT_DEBUG
30 #if defined(ASPECT_DEBUG) || defined(ASPECT_TEST)
31 #include <stdio.h>
32 #endif
34 #include "video_out.h"
36 void aspect_save_orig(struct vo *vo, int orgw, int orgh)
38 #ifdef ASPECT_DEBUG
39 printf("aspect_save_orig %dx%d \n",orgw,orgh);
40 #endif
41 vo->aspdat.orgw = orgw;
42 vo->aspdat.orgh = orgh;
45 void aspect_save_prescale(struct vo *vo, int prew, int preh)
47 #ifdef ASPECT_DEBUG
48 printf("aspect_save_prescale %dx%d \n",prew,preh);
49 #endif
50 vo->aspdat.prew = prew;
51 vo->aspdat.preh = preh;
54 void aspect_save_screenres(struct vo *vo, int scrw, int scrh)
56 #ifdef ASPECT_DEBUG
57 printf("aspect_save_screenres %dx%d \n",scrw,scrh);
58 #endif
59 struct MPOpts *opts = vo->opts;
60 if (scrw <= 0 && scrh <= 0)
61 scrw = 1024;
62 if (scrh <= 0)
63 scrh = (scrw * 3 + 3) / 4;
64 if (scrw <= 0)
65 scrw = (scrh * 4 + 2) / 3;
66 vo->aspdat.scrw = scrw;
67 vo->aspdat.scrh = scrh;
68 if (opts->force_monitor_aspect)
69 vo->monitor_aspect = opts->force_monitor_aspect;
70 else
71 vo->monitor_aspect = opts->monitor_pixel_aspect * scrw / scrh;
74 /* aspect is called with the source resolution and the
75 * resolution, that the scaled image should fit into
78 void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith)
80 struct aspect_data *aspdat = &vo->aspdat;
81 int tmpw;
83 #ifdef ASPECT_DEBUG
84 printf("aspect(0) fitin: %dx%d screenaspect: %.2f\n",aspdat->scrw,aspdat->scrh,
85 monitor_aspect);
86 printf("aspect(1) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh);
87 #endif
88 *srcw = fitw;
89 *srch = (int)(((float)fitw / (float)aspdat->prew * (float)aspdat->preh)
90 * ((float)aspdat->scrh / ((float)aspdat->scrw / vo->monitor_aspect)));
91 *srch+= *srch%2; // round
92 #ifdef ASPECT_DEBUG
93 printf("aspect(2) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh);
94 #endif
95 if(*srch>fith || *srch<aspdat->orgh){
96 tmpw = (int)(((float)fith / (float)aspdat->preh * (float)aspdat->prew)
97 * ((float)aspdat->scrw / ((float)aspdat->scrh / (1.0/vo->monitor_aspect))));
98 tmpw+= tmpw%2; // round
99 if(tmpw<=fitw /*&& tmpw>=aspdat->orgw*/){
100 *srch = fith;
101 *srcw = tmpw;
102 }else{
103 #ifndef ASPECT_TEST
104 mp_tmsg(MSGT_VO,MSGL_WARN,"[ASPECT] Warning: No suitable new res found!\n");
105 #else
106 mp_tmsg(MSGT_VO,MSGL_WARN,"[ASPECT] Error: No new size found that fits into res!\n");
107 #endif
110 aspdat->asp=*srcw / (float)*srch;
111 #ifdef ASPECT_DEBUG
112 printf("aspect(3) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh);
113 #endif
116 static void get_max_dims(struct vo *vo, int *w, int *h, int zoom)
118 struct aspect_data *aspdat = &vo->aspdat;
119 *w = zoom ? aspdat->scrw : aspdat->prew;
120 *h = zoom ? aspdat->scrh : aspdat->preh;
121 if (zoom && WinID >= 0) zoom = A_WINZOOM;
122 if (zoom == A_WINZOOM) {
123 *w = vo->dwidth;
124 *h = vo->dheight;
128 void aspect(struct vo *vo, int *srcw, int *srch, int zoom)
130 int fitw;
131 int fith;
132 get_max_dims(vo, &fitw, &fith, zoom);
133 if( !zoom && geometry_wh_changed ) {
134 #ifdef ASPECT_DEBUG
135 printf("aspect(0) no aspect forced!\n");
136 #endif
137 return; // the user doesn't want to fix aspect
139 aspect_fit(vo, srcw, srch, fitw, fith);
142 void panscan_init(struct vo *vo)
144 vo->panscan_x = 0;
145 vo->panscan_y = 0;
146 vo->panscan_amount = 0.0f;
149 static void panscan_calc_internal(struct vo *vo, int zoom)
151 int fwidth,fheight;
152 int vo_panscan_area;
153 int max_w, max_h;
154 get_max_dims(vo, &max_w, &max_h, zoom);
155 struct MPOpts *opts = vo->opts;
157 if (opts->vo_panscanrange > 0) {
158 aspect(vo, &fwidth, &fheight, zoom);
159 vo_panscan_area = max_h - fheight;
160 if (!vo_panscan_area)
161 vo_panscan_area = max_w - fwidth;
162 vo_panscan_area *= opts->vo_panscanrange;
163 } else
164 vo_panscan_area = -opts->vo_panscanrange * max_h;
166 vo->panscan_amount = vo_fs || zoom == A_WINZOOM ? vo_panscan : 0;
167 vo->panscan_x = vo_panscan_area * vo->panscan_amount * vo->aspdat.asp;
168 vo->panscan_y = vo_panscan_area * vo->panscan_amount;
171 void panscan_calc(struct vo *vo)
173 panscan_calc_internal(vo, A_ZOOM);
177 * vos that set vo_dwidth and v_dheight correctly should call this to update
178 * vo_panscan_x and vo_panscan_y
180 void panscan_calc_windowed(struct vo *vo)
182 panscan_calc_internal(vo, A_WINZOOM);