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