1 /*
2 mediastreamer2 library - modular sound and video processing and streaming
3 Copyright (C) 2010 Belledonne Communications SARL, Grenoble France.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "mediastreamer-config.h"
22 #endif
23
24 #include "layouts.h"
25
26
27 /* compute the ideal placement of the video within a window of size wsize,
28 given that the original video has size vsize. Put the result in rect*/
29
ms_layout_center_rectangle(MSVideoSize wsize,MSVideoSize vsize,MSRect * rect)30 void ms_layout_center_rectangle(MSVideoSize wsize, MSVideoSize vsize, MSRect *rect){
31 int w,h;
32 w=wsize.width & ~0x3;
33 h=((w*vsize.height)/vsize.width) & ~0x1;
34 if (h>wsize.height){
35 /*the height doesn't fit, so compute the width*/
36 h=wsize.height & ~0x1;
37 w=((h*vsize.width)/vsize.height) & ~0x3;
38 }
39 rect->x=(wsize.width-w)/2;
40 rect->y=(wsize.height-h)/2;
41 rect->w=w;
42 rect->h=h;
43 }
44
45
46 #define LOCAL_POS_OFFSET 10
47
48 /**
49 * This function is used to compute placement of video and local preview video within a window.
50 * It is used by display filters such as MSDrawDibDisplay and MSX11Video.
51 * @arg wsize the size of the window
52 * @arg vsize the size of the main video to display
53 * @arg orig_psize the size of the preview video
54 * @arg localrect_pos tells which corner is to be used to preview placement
55 * @arg scalefactor ratio of the window size over the whished preview video size , ex: 4.0
56 * @arg mainrect is a return value describing the main video placement
57 * @arg localrect is a return value describing the preview video placement
58 * @arg localrect_pos
59 **/
ms_layout_compute(MSVideoSize wsize,MSVideoSize vsize,MSVideoSize orig_psize,int localrect_pos,float scalefactor,MSRect * mainrect,MSRect * localrect)60 void ms_layout_compute(MSVideoSize wsize, MSVideoSize vsize, MSVideoSize orig_psize, int localrect_pos, float scalefactor, MSRect *mainrect, MSRect *localrect){
61 MSVideoSize psize;
62
63 ms_layout_center_rectangle(wsize,vsize,mainrect);
64 if (localrect_pos!=-1){
65 psize.width=(int)(wsize.width/scalefactor);
66 psize.height=(int)(wsize.height/scalefactor);
67 ms_layout_center_rectangle(psize,orig_psize,localrect);
68 if ((wsize.height - mainrect->h < mainrect->h/scalefactor && wsize.width - mainrect->w < mainrect->w/scalefactor) || localrect_pos<=3)
69 {
70 int x_sv;
71 int y_sv;
72 if (localrect_pos%4==1)
73 {
74 /* top left corner */
75 x_sv = LOCAL_POS_OFFSET;
76 y_sv = LOCAL_POS_OFFSET;
77 }
78 else if (localrect_pos%4==2)
79 {
80 /* top right corner */
81 x_sv = (wsize.width-localrect->w-LOCAL_POS_OFFSET);
82 y_sv = LOCAL_POS_OFFSET;
83 }
84 else if (localrect_pos%4==3)
85 {
86 /* bottom left corner */
87 x_sv = LOCAL_POS_OFFSET;
88 y_sv = (wsize.height-localrect->h-LOCAL_POS_OFFSET);
89 }
90 else /* corner = 0: default */
91 {
92 /* bottom right corner */
93 x_sv = (wsize.width-localrect->w-LOCAL_POS_OFFSET);
94 y_sv = (wsize.height-localrect->h-LOCAL_POS_OFFSET);
95 }
96 localrect->x=x_sv; //wsize.width-localrect->w-LOCAL_POS_OFFSET;
97 localrect->y=y_sv; //wsize.height-localrect->h-LOCAL_POS_OFFSET;
98 }
99 else
100 {
101 int x_sv;
102 int y_sv;
103
104 if (wsize.width - mainrect->w < mainrect->w/scalefactor)
105 {
106 // recalculate so we have a selfview taking as
107 // much available space as possible
108 psize.width=wsize.width;
109 psize.height=wsize.height-mainrect->h;
110 ms_layout_center_rectangle(psize,orig_psize,localrect);
111
112 if (localrect_pos%4==1 || localrect_pos%4==2)
113 {
114 //Self View on Top
115 x_sv = (wsize.width-localrect->w)/2;
116 y_sv = LOCAL_POS_OFFSET;
117
118 mainrect->y = wsize.height-mainrect->h-LOCAL_POS_OFFSET;
119 }
120 else
121 {
122 //Self View on Bottom
123 x_sv = (wsize.width-localrect->w)/2;
124 y_sv = (wsize.height-localrect->h-LOCAL_POS_OFFSET);
125
126 mainrect->y = LOCAL_POS_OFFSET;
127 }
128 }
129 else
130 {
131 // recalculate so we have a selfview taking as
132 // much available space as possible
133 psize.width=wsize.width-mainrect->w;
134 psize.height=wsize.height;
135 ms_layout_center_rectangle(psize,orig_psize,localrect);
136
137 if (localrect_pos%4==1 || localrect_pos%4==3)
138 {
139 //Self View on left
140 x_sv = LOCAL_POS_OFFSET;
141 y_sv = (wsize.height-localrect->h)/2;
142
143 mainrect->x = wsize.width-mainrect->w-LOCAL_POS_OFFSET;
144 }
145 else
146 {
147 //Self View on right
148 x_sv = (wsize.width-localrect->w-LOCAL_POS_OFFSET);
149 y_sv = (wsize.height-localrect->h)/2;
150
151 mainrect->x = LOCAL_POS_OFFSET;
152 }
153 }
154
155 localrect->x=x_sv; //wsize.width-localrect->w-LOCAL_POS_OFFSET;
156 localrect->y=y_sv; //wsize.height-localrect->h-LOCAL_POS_OFFSET;
157 }
158 }
159 /*
160 ms_message("Compute layout result for\nwindow size=%ix%i\nvideo orig size=%ix%i\nlocal size=%ix%i\nlocal orig size=%ix%i\n"
161 "mainrect=%i,%i,%i,%i\tlocalrect=%i,%i,%i,%i",
162 wsize.width,wsize.height,vsize.width,vsize.height,psize.width,psize.height,orig_psize.width,orig_psize.height,
163 mainrect->x,mainrect->y,mainrect->w,mainrect->h,
164 localrect->x,localrect->y,localrect->w,localrect->h);
165 */
166 }
167