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:mixbuffer
11  * @short_description: VideoConfig parameters
12  *
13  * A data object which stores videoconfig specific parameters.
14  */
15 
16 #include "mixvideolog.h"
17 #include "mixbuffer.h"
18 #include "mixbuffer_private.h"
19 
20 #define SAFE_FREE(p) if(p) { g_free(p); p = NULL; }
21 
22 static GType _mix_buffer_type = 0;
23 static MixParamsClass *parent_class = NULL;
24 
25 #define _do_init { _mix_buffer_type = g_define_type_id; }
26 
27 gboolean mix_buffer_copy(MixParams * target, const MixParams * src);
28 MixParams *mix_buffer_dup(const MixParams * obj);
29 gboolean mix_buffer_equal(MixParams * first, MixParams * second);
30 static void mix_buffer_finalize(MixParams * obj);
31 
32 G_DEFINE_TYPE_WITH_CODE (MixBuffer, mix_buffer, MIX_TYPE_PARAMS,
33 		_do_init);
34 
mix_buffer_init(MixBuffer * self)35 static void mix_buffer_init(MixBuffer * self) {
36 	/* initialize properties here */
37 
38 	MixBufferPrivate *priv = MIX_BUFFER_GET_PRIVATE(self);
39 	self->reserved = priv;
40 
41 	priv->pool = NULL;
42 
43 	self->data = NULL;
44 	self->size = 0;
45 	self->token = 0;
46 	self->callback = NULL;
47 }
48 
mix_buffer_class_init(MixBufferClass * klass)49 static void mix_buffer_class_init(MixBufferClass * klass) {
50 	MixParamsClass *mixparams_class = MIX_PARAMS_CLASS(klass);
51 
52 	/* setup static parent class */
53 	parent_class = (MixParamsClass *) g_type_class_peek_parent(klass);
54 
55 	mixparams_class->finalize = mix_buffer_finalize;
56 	mixparams_class->copy = (MixParamsCopyFunction) mix_buffer_copy;
57 	mixparams_class->dup = (MixParamsDupFunction) mix_buffer_dup;
58 	mixparams_class->equal = (MixParamsEqualFunction) mix_buffer_equal;
59 
60 	/* Register and allocate the space the private structure for this object */
61 	g_type_class_add_private(mixparams_class, sizeof(MixBufferPrivate));
62 }
63 
64 MixBuffer *
mix_buffer_new(void)65 mix_buffer_new(void) {
66 	MixBuffer *ret = (MixBuffer *) g_type_create_instance(MIX_TYPE_BUFFER);
67 	return ret;
68 }
69 
mix_buffer_finalize(MixParams * obj)70 void mix_buffer_finalize(MixParams * obj) {
71 	/* clean up here. */
72 
73 	/* MixBuffer *self = MIX_BUFFER(obj); */
74 
75 	/* Chain up parent */
76 	if (parent_class->finalize) {
77 		parent_class->finalize(obj);
78 	}
79 }
80 
81 MixBuffer *
mix_buffer_ref(MixBuffer * mix)82 mix_buffer_ref(MixBuffer * mix) {
83 	return (MixBuffer *) mix_params_ref(MIX_PARAMS(mix));
84 }
85 
86 /**
87  * mix_buffer_dup:
88  * @obj: a #MixBuffer object
89  * @returns: a newly allocated duplicate of the object.
90  *
91  * Copy duplicate of the object.
92  */
93 MixParams *
mix_buffer_dup(const MixParams * obj)94 mix_buffer_dup(const MixParams * obj) {
95 	MixParams *ret = NULL;
96 
97 	if (MIX_IS_BUFFER(obj)) {
98 		MixBuffer *duplicate = mix_buffer_new();
99 		if (mix_buffer_copy(MIX_PARAMS(duplicate), MIX_PARAMS(obj))) {
100 			ret = MIX_PARAMS(duplicate);
101 		} else {
102 			mix_buffer_unref(duplicate);
103 		}
104 	}
105 	return ret;
106 }
107 
108 /**
109  * mix_buffer_copy:
110  * @target: copy to target
111  * @src: copy from src
112  * @returns: boolean indicates if copy is successful.
113  *
114  * Copy instance data from @src to @target.
115  */
mix_buffer_copy(MixParams * target,const MixParams * src)116 gboolean mix_buffer_copy(MixParams * target, const MixParams * src) {
117 	MixBuffer *this_target, *this_src;
118 
119 	if (MIX_IS_BUFFER(target) && MIX_IS_BUFFER(src)) {
120 		// Cast the base object to this child object
121 		this_target = MIX_BUFFER(target);
122 		this_src = MIX_BUFFER(src);
123 
124 		// Duplicate string
125 		this_target->data = this_src->data;
126 		this_target->size = this_src->size;
127 		this_target->token = this_src->token;
128 		this_target->callback = this_src->callback;
129 
130 		// Now chainup base class
131 		if (parent_class->copy) {
132 			return parent_class->copy(MIX_PARAMS_CAST(target), MIX_PARAMS_CAST(
133 					src));
134 		} else {
135 			return TRUE;
136 		}
137 	}
138 	return FALSE;
139 }
140 
141 /**
142  * mix_buffer_:
143  * @first: first object to compare
144  * @second: seond object to compare
145  * @returns: boolean indicates if instance are equal.
146  *
147  * Copy instance data from @src to @target.
148  */
mix_buffer_equal(MixParams * first,MixParams * second)149 gboolean mix_buffer_equal(MixParams * first, MixParams * second) {
150 	gboolean ret = FALSE;
151 	MixBuffer *this_first, *this_second;
152 
153 	if (MIX_IS_BUFFER(first) && MIX_IS_BUFFER(second)) {
154 		// Deep compare
155 		// Cast the base object to this child object
156 
157 		this_first = MIX_BUFFER(first);
158 		this_second = MIX_BUFFER(second);
159 
160 		if (this_first->data == this_second->data && this_first->size
161 				== this_second->size && this_first->token == this_second->token
162 				&& this_first->callback == this_second->callback) {
163 			// members within this scope equal. chaining up.
164 			MixParamsClass *klass = MIX_PARAMS_CLASS(parent_class);
165 			if (klass->equal)
166 				ret = klass->equal(first, second);
167 			else
168 				ret = TRUE;
169 		}
170 	}
171 
172 	return ret;
173 }
174 
175 #define MIX_BUFFER_SETTER_CHECK_INPUT(obj) \
176 	if(!obj) return MIX_RESULT_NULL_PTR; \
177 	if(!MIX_IS_BUFFER(obj)) return MIX_RESULT_FAIL; \
178 
179 
mix_buffer_set_data(MixBuffer * obj,guchar * data,guint size,gulong token,MixBufferCallback callback)180 MIX_RESULT mix_buffer_set_data(MixBuffer * obj, guchar *data, guint size,
181 		gulong token, MixBufferCallback callback) {
182 	MIX_BUFFER_SETTER_CHECK_INPUT (obj);
183 
184 	obj->data = data;
185 	obj->size = size;
186 	obj->token = token;
187 	obj->callback = callback;
188 
189 	return MIX_RESULT_SUCCESS;
190 }
191 
mix_buffer_set_pool(MixBuffer * obj,MixBufferPool * pool)192 MIX_RESULT mix_buffer_set_pool(MixBuffer *obj, MixBufferPool *pool) {
193 
194 	MIX_BUFFER_SETTER_CHECK_INPUT (obj);
195 	MixBufferPrivate *priv = (MixBufferPrivate *) obj->reserved;
196 	priv->pool = pool;
197 
198 	return MIX_RESULT_SUCCESS;
199 }
200 
mix_buffer_unref(MixBuffer * obj)201 void mix_buffer_unref(MixBuffer * obj) {
202 
203 	// Unref through base class
204 	mix_params_unref(MIX_PARAMS(obj));
205 
206 	LOG_I( "refcount = %d\n", MIX_PARAMS(
207 			obj)->refcount);
208 
209 	// Check if we have reduced to 1, in which case we add ourselves to free pool
210 	if (MIX_PARAMS(obj)->refcount == 1) {
211 		MixBufferPrivate *priv = (MixBufferPrivate *) obj->reserved;
212 		g_return_if_fail(priv->pool != NULL);
213 
214 		if (obj->callback) {
215 			obj->callback(obj->token, obj->data);
216 		}
217 		mix_bufferpool_put(priv->pool, obj);
218 	}
219 }
220 
221