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