1 /*
2  INTEL CONFIDENTIAL
3  Copyright 2009 Intel Corporation All Rights Reserved.
4  The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.
5 
6  No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
7  */
8 
9 /**
10  * SECTION:mixvideorenderparams
11  * @short_description: VideoRender parameters
12  *
13  * A data object which stores videorender specific parameters.
14  */
15 #include <va/va.h>             /* libVA */
16 #include <glib-object.h>
17 
18 #include "mixvideorenderparams.h"
19 #include "mixvideorenderparams_internal.h"
20 
21 #include <string.h>
22 
23 static GType _mix_videorenderparams_type = 0;
24 static MixParamsClass *parent_class = NULL;
25 
26 #define _do_init { _mix_videorenderparams_type = g_define_type_id; }
27 
28 gboolean mix_videorenderparams_copy(MixParams * target, const MixParams * src);
29 MixParams *mix_videorenderparams_dup(const MixParams * obj);
30 gboolean mix_videorenderparams_equal(MixParams * first, MixParams * second);
31 static void mix_videorenderparams_finalize(MixParams * obj);
32 
33 G_DEFINE_TYPE_WITH_CODE (MixVideoRenderParams, mix_videorenderparams,
34 		MIX_TYPE_PARAMS, _do_init);
35 
mix_videorenderparams_init(MixVideoRenderParams * self)36 static void mix_videorenderparams_init(MixVideoRenderParams * self) {
37 
38 	MixVideoRenderParamsPrivate *priv = MIX_VIDEORENDERPARAMS_GET_PRIVATE(self);
39 	priv->va_cliprects = NULL;
40 	self->reserved = priv;
41 
42 	/* initialize properties here */
43 	self->display = NULL;
44 	memset(&(self->src_rect), 0, sizeof(MixRect));
45 	memset(&(self->dst_rect), 0, sizeof(MixRect));
46 
47 	self->clipping_rects = NULL;
48 	self->number_of_clipping_rects = 0;
49 
50 	/* TODO: initialize other properties */
51 	self->reserved1 = NULL;
52 	self->reserved2 = NULL;
53 	self->reserved3 = NULL;
54 	self->reserved4 = NULL;
55 }
56 
mix_videorenderparams_class_init(MixVideoRenderParamsClass * klass)57 static void mix_videorenderparams_class_init(MixVideoRenderParamsClass * klass) {
58 	MixParamsClass *mixparams_class = MIX_PARAMS_CLASS(klass);
59 
60 	/* setup static parent class */
61 	parent_class = (MixParamsClass *) g_type_class_peek_parent(klass);
62 
63 	mixparams_class->finalize = mix_videorenderparams_finalize;
64 	mixparams_class->copy = (MixParamsCopyFunction) mix_videorenderparams_copy;
65 	mixparams_class->dup = (MixParamsDupFunction) mix_videorenderparams_dup;
66 	mixparams_class->equal
67 			= (MixParamsEqualFunction) mix_videorenderparams_equal;
68 
69 	/* Register and allocate the space the private structure for this object */
70 	g_type_class_add_private(mixparams_class, sizeof(MixVideoRenderParamsPrivate));
71 }
72 
73 MixVideoRenderParams *
mix_videorenderparams_new(void)74 mix_videorenderparams_new(void) {
75 	MixVideoRenderParams *ret =
76 			(MixVideoRenderParams *) g_type_create_instance(
77 					MIX_TYPE_VIDEORENDERPARAMS);
78 
79 	return ret;
80 }
81 
mix_videorenderparams_finalize(MixParams * obj)82 void mix_videorenderparams_finalize(MixParams * obj) {
83 	/* clean up here. */
84 
85 	MixVideoRenderParams *self = MIX_VIDEORENDERPARAMS(obj);
86 	MixVideoRenderParamsPrivate *priv =
87 			(MixVideoRenderParamsPrivate *) self->reserved;
88 
89 	if (self->clipping_rects) {
90 		g_free(self->clipping_rects);
91 		self->clipping_rects = NULL;
92 	}
93 
94 	if (priv->va_cliprects) {
95 		g_free(self->clipping_rects);
96 		priv->va_cliprects = NULL;
97 	}
98 
99 	self->number_of_clipping_rects = 0;
100 
101 	if (self->display) {
102 		mix_display_unref(self->display);
103 		self->display = NULL;
104 	}
105 
106 	/* TODO: cleanup other resources allocated */
107 
108 	/* Chain up parent */
109 	if (parent_class->finalize) {
110 		parent_class->finalize(obj);
111 	}
112 }
113 
114 MixVideoRenderParams *
mix_videorenderparams_ref(MixVideoRenderParams * mix)115 mix_videorenderparams_ref(MixVideoRenderParams * mix) {
116 	return (MixVideoRenderParams *) mix_params_ref(MIX_PARAMS(mix));
117 }
118 
119 /**
120  * mix_videorenderparams_dup:
121  * @obj: a #MixVideoRenderParams object
122  * @returns: a newly allocated duplicate of the object.
123  *
124  * Copy duplicate of the object.
125  */
126 MixParams *
mix_videorenderparams_dup(const MixParams * obj)127 mix_videorenderparams_dup(const MixParams * obj) {
128 	MixParams *ret = NULL;
129 
130 	if (MIX_IS_VIDEORENDERPARAMS(obj)) {
131 		MixVideoRenderParams *duplicate = mix_videorenderparams_new();
132 		if (mix_videorenderparams_copy(MIX_PARAMS(duplicate), MIX_PARAMS(obj))) {
133 			ret = MIX_PARAMS(duplicate);
134 		} else {
135 			mix_videorenderparams_unref(duplicate);
136 		}
137 	}
138 	return ret;
139 }
140 
141 /**
142  * mix_videorenderparams_copy:
143  * @target: copy to target
144  * @src: copy from src
145  * @returns: boolean indicates if copy is successful.
146  *
147  * Copy instance data from @src to @target.
148  */
mix_videorenderparams_copy(MixParams * target,const MixParams * src)149 gboolean mix_videorenderparams_copy(MixParams * target, const MixParams * src) {
150 
151 	MixVideoRenderParams *this_target, *this_src;
152 	MIX_RESULT mix_result = MIX_RESULT_FAIL;
153 
154 	if (target == src) {
155 		return TRUE;
156 	}
157 
158 	if (MIX_IS_VIDEORENDERPARAMS(target) && MIX_IS_VIDEORENDERPARAMS(src)) {
159 
160 		// Cast the base object to this child object
161 		this_target = MIX_VIDEORENDERPARAMS(target);
162 		this_src = MIX_VIDEORENDERPARAMS(src);
163 
164 		mix_result = mix_videorenderparams_set_display(this_target,
165 				this_src->display);
166 		if (mix_result != MIX_RESULT_SUCCESS) {
167 			return FALSE;
168 		}
169 
170 		mix_result = mix_videorenderparams_set_clipping_rects(this_target,
171 				this_src->clipping_rects, this_src->number_of_clipping_rects);
172 
173 		if (mix_result != MIX_RESULT_SUCCESS) {
174 			return FALSE;
175 		}
176 
177 		this_target->src_rect = this_src->src_rect;
178 		this_target->dst_rect = this_src->dst_rect;
179 
180 		// Now chainup base class
181 		if (parent_class->copy) {
182 			return parent_class->copy(MIX_PARAMS_CAST(target), MIX_PARAMS_CAST(
183 					src));
184 		} else {
185 			return TRUE;
186 		}
187 	}
188 	return FALSE;
189 }
190 
mix_rect_equal(MixRect rc1,MixRect rc2)191 gboolean mix_rect_equal(MixRect rc1, MixRect rc2) {
192 
193 	if (rc1.x == rc2.x && rc1.y == rc2.y && rc1.width == rc2.width
194 			&& rc1.height == rc2.height) {
195 		return TRUE;
196 	}
197 
198 	return FALSE;
199 }
200 
201 /**
202  * mix_videorenderparams_:
203  * @first: first object to compare
204  * @second: seond object to compare
205  * @returns: boolean indicates if instance are equal.
206  *
207  * Copy instance data from @src to @target.
208  */
mix_videorenderparams_equal(MixParams * first,MixParams * second)209 gboolean mix_videorenderparams_equal(MixParams * first, MixParams * second) {
210 	gboolean ret = FALSE;
211 	MixVideoRenderParams *this_first, *this_second;
212 
213 	if (MIX_IS_VIDEORENDERPARAMS(first) && MIX_IS_VIDEORENDERPARAMS(second)) {
214 		// Deep compare
215 		// Cast the base object to this child object
216 
217 		this_first = MIX_VIDEORENDERPARAMS(first);
218 		this_second = MIX_VIDEORENDERPARAMS(second);
219 
220 		if (mix_display_equal(MIX_DISPLAY(this_first->display), MIX_DISPLAY(
221 				this_second->display)) && mix_rect_equal(this_first->src_rect,
222 				this_second->src_rect) && mix_rect_equal(this_first->dst_rect,
223 				this_second->dst_rect) && this_first->number_of_clipping_rects
224 				== this_second->number_of_clipping_rects && memcmp(
225 				(guchar *) this_first->number_of_clipping_rects,
226 				(guchar *) this_second->number_of_clipping_rects,
227 				this_first->number_of_clipping_rects) == 0) {
228 			// members within this scope equal. chaining up.
229 			MixParamsClass *klass = MIX_PARAMS_CLASS(parent_class);
230 			if (klass->equal)
231 				ret = parent_class->equal(first, second);
232 			else
233 				ret = TRUE;
234 		}
235 	}
236 
237 	return ret;
238 }
239 
240 #define MIX_VIDEORENDERPARAMS_SETTER_CHECK_INPUT(obj) \
241 	if(!obj) return MIX_RESULT_NULL_PTR; \
242 	if(!MIX_IS_VIDEORENDERPARAMS(obj)) return MIX_RESULT_FAIL; \
243 
244 #define MIX_VIDEORENDERPARAMS_GETTER_CHECK_INPUT(obj, prop) \
245 	if(!obj || !prop) return MIX_RESULT_NULL_PTR; \
246 	if(!MIX_IS_VIDEORENDERPARAMS(obj)) return MIX_RESULT_FAIL; \
247 
248 
249 /* TODO: Add getters and setters for other properties. The following is just an exmaple, not implemented yet. */
250 
mix_videorenderparams_set_display(MixVideoRenderParams * obj,MixDisplay * display)251 MIX_RESULT mix_videorenderparams_set_display(MixVideoRenderParams * obj,
252 		MixDisplay * display) {
253 
254 	MIX_VIDEORENDERPARAMS_SETTER_CHECK_INPUT (obj);
255 
256 	if (obj->display) {
257 		mix_display_unref(obj->display);
258 		obj->display = NULL;
259 	}
260 
261 	/* dup */
262 	if (display) {
263 		obj->display = mix_display_dup(display);
264 	}
265 
266 	return MIX_RESULT_SUCCESS;
267 }
268 
mix_videorenderparams_get_display(MixVideoRenderParams * obj,MixDisplay ** display)269 MIX_RESULT mix_videorenderparams_get_display(MixVideoRenderParams * obj,
270 		MixDisplay ** display) {
271 
272 	MIX_VIDEORENDERPARAMS_GETTER_CHECK_INPUT (obj, display);
273 
274 	/* dup? */
275 	if (obj->display) {
276 		*display = mix_display_dup(obj->display);
277 	}
278 
279 	return MIX_RESULT_SUCCESS;
280 }
281 
mix_videorenderparams_set_src_rect(MixVideoRenderParams * obj,MixRect src_rect)282 MIX_RESULT mix_videorenderparams_set_src_rect(MixVideoRenderParams * obj,
283 		MixRect src_rect) {
284 
285 	MIX_VIDEORENDERPARAMS_SETTER_CHECK_INPUT (obj);
286 
287 	obj->src_rect = src_rect;
288 
289 	return MIX_RESULT_SUCCESS;
290 }
291 
mix_videorenderparams_get_src_rect(MixVideoRenderParams * obj,MixRect * src_rect)292 MIX_RESULT mix_videorenderparams_get_src_rect(MixVideoRenderParams * obj,
293 		MixRect * src_rect) {
294 
295 	MIX_VIDEORENDERPARAMS_GETTER_CHECK_INPUT (obj, src_rect);
296 
297 	*src_rect = obj->src_rect;
298 
299 	return MIX_RESULT_SUCCESS;
300 }
301 
mix_videorenderparams_set_dest_rect(MixVideoRenderParams * obj,MixRect dst_rect)302 MIX_RESULT mix_videorenderparams_set_dest_rect(MixVideoRenderParams * obj,
303 		MixRect dst_rect) {
304 
305 	MIX_VIDEORENDERPARAMS_SETTER_CHECK_INPUT (obj);
306 
307 	obj->dst_rect = dst_rect;
308 
309 	return MIX_RESULT_SUCCESS;
310 }
311 
mix_videorenderparams_get_dest_rect(MixVideoRenderParams * obj,MixRect * dst_rect)312 MIX_RESULT mix_videorenderparams_get_dest_rect(MixVideoRenderParams * obj,
313 		MixRect * dst_rect) {
314 
315 	MIX_VIDEORENDERPARAMS_GETTER_CHECK_INPUT (obj, dst_rect);
316 
317 	*dst_rect = obj->dst_rect;
318 
319 	return MIX_RESULT_SUCCESS;
320 }
321 
mix_videorenderparams_set_clipping_rects(MixVideoRenderParams * obj,MixRect * clipping_rects,guint number_of_clipping_rects)322 MIX_RESULT mix_videorenderparams_set_clipping_rects(MixVideoRenderParams * obj,
323 		MixRect* clipping_rects, guint number_of_clipping_rects) {
324 
325 	MixVideoRenderParamsPrivate *priv = NULL;
326 	MIX_VIDEORENDERPARAMS_SETTER_CHECK_INPUT (obj);
327 
328 	priv = (MixVideoRenderParamsPrivate *) obj->reserved;
329 
330 
331 	if (obj->clipping_rects) {
332 		g_free(obj->clipping_rects);
333 		obj->clipping_rects = NULL;
334 		obj->number_of_clipping_rects = 0;
335 	}
336 
337 	if(priv->va_cliprects) {
338 		g_free(priv->va_cliprects);
339 		priv->va_cliprects = NULL;
340 	}
341 
342 
343 	if (clipping_rects && number_of_clipping_rects) {
344 
345 		gint idx = 0;
346 
347 		obj->clipping_rects = g_memdup(clipping_rects, number_of_clipping_rects
348 				* sizeof(MixRect));
349 		if (!obj->clipping_rects) {
350 			return MIX_RESULT_NO_MEMORY;
351 		}
352 
353 		obj->number_of_clipping_rects = number_of_clipping_rects;
354 
355 		/* create VARectangle list */
356 		priv->va_cliprects = g_malloc(number_of_clipping_rects * sizeof(VARectangle));
357 		if (!priv->va_cliprects) {
358 			return MIX_RESULT_NO_MEMORY;
359 		}
360 
361 		for (idx = 0; idx < number_of_clipping_rects; idx++) {
362 			priv->va_cliprects[idx].x = clipping_rects[idx].x;
363 			priv->va_cliprects[idx].y = clipping_rects[idx].y;
364 			priv->va_cliprects[idx].width = clipping_rects[idx].width;
365 			priv->va_cliprects[idx].height = clipping_rects[idx].height;
366 		}
367 	}
368 
369 	return MIX_RESULT_SUCCESS;
370 }
371 
mix_videorenderparams_get_clipping_rects(MixVideoRenderParams * obj,MixRect ** clipping_rects,guint * number_of_clipping_rects)372 MIX_RESULT mix_videorenderparams_get_clipping_rects(MixVideoRenderParams * obj,
373 		MixRect ** clipping_rects, guint* number_of_clipping_rects) {
374 
375 	MIX_VIDEORENDERPARAMS_GETTER_CHECK_INPUT (obj, clipping_rects);
376 	if (!number_of_clipping_rects) {
377 		return MIX_RESULT_NULL_PTR;
378 	}
379 
380 	*clipping_rects = NULL;
381 	*number_of_clipping_rects = 0;
382 
383 	if (obj->clipping_rects && obj->number_of_clipping_rects) {
384 		*clipping_rects = g_memdup(obj->clipping_rects,
385 				obj->number_of_clipping_rects * sizeof(MixRect));
386 		if (!*clipping_rects) {
387 			return MIX_RESULT_NO_MEMORY;
388 		}
389 
390 		*number_of_clipping_rects = obj->number_of_clipping_rects;
391 	}
392 
393 	return MIX_RESULT_SUCCESS;
394 }
395 
396 /* The mixvideo internal method */
mix_videorenderparams_get_cliprects_internal(MixVideoRenderParams * obj,VARectangle ** va_cliprects,guint * number_of_cliprects)397 MIX_RESULT mix_videorenderparams_get_cliprects_internal(
398 		MixVideoRenderParams * obj, VARectangle ** va_cliprects,
399 		guint* number_of_cliprects) {
400 
401 	MIX_VIDEORENDERPARAMS_GETTER_CHECK_INPUT (obj, va_cliprects);
402 	if (!number_of_cliprects) {
403 		return MIX_RESULT_NULL_PTR;
404 	}
405 	MixVideoRenderParamsPrivate *priv =
406 			(MixVideoRenderParamsPrivate *) obj->reserved;
407 
408 	*va_cliprects = NULL;
409 	*number_of_cliprects = 0;
410 
411 	if (priv->va_cliprects && obj->number_of_clipping_rects) {
412 		*va_cliprects = priv->va_cliprects;
413 		*number_of_cliprects = obj->number_of_clipping_rects;
414 	}
415 
416 	return MIX_RESULT_SUCCESS;
417 
418 }
419 
420 /* TODO: implement properties' setters and getters */
421