Home | History | Annotate | Download | only in src
      1 /*
      2  INTEL CONFIDENTIAL
      3  Copyright 2009 Intel Corporation All Rights Reserved.
      4  The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intels prior express written permission.
      5 
      6  No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
      7  */
      8 
      9 #include <va/va.h>             /* libVA */
     10 #include <X11/Xlib.h>
     11 #include <va/va_x11.h>
     12 
     13 #include "mixvideolog.h"
     14 
     15 #include "mixdisplayx11.h"
     16 #include "mixvideoframe.h"
     17 
     18 #include "mixframemanager.h"
     19 #include "mixvideorenderparams.h"
     20 #include "mixvideorenderparams_internal.h"
     21 
     22 #include "mixvideoformat.h"
     23 #include "mixvideoformat_vc1.h"
     24 #include "mixvideoformat_h264.h"
     25 #include "mixvideoformat_mp42.h"
     26 
     27 #include "mixvideoconfigparamsdec_vc1.h"
     28 #include "mixvideoconfigparamsdec_h264.h"
     29 #include "mixvideoconfigparamsdec_mp42.h"
     30 
     31 #include "mixvideoformatenc.h"
     32 #include "mixvideoformatenc_h264.h"
     33 #include "mixvideoformatenc_mpeg4.h"
     34 #include "mixvideoformatenc_preview.h"
     35 
     36 #include "mixvideoconfigparamsenc_h264.h"
     37 #include "mixvideoconfigparamsenc_mpeg4.h"
     38 #include "mixvideoconfigparamsenc_preview.h"
     39 
     40 
     41 #include "mixvideo.h"
     42 #include "mixvideo_private.h"
     43 
     44 #define USE_OPAQUE_POINTER
     45 
     46 #ifdef USE_OPAQUE_POINTER
     47 #define MIX_VIDEO_PRIVATE(mix) (MixVideoPrivate *)(mix->context)
     48 #else
     49 #define MIX_VIDEO_PRIVATE(mix) MIX_VIDEO_GET_PRIVATE(mix)
     50 #endif
     51 
     52 #define CHECK_INIT(mix, priv) \
     53 	if (!mix) { \
     54 		return MIX_RESULT_NULL_PTR; \
     55 	} \
     56 	if (!MIX_IS_VIDEO(mix)) { \
     57 		LOG_E( "Not MixVideo\n"); \
     58 		return MIX_RESULT_INVALID_PARAM; \
     59 	} \
     60 	priv = MIX_VIDEO_PRIVATE(mix); \
     61 	if (!priv->initialized) { \
     62 		LOG_E( "Not initialized\n"); \
     63 		return MIX_RESULT_NOT_INIT; \
     64 	}
     65 
     66 #define CHECK_INIT_CONFIG(mix, priv) \
     67 	CHECK_INIT(mix, priv); \
     68 	if (!priv->configured) { \
     69 		LOG_E( "Not configured\n"); \
     70 		return MIX_RESULT_NOT_CONFIGURED; \
     71 	}
     72 
     73 /*
     74  * default implementation of virtual methods
     75  */
     76 
     77 MIX_RESULT mix_video_get_version_default(MixVideo * mix, guint * major,
     78 		guint * minor);
     79 
     80 MIX_RESULT mix_video_initialize_default(MixVideo * mix, MixCodecMode mode,
     81 		MixVideoInitParams * init_params, MixDrmParams * drm_init_params);
     82 
     83 MIX_RESULT mix_video_deinitialize_default(MixVideo * mix);
     84 
     85 MIX_RESULT mix_video_configure_default(MixVideo * mix,
     86 		MixVideoConfigParams * config_params, MixDrmParams * drm_config_params);
     87 
     88 MIX_RESULT mix_video_get_config_default(MixVideo * mix,
     89 		MixVideoConfigParams ** config_params);
     90 
     91 MIX_RESULT mix_video_decode_default(MixVideo * mix, MixBuffer * bufin[],
     92 		gint bufincnt, MixVideoDecodeParams * decode_params);
     93 
     94 MIX_RESULT mix_video_get_frame_default(MixVideo * mix, MixVideoFrame ** frame);
     95 
     96 MIX_RESULT mix_video_release_frame_default(MixVideo * mix,
     97 		MixVideoFrame * frame);
     98 
     99 MIX_RESULT mix_video_render_default(MixVideo * mix,
    100 		MixVideoRenderParams * render_params, MixVideoFrame *frame);
    101 
    102 MIX_RESULT mix_video_encode_default(MixVideo * mix, MixBuffer * bufin[],
    103 		gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
    104 		MixVideoEncodeParams * encode_params);
    105 
    106 MIX_RESULT mix_video_flush_default(MixVideo * mix);
    107 
    108 MIX_RESULT mix_video_eos_default(MixVideo * mix);
    109 
    110 MIX_RESULT mix_video_get_state_default(MixVideo * mix, MixState * state);
    111 
    112 MIX_RESULT mix_video_get_mixbuffer_default(MixVideo * mix, MixBuffer ** buf);
    113 
    114 MIX_RESULT mix_video_release_mixbuffer_default(MixVideo * mix, MixBuffer * buf);
    115 
    116 MIX_RESULT mix_video_get_max_coded_buffer_size_default (MixVideo * mix, guint *max_size);
    117 
    118 
    119 static void mix_video_finalize(GObject * obj);
    120 MIX_RESULT mix_video_configure_decode(MixVideo * mix,
    121 		MixVideoConfigParamsDec * config_params_dec,
    122 		MixDrmParams * drm_config_params);
    123 
    124 MIX_RESULT mix_video_configure_encode(MixVideo * mix,
    125 		MixVideoConfigParamsEnc * config_params_enc,
    126 		MixDrmParams * drm_config_params);
    127 
    128 G_DEFINE_TYPE( MixVideo, mix_video, G_TYPE_OBJECT);
    129 
    130 static void mix_video_init(MixVideo * self) {
    131 
    132 	MixVideoPrivate *priv = MIX_VIDEO_GET_PRIVATE(self);
    133 
    134 #ifdef USE_OPAQUE_POINTER
    135 	self->context = priv;
    136 #else
    137 	self->context = NULL;
    138 #endif
    139 
    140 	/* private structure initialization */
    141 
    142 	mix_video_private_initialize(priv);
    143 }
    144 
    145 static void mix_video_class_init(MixVideoClass * klass) {
    146 	GObjectClass *gobject_class = (GObjectClass *) klass;
    147 
    148 	gobject_class->finalize = mix_video_finalize;
    149 
    150 	/* Register and allocate the space the private structure for this object */
    151 	g_type_class_add_private(gobject_class, sizeof(MixVideoPrivate));
    152 
    153 	klass->get_version_func = mix_video_get_version_default;
    154 	klass->initialize_func = mix_video_initialize_default;
    155 	klass->deinitialize_func = mix_video_deinitialize_default;
    156 	klass->configure_func = mix_video_configure_default;
    157 	klass->get_config_func = mix_video_get_config_default;
    158 	klass->decode_func = mix_video_decode_default;
    159 	klass->get_frame_func = mix_video_get_frame_default;
    160 	klass->release_frame_func = mix_video_release_frame_default;
    161 	klass->render_func = mix_video_render_default;
    162 	klass->encode_func = mix_video_encode_default;
    163 	klass->flush_func = mix_video_flush_default;
    164 	klass->eos_func = mix_video_eos_default;
    165 	klass->get_state_func = mix_video_get_state_default;
    166 	klass->get_mix_buffer_func = mix_video_get_mixbuffer_default;
    167 	klass->release_mix_buffer_func = mix_video_release_mixbuffer_default;
    168 	klass->get_max_coded_buffer_size_func = mix_video_get_max_coded_buffer_size_default;
    169 }
    170 
    171 MixVideo *mix_video_new(void) {
    172 
    173 	MixVideo *ret = g_object_new(MIX_TYPE_VIDEO, NULL);
    174 
    175 	return ret;
    176 }
    177 
    178 void mix_video_finalize(GObject * obj) {
    179 
    180 	/* clean up here. */
    181 
    182 	MixVideo *mix = MIX_VIDEO(obj);
    183 	mix_video_deinitialize(mix);
    184 }
    185 
    186 MixVideo *
    187 mix_video_ref(MixVideo * mix) {
    188 	return (MixVideo *) g_object_ref(G_OBJECT(mix));
    189 }
    190 
    191 /* private methods */
    192 
    193 #define MIXUNREF(obj, unref) if(obj) { unref(obj); obj = NULL; }
    194 
    195 void mix_video_private_initialize(MixVideoPrivate* priv) {
    196 	priv->objlock = NULL;
    197 	priv->initialized = FALSE;
    198 	priv->configured = FALSE;
    199 
    200 	/* libVA */
    201 	priv->va_display = NULL;
    202 	priv->va_major_version = -1;
    203 	priv->va_major_version = -1;
    204 
    205 	/* mix objects */
    206 	priv->frame_manager = NULL;
    207 	priv->video_format = NULL;
    208 	priv->video_format_enc = NULL; //for encoding
    209 	priv->surface_pool = NULL;
    210 	priv->buffer_pool = NULL;
    211 
    212 	priv->codec_mode = MIX_CODEC_MODE_DECODE;
    213 	priv->init_params = NULL;
    214 	priv->drm_params = NULL;
    215 	priv->config_params = NULL;
    216 }
    217 
    218 void mix_video_private_cleanup(MixVideoPrivate* priv) {
    219 
    220 	VAStatus va_status;
    221 
    222 	if (!priv) {
    223 		return;
    224 	}
    225 
    226 	if (priv->video_format_enc) {
    227 		mix_videofmtenc_deinitialize(priv->video_format_enc);
    228 	}
    229 
    230 	MIXUNREF(priv->frame_manager, mix_framemanager_unref)
    231 	MIXUNREF(priv->video_format, mix_videoformat_unref)
    232 	MIXUNREF(priv->video_format_enc, mix_videoformatenc_unref)
    233 	//for encoding
    234 	MIXUNREF(priv->buffer_pool, mix_bufferpool_unref)
    235 	MIXUNREF(priv->surface_pool, mix_surfacepool_unref)
    236 /*	MIXUNREF(priv->init_params, mix_videoinitparams_unref) */
    237 	MIXUNREF(priv->drm_params, mix_drmparams_unref)
    238 	MIXUNREF(priv->config_params, mix_videoconfigparams_unref)
    239 
    240 	/* terminate libVA */
    241 	if (priv->va_display) {
    242 		va_status = vaTerminate(priv->va_display);
    243 		LOG_V( "vaTerminate\n");
    244 		if (va_status != VA_STATUS_SUCCESS) {
    245 			LOG_W( "Failed vaTerminate\n");
    246 		} else {
    247 			priv->va_display = NULL;
    248 		}
    249 	}
    250 
    251 	MIXUNREF(priv->init_params, mix_videoinitparams_unref)
    252 
    253 	priv->va_major_version = -1;
    254 	priv->va_major_version = -1;
    255 
    256 	if (priv->objlock) {
    257 		g_mutex_free(priv->objlock);
    258 		priv->objlock = NULL;
    259 	}
    260 
    261 	priv->codec_mode = MIX_CODEC_MODE_DECODE;
    262 	priv->initialized = FALSE;
    263 	priv->configured = FALSE;
    264 }
    265 
    266 /* The following methods are defined in MI-X API */
    267 
    268 MIX_RESULT mix_video_get_version_default(MixVideo * mix, guint * major,
    269 		guint * minor) {
    270 	if (!mix || !major || !minor) {
    271 		return MIX_RESULT_NULL_PTR;
    272 	}
    273 
    274 	if (!MIX_IS_VIDEO(mix)) {
    275 		return MIX_RESULT_INVALID_PARAM;
    276 	}
    277 
    278 	*major = MIXVIDEO_CURRENT - MIXVIDEO_AGE;
    279 	*minor = MIXVIDEO_AGE;
    280 
    281 	return MIX_RESULT_SUCCESS;
    282 }
    283 
    284 MIX_RESULT mix_video_initialize_default(MixVideo * mix, MixCodecMode mode,
    285 		MixVideoInitParams * init_params, MixDrmParams * drm_init_params) {
    286 
    287 	MIX_RESULT ret = MIX_RESULT_FAIL;
    288 	MixVideoPrivate *priv = NULL;
    289 	MixDisplay *mix_display = NULL;
    290 
    291 	LOG_V( "Begin\n");
    292 
    293 	if (!mix || !init_params) {
    294 		LOG_E( "!mix || !init_params\n");
    295 		return MIX_RESULT_NULL_PTR;
    296 	}
    297 
    298 	if (mode >= MIX_CODEC_MODE_LAST) {
    299 		LOG_E("mode >= MIX_CODEC_MODE_LAST\n");
    300 		return MIX_RESULT_INVALID_PARAM;
    301 	}
    302 
    303 #if 0  //we have encoding support
    304 	/* TODO: We need to support encoding in the future */
    305 	if (mode == MIX_CODEC_MODE_ENCODE) {
    306 		LOG_E("mode == MIX_CODEC_MODE_ENCODE\n");
    307 		return MIX_RESULT_NOTIMPL;
    308 	}
    309 #endif
    310 
    311 	if (!MIX_IS_VIDEO(mix)) {
    312 		LOG_E( "!MIX_IS_VIDEO(mix)\n");
    313 		return MIX_RESULT_INVALID_PARAM;
    314 	}
    315 
    316 	if (!MIX_IS_VIDEOINITPARAMS(init_params)) {
    317 		LOG_E("!MIX_IS_VIDEOINITPARAMS(init_params\n");
    318 		return MIX_RESULT_INVALID_PARAM;
    319 	}
    320 
    321 	priv = MIX_VIDEO_PRIVATE(mix);
    322 
    323 	if (priv->initialized) {
    324 		LOG_W( "priv->initialized\n");
    325 		return MIX_RESULT_ALREADY_INIT;
    326 	}
    327 
    328 	/*
    329 	 * Init thread before any threads/sync object are used.
    330 	 * TODO: If thread is not supported, what we do?
    331 	 */
    332 
    333 	if (!g_thread_supported()) {
    334 		LOG_W("!g_thread_supported()\n");
    335 		g_thread_init(NULL);
    336 	}
    337 
    338 	/* create object lock */
    339 	priv->objlock = g_mutex_new();
    340 	if (!priv->objlock) {
    341 		ret = MIX_RESULT_NO_MEMORY;
    342 		LOG_E( "!priv->objlock\n");
    343 		goto cleanup;
    344 	}
    345 
    346 	/* clone mode */
    347 	priv->codec_mode = mode;
    348 
    349 	/* ref init_params */
    350 	priv->init_params = (MixVideoInitParams *) mix_params_ref(MIX_PARAMS(
    351 			init_params));
    352 	if (!priv->init_params) {
    353 		ret = MIX_RESULT_NO_MEMORY;
    354 		LOG_E( "!priv->init_params\n");
    355 		goto cleanup;
    356 	}
    357 
    358 	/* NOTE: we don't do anything with drm_init_params */
    359 
    360 	/* libVA initialization */
    361 
    362 	{
    363 		VAStatus va_status;
    364 		Display *display = NULL;
    365 		ret = mix_videoinitparams_get_display(priv->init_params, &mix_display);
    366 		if (ret != MIX_RESULT_SUCCESS) {
    367 			LOG_E("Failed to get display 1\n");
    368 			goto cleanup;
    369 		}
    370 
    371 		if (MIX_IS_DISPLAYX11(mix_display)) {
    372 			MixDisplayX11 *mix_displayx11 = MIX_DISPLAYX11(mix_display);
    373 			ret = mix_displayx11_get_display(mix_displayx11, &display);
    374 			if (ret != MIX_RESULT_SUCCESS) {
    375 				LOG_E("Failed to get display 2\n");
    376 				goto cleanup;
    377 			}
    378 		} else {
    379 
    380 			/* TODO: add support to other MixDisplay type. For now, just return error!*/
    381 			LOG_E("It is not display x11\n");
    382 			ret = MIX_RESULT_FAIL;
    383 			goto cleanup;
    384 		}
    385 
    386 		/* Now, we can initialize libVA */
    387 		priv->va_display = vaGetDisplay(display);
    388 
    389 		/* Oops! Fail to get VADisplay */
    390 		if (!priv->va_display) {
    391 			ret = MIX_RESULT_FAIL;
    392 			LOG_E("Fail to get VADisplay\n");
    393 			goto cleanup;
    394 		}
    395 
    396 		/* Initialize libVA */
    397 		va_status = vaInitialize(priv->va_display, &priv->va_major_version,
    398 				&priv->va_minor_version);
    399 
    400 		/* Oops! Fail to initialize libVA */
    401 		if (va_status != VA_STATUS_SUCCESS) {
    402 			ret = MIX_RESULT_FAIL;
    403 			LOG_E("Fail to initialize libVA\n");
    404 			goto cleanup;
    405 		}
    406 
    407 		/* TODO: check the version numbers of libVA */
    408 
    409 		priv->initialized = TRUE;
    410 		ret = MIX_RESULT_SUCCESS;
    411 	}
    412 
    413 	cleanup:
    414 
    415 	if (ret != MIX_RESULT_SUCCESS) {
    416 		mix_video_private_cleanup(priv);
    417 	}
    418 
    419 	MIXUNREF(mix_display, mix_display_unref);
    420 
    421 	LOG_V( "End\n");
    422 
    423 	return ret;
    424 }
    425 
    426 MIX_RESULT mix_video_deinitialize_default(MixVideo * mix) {
    427 
    428 	MixVideoPrivate *priv = NULL;
    429 
    430 	LOG_V( "Begin\n");
    431 
    432 	CHECK_INIT(mix, priv);
    433 
    434 	mix_video_private_cleanup(priv);
    435 
    436 	LOG_V( "End\n");
    437 	return MIX_RESULT_SUCCESS;
    438 }
    439 
    440 MIX_RESULT mix_video_configure_decode(MixVideo * mix,
    441 		MixVideoConfigParamsDec * config_params_dec, MixDrmParams * drm_config_params) {
    442 
    443 	MIX_RESULT ret = MIX_RESULT_FAIL;
    444 	MixVideoPrivate *priv = NULL;
    445 	MixVideoConfigParamsDec *priv_config_params_dec = NULL;
    446 
    447 	gchar *mime_type = NULL;
    448 	guint fps_n, fps_d;
    449 	guint bufpoolsize = 0;
    450 
    451 	MixFrameOrderMode frame_order_mode = MIX_FRAMEORDER_MODE_DISPLAYORDER;
    452 
    453 	LOG_V( "Begin\n");
    454 
    455 	CHECK_INIT(mix, priv);
    456 
    457 	if (!config_params_dec) {
    458 		LOG_E( "!config_params_dec\n");
    459 		return MIX_RESULT_NULL_PTR;
    460 	}
    461 
    462 	if (!MIX_IS_VIDEOCONFIGPARAMSDEC(config_params_dec)) {
    463 		LOG_E("Not a MixVideoConfigParamsDec\n");
    464 		return MIX_RESULT_INVALID_PARAM;
    465 	}
    466 
    467 	/* ---------------------- begin lock --------------------- */
    468 	g_mutex_lock(priv->objlock);
    469 
    470 	/*
    471 	 * MixVideo has already been configured, it should be
    472 	 * re-configured.
    473 	 *
    474 	 * TODO: Allow MixVideo re-configuration
    475 	 */
    476 	if (priv->configured) {
    477 		ret = MIX_RESULT_SUCCESS;
    478 		LOG_W( "Already configured\n");
    479 		goto cleanup;
    480 	}
    481 
    482 	/* Make a copy of config_params */
    483 	priv->config_params = (MixVideoConfigParams *) mix_params_dup(MIX_PARAMS(
    484 			config_params_dec));
    485 	if (!priv->config_params) {
    486 		ret = MIX_RESULT_NO_MEMORY;
    487 		LOG_E("Fail to duplicate config_params\n");
    488 		goto cleanup;
    489 	}
    490 
    491 	priv_config_params_dec = (MixVideoConfigParamsDec *)priv->config_params;
    492 
    493 	/* Get fps, frame order mode and mime type from config_params */
    494 	ret = mix_videoconfigparamsdec_get_mime_type(priv_config_params_dec, &mime_type);
    495 	if (ret != MIX_RESULT_SUCCESS) {
    496 		LOG_E("Failed to get mime type\n");
    497 		goto cleanup;
    498 	}
    499 
    500 	LOG_I( "mime : %s\n", mime_type);
    501 
    502 #ifdef MIX_LOG_ENABLE
    503 	if (g_strcmp0(mime_type, "video/x-wmv") == 0) {
    504 
    505 		LOG_I( "mime : video/x-wmv\n");
    506 		if (MIX_IS_VIDEOCONFIGPARAMSDEC_VC1(priv_config_params_dec)) {
    507 			LOG_I( "VC1 config_param\n");
    508 		} else {
    509 			LOG_E("Not VC1 config_param\n");
    510 		}
    511 	}
    512 #endif
    513 
    514 	ret = mix_videoconfigparamsdec_get_frame_order_mode(priv_config_params_dec,
    515 			&frame_order_mode);
    516 	if (ret != MIX_RESULT_SUCCESS) {
    517 		LOG_E("Failed to frame order mode\n");
    518 		goto cleanup;
    519 	}
    520 
    521 	ret = mix_videoconfigparamsdec_get_frame_rate(priv_config_params_dec, &fps_n,
    522 			&fps_d);
    523 	if (ret != MIX_RESULT_SUCCESS) {
    524 		LOG_E("Failed to get frame rate\n");
    525 		goto cleanup;
    526 	}
    527 
    528 	if (!fps_n) {
    529 		ret = MIX_RESULT_FAIL;
    530 		LOG_E( "fps_n is 0\n");
    531 		goto cleanup;
    532 	}
    533 
    534 	ret = mix_videoconfigparamsdec_get_buffer_pool_size(priv_config_params_dec,
    535 			&bufpoolsize);
    536 	if (ret != MIX_RESULT_SUCCESS) {
    537 		LOG_E("Failed to get buffer pool size\n");
    538 		goto cleanup;
    539 	}
    540 
    541 	/* create frame manager */
    542 	priv->frame_manager = mix_framemanager_new();
    543 	if (!priv->frame_manager) {
    544 		ret = MIX_RESULT_NO_MEMORY;
    545 		LOG_E("Failed to create frame manager\n");
    546 		goto cleanup;
    547 	}
    548 
    549 	/* initialize frame manager */
    550 
    551 	if (g_strcmp0(mime_type, "video/x-wmv") == 0 || g_strcmp0(mime_type,
    552 			"video/mpeg") == 0 || g_strcmp0(mime_type, "video/x-divx") == 0) {
    553 		ret = mix_framemanager_initialize(priv->frame_manager,
    554 				frame_order_mode, fps_n, fps_d, FALSE);
    555 	} else {
    556 		ret = mix_framemanager_initialize(priv->frame_manager,
    557 				frame_order_mode, fps_n, fps_d, TRUE);
    558 	}
    559 
    560 	if (ret != MIX_RESULT_SUCCESS) {
    561 		LOG_E("Failed to initialize frame manager\n");
    562 		goto cleanup;
    563 	}
    564 
    565 	/* create buffer pool */
    566 	priv->buffer_pool = mix_bufferpool_new();
    567 	if (!priv->buffer_pool) {
    568 		ret = MIX_RESULT_NO_MEMORY;
    569 		LOG_E("Failed to create buffer pool\n");
    570 		goto cleanup;
    571 	}
    572 
    573 	ret = mix_bufferpool_initialize(priv->buffer_pool, bufpoolsize);
    574 	if (ret != MIX_RESULT_SUCCESS) {
    575 		LOG_E("Failed to initialize buffer pool\n");
    576 		goto cleanup;
    577 	}
    578 
    579 	/* Finally, we can create MixVideoFormat */
    580 	/* What type of MixVideoFormat we need create? */
    581 
    582 	if (g_strcmp0(mime_type, "video/x-wmv") == 0
    583 			&& MIX_IS_VIDEOCONFIGPARAMSDEC_VC1(priv_config_params_dec)) {
    584 
    585 		MixVideoFormat_VC1 *video_format = mix_videoformat_vc1_new();
    586 		if (!video_format) {
    587 			ret = MIX_RESULT_NO_MEMORY;
    588 			LOG_E("Failed to create VC-1 video format\n");
    589 			goto cleanup;
    590 		}
    591 
    592 		/* TODO: work specific to VC-1 */
    593 
    594 		priv->video_format = MIX_VIDEOFORMAT(video_format);
    595 
    596 	} else if (g_strcmp0(mime_type, "video/x-h264") == 0
    597 			&& MIX_IS_VIDEOCONFIGPARAMSDEC_H264(priv_config_params_dec)) {
    598 
    599 		MixVideoFormat_H264 *video_format = mix_videoformat_h264_new();
    600 		if (!video_format) {
    601 			ret = MIX_RESULT_NO_MEMORY;
    602 			LOG_E("Failed to create H.264 video format\n");
    603 			goto cleanup;
    604 		}
    605 
    606 		/* TODO: work specific to H.264 */
    607 
    608 		priv->video_format = MIX_VIDEOFORMAT(video_format);
    609 
    610 	} else if (g_strcmp0(mime_type, "video/mpeg") == 0 || g_strcmp0(mime_type,
    611 			"video/x-divx") == 0) {
    612 
    613 		guint version = 0;
    614 
    615 		/* Is this mpeg4:2 ? */
    616 		if (g_strcmp0(mime_type, "video/mpeg") == 0) {
    617 
    618 			/*
    619 			 *  we don't support mpeg other than mpeg verion 4
    620 			 */
    621 			if (!MIX_IS_VIDEOCONFIGPARAMSDEC_MP42(priv_config_params_dec)) {
    622 				ret = MIX_RESULT_NOT_SUPPORTED;
    623 				goto cleanup;
    624 			}
    625 
    626 			/* what is the mpeg version ? */
    627 			ret = mix_videoconfigparamsdec_mp42_get_mpegversion(
    628 					MIX_VIDEOCONFIGPARAMSDEC_MP42(priv_config_params_dec), &version);
    629 			if (ret != MIX_RESULT_SUCCESS) {
    630 				LOG_E("Failed to get mpeg version\n");
    631 				goto cleanup;
    632 			}
    633 
    634 			/* if it is not MPEG4 */
    635 			if (version != 4) {
    636 				ret = MIX_RESULT_NOT_SUPPORTED;
    637 				goto cleanup;
    638 			}
    639 
    640 		} else {
    641 
    642 			/* config_param shall be MixVideoConfigParamsDecMP42 */
    643 			if (!MIX_IS_VIDEOCONFIGPARAMSDEC_MP42(priv_config_params_dec)) {
    644 				ret = MIX_RESULT_NOT_SUPPORTED;
    645 				goto cleanup;
    646 			}
    647 
    648 			/* what is the divx version ? */
    649 			ret = mix_videoconfigparamsdec_mp42_get_divxversion(
    650 					MIX_VIDEOCONFIGPARAMSDEC_MP42(priv_config_params_dec), &version);
    651 			if (ret != MIX_RESULT_SUCCESS) {
    652 				LOG_E("Failed to get divx version\n");
    653 				goto cleanup;
    654 			}
    655 
    656 			/* if it is not divx 4 or 5 */
    657 			if (version != 4 && version != 5) {
    658 				ret = MIX_RESULT_NOT_SUPPORTED;
    659 				goto cleanup;
    660 			}
    661 		}
    662 
    663 		MixVideoFormat_MP42 *video_format = mix_videoformat_mp42_new();
    664 		if (!video_format) {
    665 			ret = MIX_RESULT_NO_MEMORY;
    666 			LOG_E("Failed to create MPEG-4:2 video format\n");
    667 			goto cleanup;
    668 		}
    669 
    670 		/* TODO: work specific to MPEG-4:2 */
    671 		priv->video_format = MIX_VIDEOFORMAT(video_format);
    672 
    673 	} else {
    674 
    675 		/* Oops! A format we don't know */
    676 
    677 		ret = MIX_RESULT_FAIL;
    678 		LOG_E("Unknown format, we can't handle it\n");
    679 		goto cleanup;
    680 	}
    681 
    682 	/* initialize MixVideoFormat */
    683 	ret = mix_videofmt_initialize(priv->video_format, priv_config_params_dec,
    684 			priv->frame_manager, priv->buffer_pool, &priv->surface_pool,
    685 			priv->va_display);
    686 
    687 	if (ret != MIX_RESULT_SUCCESS) {
    688 		LOG_E("Failed initialize video format\n");
    689 		goto cleanup;
    690 	}
    691 
    692 	mix_surfacepool_ref(priv->surface_pool);
    693 
    694 	/* decide MixVideoFormat from mime_type*/
    695 
    696 	priv->configured = TRUE;
    697 	ret = MIX_RESULT_SUCCESS;
    698 
    699 	cleanup:
    700 
    701 	if (ret != MIX_RESULT_SUCCESS) {
    702 		MIXUNREF(priv->config_params, mix_videoconfigparams_unref);
    703 		MIXUNREF(priv->frame_manager, mix_framemanager_unref);
    704 		MIXUNREF(priv->buffer_pool, mix_bufferpool_unref);
    705 		MIXUNREF(priv->video_format, mix_videoformat_unref);
    706 	}
    707 
    708 	if (mime_type) {
    709 		g_free(mime_type);
    710 	}
    711 
    712 	g_mutex_unlock(priv->objlock);
    713 	/* ---------------------- end lock --------------------- */
    714 
    715 	LOG_V( "End\n");
    716 
    717 	return ret;
    718 }
    719 
    720 MIX_RESULT mix_video_configure_encode(MixVideo * mix,
    721 		MixVideoConfigParamsEnc * config_params_enc,
    722 		MixDrmParams * drm_config_params) {
    723 
    724 	MIX_RESULT ret = MIX_RESULT_FAIL;
    725 	MixVideoPrivate *priv = NULL;
    726 	MixVideoConfigParamsEnc *priv_config_params_enc = NULL;
    727 
    728 
    729 	gchar *mime_type = NULL;
    730 	MixEncodeTargetFormat encode_format = MIX_ENCODE_TARGET_FORMAT_H264;
    731 	guint bufpoolsize = 0;
    732 
    733 	MixFrameOrderMode frame_order_mode = MIX_FRAMEORDER_MODE_DECODEORDER;
    734 
    735 
    736 	LOG_V( "Begin\n");
    737 
    738 	CHECK_INIT(mix, priv);
    739 
    740 	if (!config_params_enc) {
    741 		LOG_E("!config_params_enc\n");
    742 		return MIX_RESULT_NULL_PTR;
    743 	}
    744 	if (!MIX_IS_VIDEOCONFIGPARAMSENC(config_params_enc)) {
    745 		LOG_E("Not a MixVideoConfigParams\n");
    746 		return MIX_RESULT_INVALID_PARAM;
    747 	}
    748 
    749 	/* ---------------------- begin lock --------------------- */
    750 	g_mutex_lock(priv->objlock);
    751 
    752 	/*
    753 	 * MixVideo has already been configured, it should be
    754 	 * re-configured.
    755 	 *
    756 	 * TODO: Allow MixVideo re-configuration
    757 	 */
    758 	if (priv->configured) {
    759 		ret = MIX_RESULT_SUCCESS;
    760 		LOG_E( "Already configured\n");
    761 		goto cleanup;
    762 	}
    763 
    764 	/* Make a copy of config_params */
    765 	priv->config_params = (MixVideoConfigParams *) mix_params_dup(
    766 			MIX_PARAMS(config_params_enc));
    767 	if (!priv->config_params) {
    768 		ret = MIX_RESULT_NO_MEMORY;
    769 		LOG_E("Fail to duplicate config_params\n");
    770 		goto cleanup;
    771 	}
    772 
    773 	priv_config_params_enc = (MixVideoConfigParamsEnc *)priv->config_params;
    774 
    775 	/* Get fps, frame order mode and mime type from config_params */
    776 	ret = mix_videoconfigparamsenc_get_mime_type(priv_config_params_enc,
    777 			&mime_type);
    778 	if (ret != MIX_RESULT_SUCCESS) {
    779 		LOG_E("Failed to get mime type\n");
    780 		goto cleanup;
    781 	}
    782 
    783 	LOG_I( "mime : %s\n", mime_type);
    784 
    785 	ret = mix_videoconfigparamsenc_get_encode_format(priv_config_params_enc,
    786 			&encode_format);
    787 	if (ret != MIX_RESULT_SUCCESS) {
    788 		LOG_E("Failed to get target format\n");
    789 		goto cleanup;
    790 	}
    791 
    792 	LOG_I( "encode_format : %d\n",
    793 			encode_format);
    794 
    795 	ret = mix_videoconfigparamsenc_get_buffer_pool_size(
    796 			priv_config_params_enc, &bufpoolsize);
    797 	if (ret != MIX_RESULT_SUCCESS) {
    798 		LOG_E("Failed to get buffer pool size\n");
    799 		goto cleanup;
    800 	}
    801 
    802 	/* create frame manager */
    803 	priv->frame_manager = mix_framemanager_new();
    804 	if (!priv->frame_manager) {
    805 		ret = MIX_RESULT_NO_MEMORY;
    806 		LOG_E("Failed to create frame manager\n");
    807 		goto cleanup;
    808 	}
    809 
    810 	/* initialize frame manager */
    811 	/* frame rate can be any value for encoding. */
    812 	ret = mix_framemanager_initialize(priv->frame_manager, frame_order_mode,
    813 			1, 1, FALSE);
    814 
    815 	if (ret != MIX_RESULT_SUCCESS) {
    816 		LOG_E("Failed to initialize frame manager\n");
    817 		goto cleanup;
    818 	}
    819 
    820 	/* create buffer pool */
    821 	priv->buffer_pool = mix_bufferpool_new();
    822 	if (!priv->buffer_pool) {
    823 		ret = MIX_RESULT_NO_MEMORY;
    824 		LOG_E("Failed to create buffer pool\n");
    825 		goto cleanup;
    826 	}
    827 
    828 	ret = mix_bufferpool_initialize(priv->buffer_pool, bufpoolsize);
    829 	if (ret != MIX_RESULT_SUCCESS) {
    830 		LOG_E("Failed to initialize buffer pool\n");
    831 		goto cleanup;
    832 	}
    833 
    834 	/* Finally, we can create MixVideoFormatEnc */
    835 	/* What type of MixVideoFormatEnc we need create? */
    836 
    837 	if (encode_format == MIX_ENCODE_TARGET_FORMAT_H264
    838 			&& MIX_IS_VIDEOCONFIGPARAMSENC_H264(priv_config_params_enc)) {
    839 
    840 		MixVideoFormatEnc_H264 *video_format_enc =
    841 				mix_videoformatenc_h264_new();
    842 		if (!video_format_enc) {
    843 			ret = MIX_RESULT_NO_MEMORY;
    844 			LOG_E("mix_video_configure_encode: Failed to create h264 video enc format\n");
    845 			goto cleanup;
    846 		}
    847 
    848 		/* TODO: work specific to h264 encode */
    849 
    850 		priv->video_format_enc = MIX_VIDEOFORMATENC(video_format_enc);
    851 
    852 	}
    853     else if (encode_format == MIX_ENCODE_TARGET_FORMAT_MPEG4
    854             && MIX_IS_VIDEOCONFIGPARAMSENC_MPEG4(priv_config_params_enc)) {
    855 
    856         MixVideoFormatEnc_MPEG4 *video_format_enc = mix_videoformatenc_mpeg4_new();
    857         if (!video_format_enc) {
    858             ret = MIX_RESULT_NO_MEMORY;
    859             LOG_E("mix_video_configure_encode: Failed to create mpeg-4:2 video format\n");
    860             goto cleanup;
    861         }
    862 
    863 		/* TODO: work specific to mpeg4 */
    864 
    865 		priv->video_format_enc = MIX_VIDEOFORMATENC(video_format_enc);
    866 
    867 	}
    868     else if (encode_format == MIX_ENCODE_TARGET_FORMAT_PREVIEW
    869             && MIX_IS_VIDEOCONFIGPARAMSENC_PREVIEW(priv_config_params_enc)) {
    870 
    871         MixVideoFormatEnc_Preview *video_format_enc = mix_videoformatenc_preview_new();
    872         if (!video_format_enc) {
    873             ret = MIX_RESULT_NO_MEMORY;
    874             LOG_E( "mix_video_configure_encode: Failed to create preview video format\n");
    875             goto cleanup;
    876         }
    877 
    878 		priv->video_format_enc = MIX_VIDEOFORMATENC(video_format_enc);
    879 
    880 	}
    881 	else {
    882 
    883 		/*unsupported format */
    884 		ret = MIX_RESULT_NOT_SUPPORTED;
    885 		LOG_E("Unknown format, we can't handle it\n");
    886 		goto cleanup;
    887 	}
    888 
    889 	/* initialize MixVideoEncFormat */
    890 	ret = mix_videofmtenc_initialize(priv->video_format_enc,
    891             priv_config_params_enc, priv->frame_manager, NULL, &priv->surface_pool,
    892             priv->va_display);
    893 
    894 	if (ret != MIX_RESULT_SUCCESS) {
    895 		LOG_E("Failed initialize video format\n");
    896 		goto cleanup;
    897 	}
    898 
    899 	mix_surfacepool_ref(priv->surface_pool);
    900 
    901 	priv->configured = TRUE;
    902 	ret = MIX_RESULT_SUCCESS;
    903 
    904 	cleanup:
    905 
    906 	if (ret != MIX_RESULT_SUCCESS) {
    907 		MIXUNREF(priv->frame_manager, mix_framemanager_unref);
    908 		MIXUNREF(priv->config_params, mix_videoconfigparams_unref);
    909 		MIXUNREF(priv->buffer_pool, mix_bufferpool_unref);
    910 		MIXUNREF(priv->video_format_enc, mix_videoformatenc_unref);
    911 	}
    912 
    913 	if (mime_type) {
    914 		g_free(mime_type);
    915 	}
    916 
    917 	g_mutex_unlock(priv->objlock);
    918 	/* ---------------------- end lock --------------------- */
    919 
    920 	LOG_V( "End\n");
    921 
    922 	return ret;
    923 }
    924 
    925 MIX_RESULT mix_video_configure_default(MixVideo * mix,
    926 		MixVideoConfigParams * config_params,
    927 		MixDrmParams * drm_config_params) {
    928 
    929 	MIX_RESULT ret = MIX_RESULT_FAIL;
    930 	MixVideoPrivate *priv = NULL;
    931 
    932 	LOG_V( "Begin\n");
    933 
    934 	CHECK_INIT(mix, priv);
    935 	if(!config_params) {
    936 		LOG_E("!config_params\n");
    937 		return MIX_RESULT_NULL_PTR;
    938 	}
    939 
    940 	/*Decoder mode or Encoder mode*/
    941 	if (priv->codec_mode == MIX_CODEC_MODE_DECODE && MIX_IS_VIDEOCONFIGPARAMSDEC(config_params)) {
    942 		ret = mix_video_configure_decode(mix, (MixVideoConfigParamsDec*)config_params, NULL);
    943 	} else if (priv->codec_mode == MIX_CODEC_MODE_ENCODE && MIX_IS_VIDEOCONFIGPARAMSENC(config_params)) {
    944 		ret = mix_video_configure_encode(mix, (MixVideoConfigParamsEnc*)config_params, NULL);
    945 	} else {
    946 		LOG_E("Codec mode not supported\n");
    947 	}
    948 
    949 	LOG_V( "end\n");
    950 
    951 	return ret;
    952 }
    953 
    954 MIX_RESULT mix_video_get_config_default(MixVideo * mix,
    955 		MixVideoConfigParams ** config_params) {
    956 
    957 	MIX_RESULT ret = MIX_RESULT_FAIL;
    958 	MixVideoPrivate *priv = NULL;
    959 
    960 	CHECK_INIT_CONFIG(mix, priv);
    961 
    962 	if (!config_params) {
    963 		LOG_E( "!config_params\n");
    964 		return MIX_RESULT_NULL_PTR;
    965 	}
    966 
    967 	/* ---------------------- begin lock --------------------- */
    968 	g_mutex_lock(priv->objlock);
    969 
    970 	*config_params = MIX_VIDEOCONFIGPARAMS(mix_params_dup(MIX_PARAMS(priv->config_params)));
    971 	if(!*config_params) {
    972 		ret = MIX_RESULT_NO_MEMORY;
    973 		LOG_E("Failed to duplicate MixVideoConfigParams\n");
    974 		goto cleanup;
    975 	}
    976 
    977 	cleanup:
    978 
    979 	/* ---------------------- end lock --------------------- */
    980 	g_mutex_unlock(priv->objlock);
    981 
    982 	LOG_V( "End\n");
    983 
    984 	return ret;
    985 
    986 }
    987 
    988 MIX_RESULT mix_video_decode_default(MixVideo * mix, MixBuffer * bufin[],
    989 		gint bufincnt, MixVideoDecodeParams * decode_params) {
    990 
    991 	MIX_RESULT ret = MIX_RESULT_FAIL;
    992 	MixVideoPrivate *priv = NULL;
    993 
    994 	LOG_V( "Begin\n");
    995 
    996 	CHECK_INIT_CONFIG(mix, priv);
    997 	if(!bufin || !bufincnt || !decode_params) {
    998 		LOG_E( "!bufin || !bufincnt || !decode_params\n");
    999 		return MIX_RESULT_NULL_PTR;
   1000 	}
   1001 
   1002 	//First check that we have surfaces available for decode
   1003 	ret = mix_surfacepool_check_available(priv->surface_pool);
   1004 
   1005 	if (ret == MIX_RESULT_POOLEMPTY) {
   1006 		LOG_I( "Out of surface\n");
   1007 		return MIX_RESULT_OUTOFSURFACES;
   1008 	}
   1009 
   1010 	g_mutex_lock(priv->objlock);
   1011 
   1012 	ret = mix_videofmt_decode(priv->video_format, bufin, bufincnt, decode_params);
   1013 
   1014 	g_mutex_unlock(priv->objlock);
   1015 
   1016 	LOG_V( "End\n");
   1017 
   1018 	return ret;
   1019 }
   1020 
   1021 MIX_RESULT mix_video_get_frame_default(MixVideo * mix, MixVideoFrame ** frame) {
   1022 
   1023 	LOG_V( "Begin\n");
   1024 
   1025 	MIX_RESULT ret = MIX_RESULT_FAIL;
   1026 	MixVideoPrivate *priv = NULL;
   1027 
   1028 	CHECK_INIT_CONFIG(mix, priv);
   1029 
   1030 	if (!frame) {
   1031 		LOG_E( "!frame\n");
   1032 		return MIX_RESULT_NULL_PTR;
   1033 	}
   1034 
   1035 	/* ---------------------- begin lock --------------------- */
   1036 	g_mutex_lock(priv->objlock);
   1037 
   1038 	LOG_V("Calling frame manager dequeue\n");
   1039 
   1040 	ret = mix_framemanager_dequeue(priv->frame_manager, frame);
   1041 
   1042 	/* ---------------------- end lock --------------------- */
   1043 	g_mutex_unlock(priv->objlock);
   1044 
   1045 	LOG_V( "End\n");
   1046 
   1047 	return ret;
   1048 }
   1049 
   1050 MIX_RESULT mix_video_release_frame_default(MixVideo * mix,
   1051 		MixVideoFrame * frame) {
   1052 
   1053 	LOG_V( "Begin\n");
   1054 
   1055 	MIX_RESULT ret = MIX_RESULT_FAIL;
   1056 	MixVideoPrivate *priv = NULL;
   1057 
   1058 	CHECK_INIT_CONFIG(mix, priv);
   1059 
   1060 	if (!frame) {
   1061 		LOG_E( "!frame\n");
   1062 		return MIX_RESULT_NULL_PTR;
   1063 	}
   1064 
   1065 	/*
   1066 	 * We don't need lock here. MixVideoFrame has lock to
   1067 	 * protect itself.
   1068 	 */
   1069 #if 0
   1070 	/* ---------------------- begin lock --------------------- */
   1071 	g_mutex_lock(priv->objlock);
   1072 #endif
   1073 
   1074 	LOG_I("Releasing reference frame %x\n", (guint) frame);
   1075 	mix_videoframe_unref(frame);
   1076 
   1077 	ret = MIX_RESULT_SUCCESS;
   1078 
   1079 #if 0
   1080 	/* ---------------------- end lock --------------------- */
   1081 	g_mutex_unlock(priv->objlock);
   1082 #endif
   1083 
   1084 	LOG_V( "End\n");
   1085 
   1086 	return ret;
   1087 
   1088 }
   1089 
   1090 MIX_RESULT mix_video_render_default(MixVideo * mix,
   1091 		MixVideoRenderParams * render_params, MixVideoFrame *frame) {
   1092 
   1093 	LOG_V( "Begin\n");
   1094 
   1095 	MIX_RESULT ret = MIX_RESULT_FAIL;
   1096 	MixVideoPrivate *priv = NULL;
   1097 
   1098 	MixDisplay *mix_display = NULL;
   1099 	MixDisplayX11 *mix_display_x11 = NULL;
   1100 
   1101 	Display *display = NULL;
   1102 	Drawable drawable = 0;
   1103 
   1104 	MixRect src_rect, dst_rect;
   1105 
   1106 	VARectangle *va_cliprects = NULL;
   1107 	guint number_of_cliprects = 0;
   1108 
   1109 	/* VASurfaceID va_surface_id; */
   1110 	gulong va_surface_id;
   1111 	VAStatus va_status;
   1112 
   1113 	CHECK_INIT_CONFIG(mix, priv);
   1114 
   1115 	if (!render_params || !frame) {
   1116 		LOG_E( "!render_params || !frame\n");
   1117 		return MIX_RESULT_NULL_PTR;
   1118 	}
   1119 
   1120 	/* Is this render param valid? */
   1121 	if (!MIX_IS_VIDEORENDERPARAMS(render_params)) {
   1122 		LOG_E("Not MixVideoRenderParams\n");
   1123 		return MIX_RESULT_INVALID_PARAM;
   1124 	}
   1125 
   1126 	/*
   1127 	 * We don't need lock here. priv->va_display may be the only variable
   1128 	 * seems need to be protected. But, priv->va_display is initialized
   1129 	 * when mixvideo object is initialized, and it keeps
   1130 	 * the same value thoughout the life of mixvideo.
   1131 	 */
   1132 #if 0
   1133 	/* ---------------------- begin lock --------------------- */
   1134 	g_mutex_lock(priv->objlock);
   1135 #endif
   1136 
   1137 	/* get MixDisplay prop from render param */
   1138 	ret = mix_videorenderparams_get_display(render_params, &mix_display);
   1139 	if (ret != MIX_RESULT_SUCCESS) {
   1140 		LOG_E("Failed to get mix_display\n");
   1141 		goto cleanup;
   1142 	}
   1143 
   1144 	/* Is this MixDisplayX11 ? */
   1145 	/* TODO: we shall also support MixDisplay other than MixDisplayX11 */
   1146 	if (!MIX_IS_DISPLAYX11(mix_display)) {
   1147 		ret = MIX_RESULT_INVALID_PARAM;
   1148 		LOG_E( "Not MixDisplayX11\n");
   1149 		goto cleanup;
   1150 	}
   1151 
   1152 	/* cast MixDisplay to MixDisplayX11 */
   1153 	mix_display_x11 = MIX_DISPLAYX11(mix_display);
   1154 
   1155 	/* Get Drawable */
   1156 	ret = mix_displayx11_get_drawable(mix_display_x11, &drawable);
   1157 	if (ret != MIX_RESULT_SUCCESS) {
   1158 		LOG_E( "Failed to get drawable\n");
   1159 		goto cleanup;
   1160 	}
   1161 
   1162 	/* Get Display */
   1163 	ret = mix_displayx11_get_display(mix_display_x11, &display);
   1164 	if (ret != MIX_RESULT_SUCCESS) {
   1165 		LOG_E( "Failed to get display\n");
   1166 		goto cleanup;
   1167 	}
   1168 
   1169 	/* get src_rect */
   1170 	ret = mix_videorenderparams_get_src_rect(render_params, &src_rect);
   1171 	if (ret != MIX_RESULT_SUCCESS) {
   1172 		LOG_E("Failed to get SOURCE src_rect\n");
   1173 		goto cleanup;
   1174 	}
   1175 
   1176 	/* get dst_rect */
   1177 	ret = mix_videorenderparams_get_dest_rect(render_params, &dst_rect);
   1178 	if (ret != MIX_RESULT_SUCCESS) {
   1179 		LOG_E( "Failed to get dst_rect\n");
   1180 		goto cleanup;
   1181 	}
   1182 
   1183 	/* get va_cliprects */
   1184 	ret = mix_videorenderparams_get_cliprects_internal(render_params,
   1185 			&va_cliprects, &number_of_cliprects);
   1186 	if (ret != MIX_RESULT_SUCCESS) {
   1187 		LOG_E("Failed to get va_cliprects\n");
   1188 		goto cleanup;
   1189 	}
   1190 
   1191 	/* get surface id from frame */
   1192 	ret = mix_videoframe_get_frame_id(frame, &va_surface_id);
   1193 	if (ret != MIX_RESULT_SUCCESS) {
   1194 		LOG_E("Failed to get va_surface_id\n");
   1195 		goto cleanup;
   1196 	}
   1197 	guint64 timestamp = 0;
   1198 	mix_videoframe_get_timestamp(frame, &timestamp);
   1199 	LOG_V( "Displaying surface ID %d, timestamp %"G_GINT64_FORMAT"\n", (int)va_surface_id, timestamp);
   1200 
   1201 	guint32 frame_structure = 0;
   1202 	mix_videoframe_get_frame_structure(frame, &frame_structure);
   1203 	/* TODO: the last param of vaPutSurface is de-interlacing flags,
   1204 	 what is value shall be*/
   1205 	va_status = vaPutSurface(priv->va_display, (VASurfaceID) va_surface_id,
   1206 			drawable, src_rect.x, src_rect.y, src_rect.width, src_rect.height,
   1207 			dst_rect.x, dst_rect.y, dst_rect.width, dst_rect.height,
   1208 			va_cliprects, number_of_cliprects, frame_structure);
   1209 
   1210 	if (va_status != VA_STATUS_SUCCESS) {
   1211 		ret = MIX_RESULT_FAIL;
   1212 		LOG_E("Failed vaPutSurface() : va_status = %d\n", va_status);
   1213 		goto cleanup;
   1214 	}
   1215 
   1216 	/* TODO: Is this only for X11? */
   1217 	XSync(display, FALSE);
   1218 
   1219 	ret = MIX_RESULT_SUCCESS;
   1220 
   1221 	cleanup:
   1222 
   1223 	MIXUNREF(mix_display, mix_display_unref)
   1224 	/*	MIXUNREF(render_params, mix_videorenderparams_unref)*/
   1225 
   1226 #if 0
   1227 	/* ---------------------- end lock --------------------- */
   1228 	g_mutex_unlock(priv->objlock);
   1229 #endif
   1230 
   1231 	LOG_V( "End\n");
   1232 
   1233 	return ret;
   1234 
   1235 }
   1236 
   1237 MIX_RESULT mix_video_encode_default(MixVideo * mix, MixBuffer * bufin[],
   1238 		gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
   1239 		MixVideoEncodeParams * encode_params) {
   1240 
   1241 	MIX_RESULT ret = MIX_RESULT_FAIL;
   1242 	MixVideoPrivate *priv = NULL;
   1243 
   1244 	LOG_V( "Begin\n");
   1245 
   1246 	CHECK_INIT_CONFIG(mix, priv);
   1247 	if(!bufin || !bufincnt) { //we won't check encode_params here, it's just a placeholder
   1248 		LOG_E( "!bufin || !bufincnt\n");
   1249 		return MIX_RESULT_NULL_PTR;
   1250 	}
   1251 
   1252 	g_mutex_lock(priv->objlock);
   1253 
   1254 	ret = mix_videofmtenc_encode(priv->video_format_enc, bufin, bufincnt,
   1255 			iovout, iovoutcnt, encode_params);
   1256 
   1257 	g_mutex_unlock(priv->objlock);
   1258 
   1259 	LOG_V( "End\n");
   1260 	return ret;
   1261 }
   1262 
   1263 MIX_RESULT mix_video_flush_default(MixVideo * mix) {
   1264 
   1265 	MIX_RESULT ret = MIX_RESULT_FAIL;
   1266 	MixVideoPrivate *priv = NULL;
   1267 
   1268 	LOG_V( "Begin\n");
   1269 
   1270 	CHECK_INIT_CONFIG(mix, priv);
   1271 
   1272 	/* ---------------------- begin lock --------------------- */
   1273 	g_mutex_lock(priv->objlock);
   1274 
   1275 	if (priv->codec_mode == MIX_CODEC_MODE_DECODE && priv->video_format != NULL) {
   1276 		ret = mix_videofmt_flush(priv->video_format);
   1277 
   1278 		ret = mix_framemanager_flush(priv->frame_manager);
   1279 	} else if (priv->codec_mode == MIX_CODEC_MODE_ENCODE
   1280 			&& priv->video_format_enc != NULL) {
   1281 		/*No framemanager for encoder now*/
   1282 		ret = mix_videofmtenc_flush(priv->video_format_enc);
   1283 	} else {
   1284 		g_mutex_unlock(priv->objlock);
   1285 		LOG_E("Invalid video_format/video_format_enc Pointer\n");
   1286 		return MIX_RESULT_NULL_PTR;
   1287 	}
   1288 
   1289 	/* ---------------------- end lock --------------------- */
   1290 	g_mutex_unlock(priv->objlock);
   1291 
   1292 	LOG_V( "End\n");
   1293 
   1294 	return ret;
   1295 
   1296 }
   1297 
   1298 MIX_RESULT mix_video_eos_default(MixVideo * mix) {
   1299 
   1300 	MIX_RESULT ret = MIX_RESULT_FAIL;
   1301 	MixVideoPrivate *priv = NULL;
   1302 
   1303 	LOG_V( "Begin\n");
   1304 
   1305 	CHECK_INIT_CONFIG(mix, priv);
   1306 
   1307 	/* ---------------------- begin lock --------------------- */
   1308 	g_mutex_lock(priv->objlock);
   1309 
   1310 	if (priv->codec_mode == MIX_CODEC_MODE_DECODE && priv->video_format != NULL) {
   1311 		ret = mix_videofmt_eos(priv->video_format);
   1312 
   1313 		/* frame manager will set EOS flag to be TRUE */
   1314 		ret = mix_framemanager_eos(priv->frame_manager);
   1315 	} else if (priv->codec_mode == MIX_CODEC_MODE_ENCODE
   1316 			&& priv->video_format_enc != NULL) {
   1317 		/*No framemanager now*/
   1318 		ret = mix_videofmtenc_eos(priv->video_format_enc);
   1319 	} else {
   1320 		g_mutex_unlock(priv->objlock);
   1321 		LOG_E("Invalid video_format/video_format_enc Pointer\n");
   1322 		return MIX_RESULT_NULL_PTR;
   1323 	}
   1324 
   1325 	/* ---------------------- end lock --------------------- */
   1326 	g_mutex_unlock(priv->objlock);
   1327 
   1328 	LOG_V( "End\n");
   1329 
   1330 	return ret;
   1331 }
   1332 
   1333 MIX_RESULT mix_video_get_state_default(MixVideo * mix, MixState * state) {
   1334 
   1335 	MixVideoPrivate *priv = NULL;
   1336 
   1337 	LOG_V( "Begin\n");
   1338 
   1339 	CHECK_INIT_CONFIG(mix, priv);
   1340 
   1341 	if (!state) {
   1342 		LOG_E( "!state\n");
   1343 		return MIX_RESULT_NULL_PTR;
   1344 	}
   1345 
   1346 	*state = MIX_STATE_CONFIGURED;
   1347 
   1348 	LOG_V( "End\n");
   1349 
   1350 	return MIX_RESULT_SUCCESS;
   1351 }
   1352 
   1353 MIX_RESULT mix_video_get_mixbuffer_default(MixVideo * mix, MixBuffer ** buf) {
   1354 
   1355 	MIX_RESULT ret = MIX_RESULT_FAIL;
   1356 	MixVideoPrivate *priv = NULL;
   1357 
   1358 	LOG_V( "Begin\n");
   1359 
   1360 	CHECK_INIT_CONFIG(mix, priv);
   1361 
   1362 	if (!buf) {
   1363 		LOG_E( "!buf\n");
   1364 		return MIX_RESULT_INVALID_PARAM;
   1365 	}
   1366 
   1367 	/* ---------------------- begin lock --------------------- */
   1368 	g_mutex_lock(priv->objlock);
   1369 
   1370 	ret = mix_bufferpool_get(priv->buffer_pool, buf);
   1371 
   1372 	/* ---------------------- end lock --------------------- */
   1373 	g_mutex_unlock(priv->objlock);
   1374 
   1375 	LOG_V( "End ret = 0x%x\n", ret);
   1376 
   1377 	return ret;
   1378 
   1379 }
   1380 
   1381 MIX_RESULT mix_video_release_mixbuffer_default(MixVideo * mix, MixBuffer * buf) {
   1382 
   1383 	MIX_RESULT ret = MIX_RESULT_FAIL;
   1384 	MixVideoPrivate *priv = NULL;
   1385 
   1386 	LOG_V( "Begin\n");
   1387 
   1388 	CHECK_INIT_CONFIG(mix, priv);
   1389 
   1390 	if (!buf) {
   1391 		LOG_E( "!buf\n");
   1392 		return MIX_RESULT_INVALID_PARAM;
   1393 	}
   1394 
   1395 	/* ---------------------- begin lock --------------------- */
   1396 	g_mutex_lock(priv->objlock);
   1397 
   1398 	mix_buffer_unref(buf);
   1399 
   1400 	/* ---------------------- end lock --------------------- */
   1401 	g_mutex_unlock(priv->objlock);
   1402 
   1403 	LOG_V( "End\n");
   1404 	return ret;
   1405 
   1406 }
   1407 
   1408 MIX_RESULT mix_video_get_max_coded_buffer_size_default (MixVideo * mix, guint *max_size)
   1409 {
   1410       MIX_RESULT ret = MIX_RESULT_FAIL;
   1411 	MixVideoPrivate *priv = NULL;
   1412 
   1413 	LOG_V( "Begin\n");
   1414 
   1415 	if (!mix || !max_size) /* TODO: add other parameter NULL checking */
   1416 	{
   1417 		LOG_E( "!mix || !bufsize\n");
   1418 		return MIX_RESULT_NULL_PTR;
   1419 	}
   1420 
   1421 	CHECK_INIT_CONFIG(mix, priv);
   1422 
   1423 	g_mutex_lock(priv->objlock);
   1424 
   1425 	ret = mix_videofmtenc_get_max_coded_buffer_size(priv->video_format_enc, max_size);
   1426 
   1427 	g_mutex_unlock(priv->objlock);
   1428 
   1429 	LOG_V( "End\n");
   1430 	return ret;
   1431 }
   1432 
   1433 /*
   1434  * API functions
   1435  */
   1436 
   1437 #define CHECK_AND_GET_MIX_CLASS(mix, klass) \
   1438 	if (!mix) { \
   1439 		return MIX_RESULT_NULL_PTR; \
   1440 	} \
   1441 	if (!MIX_IS_VIDEO(mix)) { \
   1442 		LOG_E( "Not MixVideo\n"); \
   1443 		return MIX_RESULT_INVALID_PARAM; \
   1444 	} \
   1445 	klass = MIX_VIDEO_GET_CLASS(mix);
   1446 
   1447 
   1448 MIX_RESULT mix_video_get_version(MixVideo * mix, guint * major, guint * minor) {
   1449 
   1450 	MixVideoClass *klass = NULL;
   1451 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1452 
   1453 	if (klass->get_version_func) {
   1454 		return klass->get_version_func(mix, major, minor);
   1455 	}
   1456 	return MIX_RESULT_NOTIMPL;
   1457 
   1458 }
   1459 
   1460 MIX_RESULT mix_video_initialize(MixVideo * mix, MixCodecMode mode,
   1461 		MixVideoInitParams * init_params, MixDrmParams * drm_init_params) {
   1462 
   1463 	MixVideoClass *klass = NULL;
   1464 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1465 
   1466 	if (klass->initialize_func) {
   1467 		return klass->initialize_func(mix, mode, init_params, drm_init_params);
   1468 	}
   1469 	return MIX_RESULT_NOTIMPL;
   1470 
   1471 }
   1472 
   1473 MIX_RESULT mix_video_deinitialize(MixVideo * mix) {
   1474 
   1475 	MixVideoClass *klass = NULL;
   1476 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1477 
   1478 	if (klass->deinitialize_func) {
   1479 		return klass->deinitialize_func(mix);
   1480 	}
   1481 	return MIX_RESULT_NOTIMPL;
   1482 }
   1483 
   1484 MIX_RESULT mix_video_configure(MixVideo * mix,
   1485 		MixVideoConfigParams * config_params,
   1486 		MixDrmParams * drm_config_params) {
   1487 
   1488 	MixVideoClass *klass = NULL;
   1489 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1490 
   1491 	if (klass->configure_func) {
   1492 		return klass->configure_func(mix, config_params, drm_config_params);
   1493 	}
   1494 	return MIX_RESULT_NOTIMPL;
   1495 }
   1496 
   1497 MIX_RESULT mix_video_get_config(MixVideo * mix,
   1498 		MixVideoConfigParams ** config_params_dec) {
   1499 
   1500 	MixVideoClass *klass = NULL;
   1501 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1502 
   1503 	if (klass->get_config_func) {
   1504 		return klass->get_config_func(mix, config_params_dec);
   1505 	}
   1506 	return MIX_RESULT_NOTIMPL;
   1507 
   1508 }
   1509 
   1510 MIX_RESULT mix_video_decode(MixVideo * mix, MixBuffer * bufin[], gint bufincnt,
   1511 		MixVideoDecodeParams * decode_params) {
   1512 
   1513 	MixVideoClass *klass = NULL;
   1514 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1515 
   1516 	if (klass->decode_func) {
   1517 		return klass->decode_func(mix, bufin, bufincnt,
   1518 				decode_params);
   1519 	}
   1520 	return MIX_RESULT_NOTIMPL;
   1521 
   1522 }
   1523 
   1524 MIX_RESULT mix_video_get_frame(MixVideo * mix, MixVideoFrame ** frame) {
   1525 
   1526 	MixVideoClass *klass = NULL;
   1527 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1528 
   1529 	if (klass->get_frame_func) {
   1530 		return klass->get_frame_func(mix, frame);
   1531 	}
   1532 	return MIX_RESULT_NOTIMPL;
   1533 
   1534 }
   1535 
   1536 MIX_RESULT mix_video_release_frame(MixVideo * mix, MixVideoFrame * frame) {
   1537 
   1538 	MixVideoClass *klass = NULL;
   1539 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1540 
   1541 	if (klass->release_frame_func) {
   1542 		return klass->release_frame_func(mix, frame);
   1543 	}
   1544 	return MIX_RESULT_NOTIMPL;
   1545 }
   1546 
   1547 MIX_RESULT mix_video_render(MixVideo * mix,
   1548 		MixVideoRenderParams * render_params, MixVideoFrame *frame) {
   1549 
   1550 	MixVideoClass *klass = NULL;
   1551 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1552 
   1553 	if (klass->render_func) {
   1554 		return klass->render_func(mix, render_params, frame);
   1555 	}
   1556 	return MIX_RESULT_NOTIMPL;
   1557 
   1558 }
   1559 
   1560 MIX_RESULT mix_video_encode(MixVideo * mix, MixBuffer * bufin[], gint bufincnt,
   1561 		MixIOVec * iovout[], gint iovoutcnt,
   1562 		MixVideoEncodeParams * encode_params) {
   1563 
   1564 	MixVideoClass *klass = NULL;
   1565 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1566 
   1567 	if (klass->encode_func) {
   1568 		return klass->encode_func(mix, bufin, bufincnt, iovout, iovoutcnt,
   1569 				encode_params);
   1570 	}
   1571 	return MIX_RESULT_NOTIMPL;
   1572 
   1573 }
   1574 
   1575 MIX_RESULT mix_video_flush(MixVideo * mix) {
   1576 
   1577 	MixVideoClass *klass = NULL;
   1578 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1579 
   1580 	if (klass->flush_func) {
   1581 		return klass->flush_func(mix);
   1582 	}
   1583 	return MIX_RESULT_NOTIMPL;
   1584 }
   1585 
   1586 MIX_RESULT mix_video_eos(MixVideo * mix) {
   1587 
   1588 	MixVideoClass *klass = NULL;
   1589 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1590 
   1591 	if (klass->eos_func) {
   1592 		return klass->eos_func(mix);
   1593 	}
   1594 	return MIX_RESULT_NOTIMPL;
   1595 }
   1596 
   1597 MIX_RESULT mix_video_get_state(MixVideo * mix, MixState * state) {
   1598 
   1599 	MixVideoClass *klass = NULL;
   1600 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1601 
   1602 	if (klass->get_state_func) {
   1603 		return klass->get_state_func(mix, state);
   1604 	}
   1605 	return MIX_RESULT_NOTIMPL;
   1606 }
   1607 
   1608 MIX_RESULT mix_video_get_mixbuffer(MixVideo * mix, MixBuffer ** buf) {
   1609 
   1610 	MixVideoClass *klass = NULL;
   1611 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1612 
   1613 	if (klass->get_mix_buffer_func) {
   1614 		return klass->get_mix_buffer_func(mix, buf);
   1615 	}
   1616 	return MIX_RESULT_NOTIMPL;
   1617 }
   1618 
   1619 MIX_RESULT mix_video_release_mixbuffer(MixVideo * mix, MixBuffer * buf) {
   1620 
   1621 	MixVideoClass *klass = NULL;
   1622 	CHECK_AND_GET_MIX_CLASS(mix, klass);
   1623 
   1624 	if (klass->release_mix_buffer_func) {
   1625 		return klass->release_mix_buffer_func(mix, buf);
   1626 	}
   1627 	return MIX_RESULT_NOTIMPL;
   1628 }
   1629 
   1630 MIX_RESULT mix_video_get_max_coded_buffer_size(MixVideo * mix, guint *bufsize) {
   1631 
   1632 	MixVideoClass *klass = MIX_VIDEO_GET_CLASS(mix);
   1633 
   1634 	if (klass->get_max_coded_buffer_size_func) {
   1635 		return klass->get_max_coded_buffer_size_func(mix, bufsize);
   1636 	}
   1637 	return MIX_RESULT_NOTIMPL;
   1638 }
   1639