1bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/*
2bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee INTEL CONFIDENTIAL
3bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee Copyright 2009 Intel Corporation All Rights Reserved.
4bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 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.
5bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
6bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 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.
7bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
8bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
9bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
10bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * SECTION:mixsurfacepool
11bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @short_description: MI-X Video Surface Pool
12bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
13bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * A data object which stores and manipulates a pool of video surfaces.
14bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
15bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
16bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "mixvideolog.h"
17bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "mixsurfacepool.h"
18bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "mixvideoframe_private.h"
19bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
20bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#define MIX_LOCK(lock) g_mutex_lock(lock);
21bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#define MIX_UNLOCK(lock) g_mutex_unlock(lock);
22bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
23bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#define SAFE_FREE(p) if(p) { g_free(p); p = NULL; }
24bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
25bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic GType _mix_surfacepool_type = 0;
26bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic MixParamsClass *parent_class = NULL;
27bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
28bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#define _do_init { _mix_surfacepool_type = g_define_type_id; }
29bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
30bd8388b4555645b3d29abc6a94c303638064d69awonjong.leegboolean mix_surfacepool_copy(MixParams * target, const MixParams * src);
31bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMixParams *mix_surfacepool_dup(const MixParams * obj);
32bd8388b4555645b3d29abc6a94c303638064d69awonjong.leegboolean mix_surfacepool_equal(MixParams * first, MixParams * second);
33bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void mix_surfacepool_finalize(MixParams * obj);
34bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
35bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeG_DEFINE_TYPE_WITH_CODE (MixSurfacePool, mix_surfacepool, MIX_TYPE_PARAMS,
36bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		_do_init);
37bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
38bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void mix_surfacepool_init(MixSurfacePool * self) {
39bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* initialize properties here */
40bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->free_list = NULL;
41bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->in_use_list = NULL;
42bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->free_list_max_size = 0;
43bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->free_list_cur_size = 0;
44bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->high_water_mark = 0;
45bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
46bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->reserved1 = NULL;
47bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->reserved2 = NULL;
48bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->reserved3 = NULL;
49bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->reserved4 = NULL;
50bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
51bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	// TODO: relocate this mutex allocation -we can't communicate failure in ctor.
52bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	// Note that g_thread_init() has already been called by mix_video_init()
53bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->objectlock = g_mutex_new();
54bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
55bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
56bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
57bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void mix_surfacepool_class_init(MixSurfacePoolClass * klass) {
58bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixParamsClass *mixparams_class = MIX_PARAMS_CLASS(klass);
59bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
60bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* setup static parent class */
61bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent_class = (MixParamsClass *) g_type_class_peek_parent(klass);
62bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
63bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mixparams_class->finalize = mix_surfacepool_finalize;
64bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mixparams_class->copy = (MixParamsCopyFunction) mix_surfacepool_copy;
65bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mixparams_class->dup = (MixParamsDupFunction) mix_surfacepool_dup;
66bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mixparams_class->equal = (MixParamsEqualFunction) mix_surfacepool_equal;
67bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
68bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
69bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMixSurfacePool *
70bd8388b4555645b3d29abc6a94c303638064d69awonjong.leemix_surfacepool_new(void) {
71bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixSurfacePool *ret = (MixSurfacePool *) g_type_create_instance(
72bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			MIX_TYPE_SURFACEPOOL);
73bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
74bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
75bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
76bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid mix_surfacepool_finalize(MixParams * obj) {
77bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* clean up here. */
78bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
79bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixSurfacePool *self = MIX_SURFACEPOOL(obj);
80bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
81bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (self->objectlock) {
82bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		g_mutex_free(self->objectlock);
83bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		self->objectlock = NULL;
84bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
85bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
86bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Chain up parent */
87bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (parent_class->finalize) {
88bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		parent_class->finalize(obj);
89bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
90bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
91bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
92bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMixSurfacePool *
93bd8388b4555645b3d29abc6a94c303638064d69awonjong.leemix_surfacepool_ref(MixSurfacePool * mix) {
94bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return (MixSurfacePool *) mix_params_ref(MIX_PARAMS(mix));
95bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
96bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
97bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
98bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_dup:
99bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @obj: a #MixSurfacePool object
100bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: a newly allocated duplicate of the object.
101bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
102bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Copy duplicate of the object.
103bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
104bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMixParams *
105bd8388b4555645b3d29abc6a94c303638064d69awonjong.leemix_surfacepool_dup(const MixParams * obj) {
106bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixParams *ret = NULL;
107bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
108bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (MIX_IS_SURFACEPOOL(obj)) {
109bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
110bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_LOCK(MIX_SURFACEPOOL(obj)->objectlock);
111bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
112bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MixSurfacePool *duplicate = mix_surfacepool_new();
113bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (mix_surfacepool_copy(MIX_PARAMS(duplicate), MIX_PARAMS(obj))) {
114bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_PARAMS(duplicate);
115bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		} else {
116bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_surfacepool_unref(duplicate);
117bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
118bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
119bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(MIX_SURFACEPOOL(obj)->objectlock);
120bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
121bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
122bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
123bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
124bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
125bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
126bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_copy:
127bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @target: copy to target
128bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @src: copy from src
129bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: boolean indicates if copy is successful.
130bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
131bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Copy instance data from @src to @target.
132bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
133bd8388b4555645b3d29abc6a94c303638064d69awonjong.leegboolean mix_surfacepool_copy(MixParams * target, const MixParams * src) {
134bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixSurfacePool *this_target, *this_src;
135bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
136bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (MIX_IS_SURFACEPOOL(target) && MIX_IS_SURFACEPOOL(src)) {
137bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
138bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_LOCK(MIX_SURFACEPOOL(src)->objectlock);
139bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_LOCK(MIX_SURFACEPOOL(target)->objectlock);
140bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
141bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Cast the base object to this child object
142bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_target = MIX_SURFACEPOOL(target);
143bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_src = MIX_SURFACEPOOL(src);
144bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
145bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Free the existing properties
146bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
147bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Duplicate string
148bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_target->free_list = this_src->free_list;
149bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_target->in_use_list = this_src->in_use_list;
150bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_target->free_list_max_size = this_src->free_list_max_size;
151bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_target->free_list_cur_size = this_src->free_list_cur_size;
152bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_target->high_water_mark = this_src->high_water_mark;
153bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
154bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(MIX_SURFACEPOOL(src)->objectlock);
155bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(MIX_SURFACEPOOL(target)->objectlock);
156bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
157bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Now chainup base class
158bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (parent_class->copy) {
159bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			return parent_class->copy(MIX_PARAMS_CAST(target), MIX_PARAMS_CAST(
160bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					src));
161bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		} else {
162bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			return TRUE;
163bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
164bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
165bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return FALSE;
166bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
167bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
168bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
169bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_equal:
170bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @first: first object to compare
171bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @second: seond object to compare
172bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: boolean indicates if instance are equal.
173bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
174bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Copy instance data from @src to @target.
175bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
176bd8388b4555645b3d29abc6a94c303638064d69awonjong.leegboolean mix_surfacepool_equal(MixParams * first, MixParams * second) {
177bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gboolean ret = FALSE;
178bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixSurfacePool *this_first, *this_second;
179bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
180bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (MIX_IS_SURFACEPOOL(first) && MIX_IS_SURFACEPOOL(second)) {
181bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Deep compare
182bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Cast the base object to this child object
183bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
184bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_LOCK(MIX_SURFACEPOOL(first)->objectlock);
185bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_LOCK(MIX_SURFACEPOOL(second)->objectlock);
186bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
187bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_first = MIX_SURFACEPOOL(first);
188bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		this_second = MIX_SURFACEPOOL(second);
189bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
190bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		/* TODO: add comparison for other properties */
191bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (this_first->free_list == this_second->free_list
192bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				&& this_first->in_use_list == this_second->in_use_list
193bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				&& this_first->free_list_max_size
194bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee						== this_second->free_list_max_size
195bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				&& this_first->free_list_cur_size
196bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee						== this_second->free_list_cur_size
197bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				&& this_first->high_water_mark == this_second->high_water_mark) {
198bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			// members within this scope equal. chaining up.
199bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			MixParamsClass *klass = MIX_PARAMS_CLASS(parent_class);
200bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (klass->equal)
201bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = klass->equal(first, second);
202bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			else
203bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = TRUE;
204bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
205bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
206bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_LOCK(MIX_SURFACEPOOL(first)->objectlock);
207bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_LOCK(MIX_SURFACEPOOL(second)->objectlock);
208bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
209bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
210bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
211bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
212bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
213bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
214bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/*  Class Methods  */
215bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
216bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
217bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_initialize:
218bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: MIX_RESULT_SUCCESS if successful in creating the surface pool
219bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
220bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Use this method to create a new surface pool, consisting of a GSList of
221bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * frame objects that represents a pool of surfaces.
222bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
223bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_surfacepool_initialize(MixSurfacePool * obj,
224bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		VASurfaceID *surfaces, guint num_surfaces) {
225bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
226bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
227bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
228bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj == NULL || surfaces == NULL) {
229bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
230bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E(
231bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				"Error NULL ptrs, obj %x, surfaces %x\n", (guint) obj,
232bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				(guint) surfaces);
233bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
234bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
235bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
236bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
237bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_LOCK(obj->objectlock);
238bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
239bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((obj->free_list != NULL) || (obj->in_use_list != NULL)) {
240bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//surface pool is in use; return error; need proper cleanup
241bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO need cleanup here?
242bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
243bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
244bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
245bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_ALREADY_INIT;
246bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
247bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
248bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (num_surfaces == 0) {
249bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->free_list = NULL;
250bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
251bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->in_use_list = NULL;
252bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
253bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->free_list_max_size = num_surfaces;
254bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
255bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->free_list_cur_size = num_surfaces;
256bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
257bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->high_water_mark = 0;
258bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
259bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
260bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
261bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_SUCCESS;
262bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
263bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
264bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	// Initialize the free pool with frame objects
265bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
266bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gint i = 0;
267bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFrame *frame = NULL;
268bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
269bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	for (; i < num_surfaces; i++) {
270bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
271bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Create a frame object for each surface ID
272bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		frame = mix_videoframe_new();
273bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
274bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (frame == NULL) {
275bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//TODO need to log an error here and do cleanup
276bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
277bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			MIX_UNLOCK(obj->objectlock);
278bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
279bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			return MIX_RESULT_NO_MEMORY;
280bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
281bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
282bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Set the frame ID to the surface ID
283bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_frame_id(frame, surfaces[i]);
284bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Set the ci frame index to the surface ID
285bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_ci_frame_idx (frame, i);
286bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Leave timestamp for each frame object as zero
287bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		// Set the pool reference in the private data of the frame object
288bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_pool(frame, obj);
289bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
290bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Add each frame object to the pool list
291bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->free_list = g_slist_append(obj->free_list, frame);
292bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
293bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
294bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
295bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->in_use_list = NULL;
296bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
297bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->free_list_max_size = num_surfaces;
298bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
299bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->free_list_cur_size = num_surfaces;
300bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
301bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->high_water_mark = 0;
302bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
303bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_UNLOCK(obj->objectlock);
304bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
305bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
306bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
307bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
308bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
309bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
310bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
311bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_put:
312bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: SUCCESS or FAILURE
313bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
314bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Use this method to return a surface to the free pool
315bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
316bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_surfacepool_put(MixSurfacePool * obj, MixVideoFrame * frame) {
317bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
318bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
319bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj == NULL || frame == NULL)
320bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
321bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
322bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Frame id: %d\n", frame->frame_id);
323bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_LOCK(obj->objectlock);
324bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
325bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj->in_use_list == NULL) {
326bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//in use list cannot be empty if a frame is in use
327bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO need better error code for this
328bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
329bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
330bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
331bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_FAIL;
332bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
333bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
334bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	GSList *element = g_slist_find(obj->in_use_list, frame);
335bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (element == NULL) {
336bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Integrity error; frame not found in in use list
337bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO need better error code and handling for this
338bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
339bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
340bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
341bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_FAIL;
342bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	} else {
343bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Remove this element from the in_use_list
344bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->in_use_list = g_slist_remove_link(obj->in_use_list, element);
345bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
346bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Concat the element to the free_list and reset the timestamp of the frame
347bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Note that the surface ID stays valid
348bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_timestamp(frame, 0);
349bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->free_list = g_slist_concat(obj->free_list, element);
350bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
351bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//increment the free list count
352bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->free_list_cur_size++;
353bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
354bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
355bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Note that we do nothing with the ref count for this.  We want it to
356bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//stay at 1, which is what triggered it to be added back to the free list.
357bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
358bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_UNLOCK(obj->objectlock);
359bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
360bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
361bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
362bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
363bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
364bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
365bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_get:
366bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: SUCCESS or FAILURE
367bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
368bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Use this method to get a surface from the free pool
369bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
370bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_surfacepool_get(MixSurfacePool * obj, MixVideoFrame ** frame) {
371bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
372bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
373bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
374bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj == NULL || frame == NULL)
375bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
376bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
377bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_LOCK(obj->objectlock);
378bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
379bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#if 0
380bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj->free_list == NULL) {
381bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#else
382bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj->free_list_cur_size <= 1) {  //Keep one surface free at all times for VBLANK bug
383bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif
384bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//We are out of surfaces
385bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO need to log this as well
386bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
387bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
388bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
389bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "out of surfaces\n");
390bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
391bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NO_MEMORY;
392bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
393bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
394bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Remove a frame from the free pool
395bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
396bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//We just remove the one at the head, since it's convenient
397bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	GSList *element = obj->free_list;
398bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->free_list = g_slist_remove_link(obj->free_list, element);
399bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (element == NULL) {
400bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Unexpected behavior
401bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO need better error code and handling for this
402bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
403bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
404bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
405bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Element is null\n");
406bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
407bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_FAIL;
408bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	} else {
409bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Concat the element to the in_use_list
410bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->in_use_list = g_slist_concat(obj->in_use_list, element);
411bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
412bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO replace with proper logging
413bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
414bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_I( "frame refcount%d\n",
415bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				MIX_PARAMS(element->data)->refcount);
416bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
417bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Set the out frame pointer
418bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		*frame = (MixVideoFrame *) element->data;
419bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
420bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Frame id: %d\n", (*frame)->frame_id);
421bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
422bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//decrement the free list count
423bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->free_list_cur_size--;
424bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
425bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Check the high water mark for surface use
426bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		guint size = g_slist_length(obj->in_use_list);
427bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (size > obj->high_water_mark)
428bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			obj->high_water_mark = size;
429bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO Log this high water mark
430bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
431bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
432bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Increment the reference count for the frame
433bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mix_videoframe_ref(*frame);
434bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
435bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_UNLOCK(obj->objectlock);
436bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
437bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
438bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
439bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
440bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
441bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
442bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
443bd8388b4555645b3d29abc6a94c303638064d69awonjong.leegint mixframe_compare_index (MixVideoFrame * a, MixVideoFrame * b)
444bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
445bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (a == NULL || b == NULL)
446bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 return -1;
447bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (a->ci_frame_idx == b->ci_frame_idx)
448bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        return 0;
449bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    else
450bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        return -1;
451bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
452bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
453bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
454bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_get:
455bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: SUCCESS or FAILURE
456bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
457bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Use this method to get a surface from the free pool according to the CI frame idx
458bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
459bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
460bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_surfacepool_get_frame_with_ci_frameidx (MixSurfacePool * obj, MixVideoFrame ** frame, MixVideoFrame *in_frame) {
461bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
462bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
463bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
464bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj == NULL || frame == NULL)
465bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
466bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
467bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_LOCK(obj->objectlock);
468bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
469bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj->free_list == NULL) {
470bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//We are out of surfaces
471bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO need to log this as well
472bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
473bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
474bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
475bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "out of surfaces\n");
476bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
477bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NO_MEMORY;
478bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
479bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
480bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Remove a frame from the free pool
481bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
482bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//We just remove the one at the head, since it's convenient
483bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	GSList *element = g_slist_find_custom (obj->free_list, in_frame, (GCompareFunc) mixframe_compare_index);
484bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->free_list = g_slist_remove_link(obj->free_list, element);
485bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (element == NULL) {
486bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Unexpected behavior
487bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO need better error code and handling for this
488bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
489bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
490bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
491bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Element is null\n");
492bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
493bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_FAIL;
494bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	} else {
495bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Concat the element to the in_use_list
496bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->in_use_list = g_slist_concat(obj->in_use_list, element);
497bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
498bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO replace with proper logging
499bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
500bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_I( "frame refcount%d\n",
501bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				MIX_PARAMS(element->data)->refcount);
502bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
503bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Set the out frame pointer
504bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		*frame = (MixVideoFrame *) element->data;
505bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
506bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Check the high water mark for surface use
507bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		guint size = g_slist_length(obj->in_use_list);
508bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (size > obj->high_water_mark)
509bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			obj->high_water_mark = size;
510bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO Log this high water mark
511bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
512bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
513bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Increment the reference count for the frame
514bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mix_videoframe_ref(*frame);
515bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
516bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_UNLOCK(obj->objectlock);
517bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
518bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
519bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
520bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
521bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
522bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
523bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_check_available:
524bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: SUCCESS or FAILURE
525bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
526bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Use this method to check availability of getting a surface from the free pool
527bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
528bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_surfacepool_check_available(MixSurfacePool * obj) {
529bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
530bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
531bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
532bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj == NULL)
533bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
534bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
535bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_LOCK(obj->objectlock);
536bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
537bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#if 0
538bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj->free_list == NULL) {
539bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#else
540bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj->free_list_cur_size <= 1) {  //Keep one surface free at all times for VBLANK bug
541bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif
542bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//We are out of surfaces
543bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
544bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
545bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
546bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_W(
547bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				"Returning MIX_RESULT_POOLEMPTY because out of surfaces\n");
548bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
549bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_POOLEMPTY;
550bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	} else {
551bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Pool is not empty
552bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
553bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
554bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
555bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_I(
556bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				"Returning MIX_RESULT_SUCCESS because surfaces are available\n");
557bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
558bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_SUCCESS;
559bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
560bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
561bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
562bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
563bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
564bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * mix_surfacepool_deinitialize:
565bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * @returns: SUCCESS or FAILURE
566bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee *
567bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Use this method to teardown a surface pool
568bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
569bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_surfacepool_deinitialize(MixSurfacePool * obj) {
570bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (obj == NULL)
571bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
572bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
573bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_LOCK(obj->objectlock);
574bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
575bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((obj->in_use_list != NULL) || (g_slist_length(obj->free_list)
576bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			!= obj->free_list_max_size)) {
577bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//TODO better error code
578bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//We have outstanding frame objects in use and they need to be
579bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//freed before we can deinitialize.
580bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
581bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_UNLOCK(obj->objectlock);
582bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
583bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_FAIL;
584bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
585bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
586bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Now remove frame objects from the list
587bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
588bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFrame *frame = NULL;
589bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
590bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	while (obj->free_list != NULL) {
591bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Get the frame object from the head of the list
592bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		frame = obj->free_list->data;
593bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//frame = g_slist_nth_data(obj->free_list, 0);
594bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
595bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Release it
596bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_unref(frame);
597bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
598bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Delete the head node of the list and store the new head
599bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		obj->free_list = g_slist_delete_link(obj->free_list, obj->free_list);
600bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
601bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Repeat until empty
602bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
603bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
604bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->free_list_max_size = 0;
605bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->free_list_cur_size = 0;
606bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
607bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//May want to log this information for tuning
608bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	obj->high_water_mark = 0;
609bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
610bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_UNLOCK(obj->objectlock);
611bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
612bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
613bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
614bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
615bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#define MIX_SURFACEPOOL_SETTER_CHECK_INPUT(obj) \
616bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if(!obj) return MIX_RESULT_NULL_PTR; \
617bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if(!MIX_IS_SURFACEPOOL(obj)) return MIX_RESULT_FAIL; \
618bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
619bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#define MIX_SURFACEPOOL_GETTER_CHECK_INPUT(obj, prop) \
620bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if(!obj || !prop) return MIX_RESULT_NULL_PTR; \
621bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if(!MIX_IS_SURFACEPOOL(obj)) return MIX_RESULT_FAIL; \
622bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
623bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
624bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT
625bd8388b4555645b3d29abc6a94c303638064d69awonjong.leemix_surfacepool_dumpframe(MixVideoFrame *frame)
626bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
627bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_I( "\tFrame %x, id %lu, refcount %d, ts %lu\n", (guint)frame,
628bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			frame->frame_id, MIX_PARAMS(frame)->refcount, (gulong) frame->timestamp);
629bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
630bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
631bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
632bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
633bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT
634bd8388b4555645b3d29abc6a94c303638064d69awonjong.leemix_surfacepool_dumpprint (MixSurfacePool * obj)
635bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
636bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//TODO replace this with proper logging later
637bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
638bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_I( "SURFACE POOL DUMP:\n");
639bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_I( "Free list size is %d\n", obj->free_list_cur_size);
640bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_I( "In use list size is %d\n", g_slist_length(obj->in_use_list));
641bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_I( "High water mark is %lu\n", obj->high_water_mark);
642bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
643bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Walk the free list and report the contents
644bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_I( "Free list contents:\n");
645bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	g_slist_foreach(obj->free_list, (GFunc) mix_surfacepool_dumpframe, NULL);
646bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
647bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Walk the in_use list and report the contents
648bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_I( "In Use list contents:\n");
649bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	g_slist_foreach(obj->in_use_list, (GFunc) mix_surfacepool_dumpframe, NULL);
650bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
651bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
652bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
653