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
23static GType _mix_videorenderparams_type = 0;
24static MixParamsClass *parent_class = NULL;
25
26#define _do_init { _mix_videorenderparams_type = g_define_type_id; }
27
28gboolean mix_videorenderparams_copy(MixParams * target, const MixParams * src);
29MixParams *mix_videorenderparams_dup(const MixParams * obj);
30gboolean mix_videorenderparams_equal(MixParams * first, MixParams * second);
31static void mix_videorenderparams_finalize(MixParams * obj);
32
33G_DEFINE_TYPE_WITH_CODE (MixVideoRenderParams, mix_videorenderparams,
34		MIX_TYPE_PARAMS, _do_init);
35
36static 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
57static 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
73MixVideoRenderParams *
74mix_videorenderparams_new(void) {
75	MixVideoRenderParams *ret =
76			(MixVideoRenderParams *) g_type_create_instance(
77					MIX_TYPE_VIDEORENDERPARAMS);
78
79	return ret;
80}
81
82void 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
114MixVideoRenderParams *
115mix_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 */
126MixParams *
127mix_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 */
149gboolean 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
191gboolean 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 */
209gboolean 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
251MIX_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
269MIX_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
282MIX_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
292MIX_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
302MIX_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
312MIX_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
322MIX_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
372MIX_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 */
397MIX_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