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
22static GType _mix_buffer_type = 0;
23static MixParamsClass *parent_class = NULL;
24
25#define _do_init { _mix_buffer_type = g_define_type_id; }
26
27gboolean mix_buffer_copy(MixParams * target, const MixParams * src);
28MixParams *mix_buffer_dup(const MixParams * obj);
29gboolean mix_buffer_equal(MixParams * first, MixParams * second);
30static void mix_buffer_finalize(MixParams * obj);
31
32G_DEFINE_TYPE_WITH_CODE (MixBuffer, mix_buffer, MIX_TYPE_PARAMS,
33		_do_init);
34
35static 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
49static 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
64MixBuffer *
65mix_buffer_new(void) {
66	MixBuffer *ret = (MixBuffer *) g_type_create_instance(MIX_TYPE_BUFFER);
67	return ret;
68}
69
70void 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
81MixBuffer *
82mix_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 */
93MixParams *
94mix_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 */
116gboolean 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 */
149gboolean 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
180MIX_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
192MIX_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
201void 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