Merge of 0427 GAID fixes and improve HW Decode for H.264 (overlay)

Change-Id: I5f4c77c123200e11d10468142a3b929778a434db
diff --git a/mix_vbp/viddec_fw/fw/codecs/h264/parser/Android.mk b/mix_vbp/viddec_fw/fw/codecs/h264/parser/Android.mk
index 37dfdcf..b7c15d6 100644
--- a/mix_vbp/viddec_fw/fw/codecs/h264/parser/Android.mk
+++ b/mix_vbp/viddec_fw/fw/codecs/h264/parser/Android.mk
@@ -17,24 +17,19 @@
 
 LOCAL_CFLAGS := -DVBP -DHOST_ONLY
 
-LOCAL_C_INCLUDES :=			\
-	$(GLIB_TOP)			\
-	$(GLIB_TOP)/android		\
-	$(GLIB_TOP)/glib		\
-	$(GLIB_TOP)/gobject		\
+LOCAL_C_INCLUDES :=							   \
+	$(GLIB_TOP)							   \
+	$(GLIB_TOP)/android						   \
+	$(GLIB_TOP)/glib						   \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/include		   \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/include		   \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/parser/include	   \
-	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/h264/include \
-	$(TARGET_OUT_HEADERS)/libmixcommon
+	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/h264/include
 
 LOCAL_MODULE := libmixvbp_h264
 
 LOCAL_SHARED_LIBRARIES :=		\
 	libglib-2.0			\
-	libgobject-2.0			\
-	libgthread-2.0			\
-	libgmodule-2.0			\
 	libmixvbp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/mix_vbp/viddec_fw/fw/codecs/mp4/parser/Android.mk b/mix_vbp/viddec_fw/fw/codecs/mp4/parser/Android.mk
index c539d61..23c0c52 100644
--- a/mix_vbp/viddec_fw/fw/codecs/mp4/parser/Android.mk
+++ b/mix_vbp/viddec_fw/fw/codecs/mp4/parser/Android.mk
@@ -14,24 +14,19 @@
 
 LOCAL_CFLAGS := -DVBP -DHOST_ONLY
 
-LOCAL_C_INCLUDES :=			\
-	$(GLIB_TOP)			\
-	$(GLIB_TOP)/android		\
-	$(GLIB_TOP)/glib		\
-	$(GLIB_TOP)/gobject		\
+LOCAL_C_INCLUDES :=							   \
+	$(GLIB_TOP)							   \
+	$(GLIB_TOP)/android						   \
+	$(GLIB_TOP)/glib						   \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/include		   \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/include		   \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/parser/include	   \
-	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/mp4/include \
-	$(TARGET_OUT_HEADERS)/libmixcommon
+	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/mp4/include
 
 LOCAL_MODULE := libmixvbp_mpeg4
 
 LOCAL_SHARED_LIBRARIES :=		\
 	libglib-2.0			\
-	libgobject-2.0			\
-	libgthread-2.0			\
-	libgmodule-2.0			\
 	libmixvbp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/mix_vbp/viddec_fw/fw/parser/Android.mk b/mix_vbp/viddec_fw/fw/parser/Android.mk
index 797c640..cc9ba5a 100644
--- a/mix_vbp/viddec_fw/fw/parser/Android.mk
+++ b/mix_vbp/viddec_fw/fw/parser/Android.mk
@@ -26,7 +26,6 @@
 	$(GLIB_TOP)			\
 	$(GLIB_TOP)/glib		\
 	$(GLIB_TOP)/android		\
-	$(GLIB_TOP)/gobject		\
 	$(LOCAL_PATH)/include		\
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/include		   \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/include		   \
@@ -35,7 +34,6 @@
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/mp4/include  \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/vc1/include  \
 	$(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/vc1/parser   \
-	$(TARGET_OUT_HEADERS)/libmixcommon				   \
 	$(TARGET_OUT_HEADERS)/libva
 
 LOCAL_COPY_HEADERS_TO := libmixvbp
@@ -48,10 +46,7 @@
 LOCAL_SHARED_LIBRARIES :=		\
 	libdl				\
 	libcutils			\
-	libglib-2.0			\
-	libgobject-2.0			\
-	libgthread-2.0			\
-	libgmodule-2.0
+	libglib-2.0
 
 ifeq ($(strip $(MIXVBP_LOG_ENABLE)),true)
 LOCAL_CFLAGS += -DVBP_TRACE
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c b/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
index e82d7b5..8695ef7 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
@@ -1440,13 +1440,14 @@
   	while (size_left >= NAL_length_size)
   	{
     	NAL_length = vbp_get_NAL_length_h264(cubby->buf + size_parsed);    	
-    	  
-        size_parsed += NAL_length_size;
+
+    	size_parsed += NAL_length_size;
 #else
 	while (size_left > 0)
 	{
-		NAL_length = size_left;
+	NAL_length = size_left;
 #endif
+    	  
     	cxt->list.data[cxt->list.num_items].stpos = size_parsed;
     	size_parsed += NAL_length; /* skip NAL bytes */
     	/* end position is exclusive */
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_trace.h b/mix_vbp/viddec_fw/fw/parser/vbp_trace.h
index c532b67..9f2a21c 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_trace.h
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_trace.h
@@ -17,25 +17,6 @@
 
 #ifdef VBP_TRACE /* if VBP_TRACE is defined*/
 
-#ifdef ANDROID
-
-#include <utils/Log.h>
-
-#define ETRACE(format, ...) \
-    __android_log_print(ANDROID_LOG_ERROR, "mixvbp", "%s():%d: "format, \
-                        __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define WTRACE(format, ...) \
-    __android_log_print(ANDROID_LOG_WARN, "mixvbp", "%s():%d: "format, \
-                        __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define ITRACE(format, ...) \
-    __android_log_print(ANDROID_LOG_INFO, "mixvbp", "%s():%d: "format, \
-                        __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define VTRACE(format, ...) \
-    __android_log_print(ANDROID_LOG_VERBOSE, "mixvbp", "%s():%d: "format, \
-                        __FUNCTION__, __LINE__, ##__VA_ARGS__)
-
-#else
-
 #include <stdio.h>
 #include <stdarg.h>
 
@@ -50,8 +31,6 @@
 #define ITRACE(format, ...) VBP_TRACE_UTIL("INFO:    ",  format, ##__VA_ARGS__)
 #define VTRACE(format, ...) VBP_TRACE_UTIL("VERBOSE: ",  format, ##__VA_ARGS__)
 
-#endif /* ANDROID */
-
 #else /* if VBP_TRACE is not defined */
 
 #define ETRACE(format, ...)
@@ -59,6 +38,7 @@
 #define ITRACE(format, ...)
 #define VTRACE(format, ...)
 
+
 #endif /* VBP_TRACE*/
 
 
diff --git a/mix_video/configure.ac b/mix_video/configure.ac
index 8605a92..6baf0ed 100644
--- a/mix_video/configure.ac
+++ b/mix_video/configure.ac
@@ -2,7 +2,7 @@
 
 AC_CONFIG_MACRO_DIR(m4)
 
-AS_MIX_VERSION(mixvideo, MIXVIDEO, 0, 1, 14)
+AS_MIX_VERSION(mixvideo, MIXVIDEO, 0, 1, 15)
 
 dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode
 AM_MAINTAINER_MODE
diff --git a/mix_video/mixvideo.spec b/mix_video/mixvideo.spec
index 7be66bb..8e5efb4 100644
--- a/mix_video/mixvideo.spec
+++ b/mix_video/mixvideo.spec
@@ -6,7 +6,7 @@
 
 Summary: MIX Video
 Name: mixvideo
-Version: 0.1.14
+Version: 0.1.15
 Release: 1
 Source0: %{name}-%{version}.tar.gz
 NoSource: 0
diff --git a/mix_video/src/mixdisplayx11.c b/mix_video/src/mixdisplayx11.c
index 467bde2..7398234 100644
--- a/mix_video/src/mixdisplayx11.c
+++ b/mix_video/src/mixdisplayx11.c
@@ -20,14 +20,14 @@
 static GType _mix_displayx11_type = 0;
 static MixDisplayClass *parent_class = NULL;
 
-#define _do_init { _mix_displayx11_type = g_define_type_id; }
-
 #ifdef ANDROID
 int XSync(Display* display, Bool bvalue) {
     return 0;
 }
 #endif
 
+#define _do_init { _mix_displayx11_type = g_define_type_id; }
+
 gboolean mix_displayx11_copy(MixDisplay * target, const MixDisplay * src);
 MixDisplay *mix_displayx11_dup(const MixDisplay * obj);
 gboolean mix_displayx11_equal(MixDisplay * first, MixDisplay * second);
diff --git a/mix_video/src/mixsurfacepool.c b/mix_video/src/mixsurfacepool.c
index f7672c8..0c778af 100644
--- a/mix_video/src/mixsurfacepool.c
+++ b/mix_video/src/mixsurfacepool.c
@@ -221,7 +221,7 @@
  * frame objects that represents a pool of surfaces.
  */
 MIX_RESULT mix_surfacepool_initialize(MixSurfacePool * obj,
-		VASurfaceID *surfaces, guint num_surfaces) {
+		VASurfaceID *surfaces, guint num_surfaces, VADisplay va_display) {
 
 	LOG_V( "Begin\n");
 
@@ -287,6 +287,8 @@
 		// Set the pool reference in the private data of the frame object
 		mix_videoframe_set_pool(frame, obj);
 
+		mix_videoframe_set_vadisplay(frame, va_display);
+
 		//Add each frame object to the pool list
 		obj->free_list = g_slist_append(obj->free_list, frame);
 
diff --git a/mix_video/src/mixsurfacepool.h b/mix_video/src/mixsurfacepool.h
index 6468ebe..d475792 100644
--- a/mix_video/src/mixsurfacepool.h
+++ b/mix_video/src/mixsurfacepool.h
@@ -139,7 +139,7 @@
 /* Class Methods */
 
 MIX_RESULT mix_surfacepool_initialize (MixSurfacePool * obj, 
-				VASurfaceID *surfaces, guint num_surfaces);
+				VASurfaceID *surfaces, guint num_surfaces, VADisplay va_display);
 MIX_RESULT mix_surfacepool_put (MixSurfacePool * obj,
 				MixVideoFrame * frame);
 
diff --git a/mix_video/src/mixvideo.c b/mix_video/src/mixvideo.c
index ef74184..ffd72d5 100644
--- a/mix_video/src/mixvideo.c
+++ b/mix_video/src/mixvideo.c
@@ -12,6 +12,8 @@
 #endif
 #include <va/va_x11.h>
 
+#include <string.h>
+
 #include "mixvideolog.h"
 
 #include "mixdisplayx11.h"
@@ -104,7 +106,6 @@
 MIX_RESULT mix_video_get_decoded_data_default(MixVideo * mix, MixIOVec * iovout,
 		MixVideoRenderParams * render_params, MixVideoFrame *frame);
 
-
 MIX_RESULT mix_video_encode_default(MixVideo * mix, MixBuffer * bufin[],
 		gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
 		MixVideoEncodeParams * encode_params);
@@ -165,7 +166,7 @@
 	klass->get_frame_func = mix_video_get_frame_default;
 	klass->release_frame_func = mix_video_release_frame_default;
 	klass->render_func = mix_video_render_default;
-        klass->get_decoded_data_func = mix_video_get_decoded_data_default;
+	klass->get_decoded_data_func = mix_video_get_decoded_data_default;
 	klass->encode_func = mix_video_encode_default;
 	klass->flush_func = mix_video_flush_default;
 	klass->eos_func = mix_video_eos_default;
@@ -377,12 +378,10 @@
 
 		if (MIX_IS_DISPLAYX11(mix_display)) {
 			MixDisplayX11 *mix_displayx11 = MIX_DISPLAYX11(mix_display);
-#if 1
-			mix_displayx11->display = g_malloc(sizeof(Display));
-			*(mix_displayx11->display) = 0x18c34078;
-#else
-			//mix_displayx11->display = 1;
-#endif
+
+                        /* XXX NOTE: This must be fixed in all clients */
+                        mix_displayx11->display = 0x18c34078;
+
 			ret = mix_displayx11_get_display(mix_displayx11, &display);
 			if (ret != MIX_RESULT_SUCCESS) {
 				LOG_E("Failed to get display 2\n");
@@ -1123,6 +1122,8 @@
 	gulong va_surface_id;
 	VAStatus va_status;
 
+	gboolean sync_flag = FALSE;
+
 	CHECK_INIT_CONFIG(mix, priv);
 
 	if (!render_params || !frame) {
@@ -1213,6 +1214,29 @@
 
 	guint32 frame_structure = 0;
 	mix_videoframe_get_frame_structure(frame, &frame_structure);
+
+	ret = mix_videoframe_get_sync_flag(frame, &sync_flag);
+	if (ret != MIX_RESULT_SUCCESS) {
+		LOG_E("Failed to get sync_flag\n");
+		goto cleanup;
+	}
+
+	if (!sync_flag) {
+		ret = mix_videoframe_set_sync_flag(frame, TRUE);
+		if (ret != MIX_RESULT_SUCCESS) {
+			LOG_E("Failed to set sync_flag\n");
+			goto cleanup;
+		}
+
+		va_status = vaSyncSurface(priv->va_display, va_surface_id);
+		if (va_status != VA_STATUS_SUCCESS) {
+			ret = MIX_RESULT_FAIL;
+			LOG_E("Failed vaSyncSurface() : va_status = 0x%x\n", va_status);
+			goto cleanup;
+		}
+	}
+
+
 	/* TODO: the last param of vaPutSurface is de-interlacing flags,
 	 what is value shall be*/
 	va_status = vaPutSurface(priv->va_display, (VASurfaceID) va_surface_id,
@@ -1222,13 +1246,10 @@
 
 	if (va_status != VA_STATUS_SUCCESS) {
 		ret = MIX_RESULT_FAIL;
-		LOG_E("Failed vaPutSurface() : va_status = %d\n", va_status);
+		LOG_E("Failed vaPutSurface() : va_status = 0x%x\n", va_status);
 		goto cleanup;
 	}
 
-	/* TODO: Is this only for X11? */
-	XSync(display, FALSE);
-
 	ret = MIX_RESULT_SUCCESS;
 
 	cleanup:
@@ -1411,7 +1432,6 @@
 	return MIX_RESULT_NOTIMPL;
 }
 
-
 MIX_RESULT mix_video_encode_default(MixVideo * mix, MixBuffer * bufin[],
 		gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
 		MixVideoEncodeParams * encode_params) {
diff --git a/mix_video/src/mixvideo.h b/mix_video/src/mixvideo.h
index 73c6b71..91e9011 100644
--- a/mix_video/src/mixvideo.h
+++ b/mix_video/src/mixvideo.h
@@ -69,7 +69,6 @@
                 MixIOVec * iovout, MixVideoRenderParams * render_params,
                 MixVideoFrame *frame);
 
-
 typedef MIX_RESULT (*MixVideoEncodeFunc)(MixVideo * mix, MixBuffer * bufin[],
 		gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
 		MixVideoEncodeParams * encode_params);
diff --git a/mix_video/src/mixvideoformat.c b/mix_video/src/mixvideoformat.c
index fa601cb..f446651 100644
--- a/mix_video/src/mixvideoformat.c
+++ b/mix_video/src/mixvideoformat.c
@@ -117,20 +117,20 @@
 	if (mix->va_display) {
 		if (mix->va_context != VA_INVALID_ID)
 		{
-			va_status = vaDestroyConfig(mix->va_display, mix->va_config);
-			if (va_status != VA_STATUS_SUCCESS) {
-			LOG_W( "Failed vaDestroyConfig\n");
-			} 
-			mix->va_config = VA_INVALID_ID;
-		}
-		if (mix->va_context != VA_INVALID_ID)
-		{
 			va_status = vaDestroyContext(mix->va_display, mix->va_context);
 			if (va_status != VA_STATUS_SUCCESS) {
 				LOG_W( "Failed vaDestroyContext\n");
 			}
 			mix->va_context = VA_INVALID_ID;
 		}
+		if (mix->va_config != VA_INVALID_ID)
+		{
+			va_status = vaDestroyConfig(mix->va_display, mix->va_config);
+			if (va_status != VA_STATUS_SUCCESS) {
+			LOG_W( "Failed vaDestroyConfig\n");
+			} 
+			mix->va_config = VA_INVALID_ID;
+		}
 		if (mix->va_surfaces)
 		{
 			va_status = vaDestroySurfaces(mix->va_display, mix->va_surfaces, mix->va_num_surfaces);
diff --git a/mix_video/src/mixvideoformat_h264.c b/mix_video/src/mixvideoformat_h264.c
index 9e81cbf..1f57019 100644
--- a/mix_video/src/mixvideoformat_h264.c
+++ b/mix_video/src/mixvideoformat_h264.c
@@ -493,7 +493,7 @@
 	
 
 	ret = mix_surfacepool_initialize(parent->surfacepool,
-		surfaces, numSurfaces);
+		surfaces, numSurfaces, vadisplay);
 
 	switch (ret)
 	{
@@ -932,7 +932,7 @@
 }
 #define HACK_DPB
 #ifdef HACK_DPB
-static inline void mix_videofmt_h264_hack_dpb(MixVideoFormat *mix, 
+static inline MIX_RESULT mix_videofmt_h264_hack_dpb(MixVideoFormat *mix, 
 					vbp_picture_data_h264* pic_data
 					) 
 {
@@ -942,6 +942,7 @@
 	VAPictureParameterBufferH264 *pic_params = pic_data->pic_parms;
 	VAPictureH264 *pRefList = NULL;
 	int i = 0, j = 0, k = 0, list = 0;
+	MIX_RESULT ret = MIX_RESULT_FAIL;
 
 	MixVideoFormat_H264 *self = MIX_VIDEOFORMAT_H264(mix);
 
@@ -989,6 +990,9 @@
 				{
 					guint poc = mix_videofmt_h264_get_poc(&(pRefList[j]));
 					gpointer video_frame = g_hash_table_lookup(self->dpb_surface_table, (gpointer)poc);
+
+					if (!video_frame) return MIX_RESULT_DROPFRAME; //return non-fatal error
+
 					pic_params->ReferenceFrames[pic_params->num_ref_frames].picture_id = 
 						((MixVideoFrame *)video_frame)->frame_id;
 
@@ -1009,6 +1013,7 @@
 		}
 
 	}
+	return MIX_RESULT_SUCCESS;
 }
 #endif
 
@@ -1127,7 +1132,12 @@
 
 #ifdef HACK_DPB
 	//We have to provide a hacked DPB rather than complete DPB for libva as workaround
-	mix_videofmt_h264_hack_dpb(mix, pic_data);
+	ret = mix_videofmt_h264_hack_dpb(mix, pic_data);
+	if (ret != MIX_RESULT_SUCCESS)
+	{
+		LOG_E( "Error reference frame not found\n");
+		goto cleanup;
+	}
 #endif
 
 	//Libva buffer set up
@@ -1196,7 +1206,7 @@
 				if (video_frame == NULL)
 				{
 					LOG_E(  "unable to find surface of picture %d (current picture %d).", poc, mix_videofmt_h264_get_poc(&pic_params->CurrPic));
-					ret = MIX_RESULT_FAIL;
+					ret = MIX_RESULT_DROPFRAME;  //return non-fatal error
 					goto cleanup;
 				}
 				else
@@ -1219,7 +1229,7 @@
 					if (video_frame == NULL)
 					{
 						LOG_E(  "unable to find surface of picture %d (current picture %d).", poc, mix_videofmt_h264_get_poc(&pic_params->CurrPic));
-						ret = MIX_RESULT_FAIL;
+						ret = MIX_RESULT_DROPFRAME;  //return non-fatal error
 						goto cleanup;
 					}
 					else
@@ -1330,6 +1340,8 @@
 		goto cleanup;
 	}
 
+#if 0	/* we don't call vaSyncSurface here, the call is moved to mix_video_render() */
+
 	LOG_V( "Calling vaSyncSurface\n");
 
 	//Decode the picture
@@ -1341,7 +1353,7 @@
 		LOG_E( "Video driver returned error from vaSyncSurface\n");
 		goto cleanup;
 	}
-
+#endif
 
 	if (pic_index == 0)
 	{
diff --git a/mix_video/src/mixvideoformat_mp42.c b/mix_video/src/mixvideoformat_mp42.c
index 3aae249..c6c7b30 100644
--- a/mix_video/src/mixvideoformat_mp42.c
+++ b/mix_video/src/mixvideoformat_mp42.c
@@ -347,7 +347,7 @@
 	*surface_pool = parent->surfacepool;
 
 	ret = mix_surfacepool_initialize(parent->surfacepool, surfaces,
-			numSurfaces);
+			numSurfaces, va_display);
 
 	/* Initialize and save the VA context ID
 	 * Note: VA_PROGRESSIVE libva flag is only relevant to MPEG2
@@ -665,7 +665,7 @@
 		 */
 
 		if (!g_queue_is_empty(self->packed_stream_queue)) {
-			ret = MIX_RESULT_FAIL;
+			ret = MIX_RESULT_DROPFRAME;
 			LOG_E("The previous packed frame is not fully processed yet!\n");
 			goto cleanup;
 		}
@@ -679,19 +679,19 @@
 			/* Is the first frame in the packed frames a reference frame? */
 			if (idx == 0 && frame_type != MP4_VOP_TYPE_I && frame_type
 					!= MP4_VOP_TYPE_P) {
-				ret = MIX_RESULT_FAIL;
+				ret = MIX_RESULT_DROPFRAME;;
 				LOG_E("The first frame in packed frame is not I or B\n");
 				goto cleanup;
 			}
 
 			if (idx != 0 && frame_type != MP4_VOP_TYPE_B) {
-				ret = MIX_RESULT_FAIL;
+				ret = MIX_RESULT_DROPFRAME;;
 				LOG_E("The frame other than the first one in packed frame is not B\n");
 				goto cleanup;
 			}
 
 			if (picture_data->vop_coded == 0) {
-				ret = MIX_RESULT_FAIL;
+				ret = MIX_RESULT_DROPFRAME;
 				LOG_E("In packed frame, there's unexpected skipped frame\n");
 				goto cleanup;
 			}
@@ -769,7 +769,7 @@
 				frame_type = picture_param->vop_fields.bits.vop_coding_type;
 
 				if (frame_type == MP4_VOP_TYPE_B) {
-					ret = MIX_RESULT_FAIL;
+					ret = MIX_RESULT_DROPFRAME;
 					LOG_E("The frame right after packed frame is B frame!\n");
 					goto cleanup;
 				}
@@ -1055,6 +1055,7 @@
 		goto cleanup;
 	}
 
+#if 0   /* we don't call vaSyncSurface here, the call is moved to mix_video_render() */
 	LOG_V("Calling vaSyncSurface\n");
 
 	/* Decode the picture */
@@ -1064,6 +1065,7 @@
 		LOG_E("Failed to vaSyncSurface(): va_ret = 0x%x\n", va_ret);
 		goto cleanup;
 	}
+#endif 
 
 	/* Set the discontinuity flag */
 	mix_videoframe_set_discontinuity(frame, discontinuity);
diff --git a/mix_video/src/mixvideoformat_vc1.c b/mix_video/src/mixvideoformat_vc1.c
index ec09985..0702c85 100644
--- a/mix_video/src/mixvideoformat_vc1.c
+++ b/mix_video/src/mixvideoformat_vc1.c
@@ -546,7 +546,7 @@
 	
 
         ret = mix_surfacepool_initialize(parent->surfacepool,
-                surfaces, numSurfaces);
+                surfaces, numSurfaces, vadisplay);
 
         switch (ret)
         {
@@ -995,7 +995,7 @@
 				ret = mix_videoframe_set_frame_type(frame, frame_type);
 				break;
 			case VC1_PTYPE_BI: // BI frame type
-				ret = mix_videoframe_set_frame_type(frame, TYPE_I);
+				ret = mix_videoframe_set_frame_type(frame, TYPE_B);
 				break;
 	//Not indicated here	case VC1_PTYPE_SKIPPED:  
 			default:
@@ -1035,7 +1035,7 @@
 				could have been overwritten and hence not avaiable for reference.
 				*/
 				LOG_E( "reference distance is not 0!");
-				ret = MIX_RESULT_FAIL;
+				ret = MIX_RESULT_DROPFRAME;
 				goto cleanup;				
 			}
 			if (1 == pic_index)
@@ -1070,14 +1070,19 @@
 				}
 				else
 				{
-					ret = MIX_RESULT_FAIL;
+					ret = MIX_RESULT_DROPFRAME;
 					LOG_E( "Error could not find reference frames for P frame\n");
 					goto cleanup;
 				}
 			}
 			pic_params->backward_reference_picture = VA_INVALID_SURFACE;
 
-			LOG_V( "P frame, surface ID %u, forw ref frame is %u\n", (guint)frame->frame_id, (guint)self->reference_frames[0]->frame_id);
+#ifdef MIX_LOG_ENABLE	/* this is to fix a crash when MIX_LOG_ENABLE is set */
+			if(self->reference_frames[0] && frame) {
+				LOG_V( "P frame, surface ID %u, forw ref frame is %u\n",
+						(guint)frame->frame_id, (guint)self->reference_frames[0]->frame_id);
+			}
+#endif
 			LOG_V( "mix_video vinfo:  Frame type is P\n");
 			break;
 
@@ -1087,7 +1092,7 @@
 			if (!self->haveBframes)	//We don't expect B frames and have not allocated a surface 
 						// for the extra ref frame so this is an error
 			{
-				ret = MIX_RESULT_FAIL;
+				ret = MIX_RESULT_DROPFRAME;
 				LOG_E( "Unexpected B frame, cannot process\n");
 				goto cleanup;
 			}
@@ -1099,7 +1104,7 @@
 			LOG_V( "mix_video vinfo:  Frame type is B\n");
 			break;
 
-		case VC1_PTYPE_BI: 
+		case VC1_PTYPE_BI:
 			pic_params->forward_reference_picture = VA_INVALID_SURFACE;
 			pic_params->backward_reference_picture = VA_INVALID_SURFACE;
 			LOG_V( "BI frame\n");
@@ -1274,6 +1279,7 @@
 		goto cleanup;
 	}
 
+#if 0   /* we don't call vaSyncSurface here, the call is moved to mix_video_render() */
 	LOG_V( "Calling vaSyncSurface\n");
 
 	//Decode the picture
@@ -1285,6 +1291,7 @@
 		LOG_E( "Video driver returned error from vaSyncSurface\n");
 		goto cleanup;
 	}
+#endif
 
 cleanup:
 	if (NULL != buffer_ids)
diff --git a/mix_video/src/mixvideoformatenc_h264.c b/mix_video/src/mixvideoformatenc_h264.c
index 8472e93..bf25304 100644
--- a/mix_video/src/mixvideoformatenc_h264.c
+++ b/mix_video/src/mixvideoformatenc_h264.c
@@ -44,14 +44,15 @@
     self->encoded_frames = 0;
     self->pic_skipped = FALSE;
     self->is_intra = TRUE;
-    self->cur_fame = NULL;
-    self->ref_fame = NULL;
-    self->rec_fame = NULL;	
+    self->cur_frame = NULL;
+    self->ref_frame = NULL;
+    self->rec_frame = NULL;	
 
     self->ci_shared_surfaces = NULL;
     self->surfaces= NULL;
     self->surface_num = 0;
 
+    self->coded_buf_index = 0;
     parent->initialized = FALSE;
 }
 
@@ -585,7 +586,7 @@
                 "mix_surfacepool_initialize\n");			
         
         ret = mix_surfacepool_initialize(parent->surfacepool,
-                self->surfaces, parent->ci_frame_num + numSurfaces);
+                self->surfaces, parent->ci_frame_num + numSurfaces, va_display);
         
         switch (ret)
         {
@@ -641,7 +642,23 @@
                 VAEncCodedBufferType,
                 self->coded_buf_size,  //
                 1, NULL,
-                &self->coded_buf);
+                &(self->coded_buf[0]));
+        
+        if (va_status != VA_STATUS_SUCCESS)	 
+        {
+            LOG_E( 
+                    "Failed to vaCreateBuffer: VAEncCodedBufferType\n");	
+            g_free (surfaces);			
+            g_mutex_unlock(parent->objectlock);
+            return MIX_RESULT_FAIL;
+        }
+
+        /*Create coded buffer for output*/
+        va_status = vaCreateBuffer (va_display, parent->va_context,
+                VAEncCodedBufferType,
+                self->coded_buf_size,  //
+                1, NULL,
+                &(self->coded_buf[1]));
         
         if (va_status != VA_STATUS_SUCCESS)	 
         {
@@ -793,25 +810,25 @@
 
 #if 0    
     /*unref the current source surface*/ 
-    if (self->cur_fame != NULL)
+    if (self->cur_frame != NULL)
     {
-        mix_videoframe_unref (self->cur_fame);
-        self->cur_fame = NULL;
+        mix_videoframe_unref (self->cur_frame);
+        self->cur_frame = NULL;
     }
 #endif		
     
     /*unref the reconstructed surface*/ 
-    if (self->rec_fame != NULL)
+    if (self->rec_frame != NULL)
     {
-        mix_videoframe_unref (self->rec_fame);
-        self->rec_fame = NULL;
+        mix_videoframe_unref (self->rec_frame);
+        self->rec_frame = NULL;
     }
 
     /*unref the reference surface*/ 
-    if (self->ref_fame != NULL)
+    if (self->ref_frame != NULL)
     {
-        mix_videoframe_unref (self->ref_fame);
-        self->ref_fame = NULL;       
+        mix_videoframe_unref (self->ref_frame);
+        self->ref_frame = NULL;       
     }
     
     /*reset the properities*/    
@@ -868,25 +885,25 @@
 
 #if 0
     /*unref the current source surface*/ 
-    if (self->cur_fame != NULL)
+    if (self->cur_frame != NULL)
     {
-        mix_videoframe_unref (self->cur_fame);
-        self->cur_fame = NULL;
+        mix_videoframe_unref (self->cur_frame);
+        self->cur_frame = NULL;
     }
 #endif	
     
     /*unref the reconstructed surface*/ 
-    if (self->rec_fame != NULL)
+    if (self->rec_frame != NULL)
     {
-        mix_videoframe_unref (self->rec_fame);
-        self->rec_fame = NULL;
+        mix_videoframe_unref (self->rec_frame);
+        self->rec_frame = NULL;
     }
 
     /*unref the reference surface*/ 
-    if (self->ref_fame != NULL)
+    if (self->ref_frame != NULL)
     {
-        mix_videoframe_unref (self->ref_fame);
-        self->ref_fame = NULL;       
+        mix_videoframe_unref (self->ref_frame);
+        self->ref_frame = NULL;       
     }	
 
     LOG_V( "Release surfaces\n");			
@@ -1045,20 +1062,15 @@
         return MIX_RESULT_NULL_PTR;
     
     LOG_V( "Begin\n\n");		
-    
-#if 0 //not needed currently
-    MixVideoConfigParamsEncH264 * params_h264
-        = MIX_VIDEOCONFIGPARAMSENC_H264 (config_params_enc);
-#endif	
-    
+
     if (MIX_IS_VIDEOFORMATENC_H264(mix)) {
         
         parent = MIX_VIDEOFORMATENC(&(mix->parent));
         
         /*set picture params for HW*/
-        h264_pic_param.reference_picture = mix->ref_fame->frame_id;  
-        h264_pic_param.reconstructed_picture = mix->rec_fame->frame_id;
-        h264_pic_param.coded_buf = mix->coded_buf;
+        h264_pic_param.reference_picture = mix->ref_frame->frame_id;  
+        h264_pic_param.reconstructed_picture = mix->rec_frame->frame_id;
+        h264_pic_param.coded_buf = mix->coded_buf[mix->coded_buf_index];
         h264_pic_param.picture_width = parent->picture_width;
         h264_pic_param.picture_height = parent->picture_height;
         h264_pic_param.last_picture = 0;	
@@ -1070,8 +1082,10 @@
                 h264_pic_param.reference_picture);	
         LOG_I( "reconstructed_picture = 0x%08x\n", 
                 h264_pic_param.reconstructed_picture);	
+        LOG_I( "coded_buf_index = %d\n", 
+                mix->coded_buf_index);	
         LOG_I( "coded_buf = 0x%08x\n", 
-                h264_pic_param.coded_buf);	
+                h264_pic_param.coded_buf);
         LOG_I( "picture_width = %d\n", 
                 h264_pic_param.picture_width);	
         LOG_I( "picture_height = %d\n\n", 
@@ -1107,7 +1121,7 @@
                 "not H264 video encode Object\n");						
         return MIX_RESULT_FAIL;		
     }		
-    
+	
     LOG_V( "end\n");		
     return MIX_RESULT_SUCCESS;  
     
@@ -1270,7 +1284,7 @@
     gulong surface = 0;
     guint16 width, height;
     
-    MixVideoFrame *  tmp_fame;
+    MixVideoFrame *  tmp_frame;
     guint8 *buf;
     
     if ((mix == NULL) || (bufin == NULL) || (iovout == NULL)) {
@@ -1320,9 +1334,9 @@
             LOG_V( 
                     "We are NOT in share buffer mode\n");		
             
-            if (mix->ref_fame == NULL)
+            if (mix->ref_frame == NULL)
             {
-                ret = mix_surfacepool_get(parent->surfacepool, &mix->ref_fame);
+                ret = mix_surfacepool_get(parent->surfacepool, &mix->ref_frame);
                 if (ret != MIX_RESULT_SUCCESS)  //#ifdef SLEEP_SURFACE not used
                 {
                     LOG_E( 
@@ -1331,9 +1345,9 @@
                 }
             }
             
-            if (mix->rec_fame == NULL)	
+            if (mix->rec_frame == NULL)	
             {
-                ret = mix_surfacepool_get(parent->surfacepool, &mix->rec_fame);
+                ret = mix_surfacepool_get(parent->surfacepool, &mix->rec_frame);
                 if (ret != MIX_RESULT_SUCCESS)
                 {
                     LOG_E( 
@@ -1343,12 +1357,12 @@
             }
 
             if (parent->need_display) {
-                mix->cur_fame = NULL;				
+                mix->cur_frame = NULL;				
             }
             
-            if (mix->cur_fame == NULL)
+            if (mix->cur_frame == NULL)
             {
-                ret = mix_surfacepool_get(parent->surfacepool, &mix->cur_fame);
+                ret = mix_surfacepool_get(parent->surfacepool, &mix->cur_frame);
                 if (ret != MIX_RESULT_SUCCESS)
                 {
                     LOG_E( 
@@ -1369,7 +1383,7 @@
             LOG_V( 
                     "map source data to surface\n");	
             
-            ret = mix_videoframe_get_frame_id(mix->cur_fame, &surface);
+            ret = mix_videoframe_get_frame_id(mix->cur_frame, &surface);
             if (ret != MIX_RESULT_SUCCESS)
             {
                 LOG_E( 
@@ -1425,6 +1439,12 @@
             
             guint8 *inbuf = bufin->data;      
             
+/* mutually exclusive */
+//#define USE_SRC_FMT_YUV420
+//#define USE_SRC_FMT_NV12
+#define USE_SRC_FMT_NV21
+
+#ifdef USE_SRC_FMT_YUV420
             /*need to convert YUV420 to NV12*/
             dst_y = pvbuf +image->offsets[0];
             
@@ -1443,6 +1463,36 @@
                 }
                 dst_uv += image->pitches[1];
             }
+#else //USE_SRC_FMT_NV12 or USE_SRC_FMT_NV21
+            int offset_uv = width * height;
+            guint8 *inbuf_uv = inbuf + offset_uv;
+            int height_uv = height / 2;
+            int width_uv = width;
+
+            dst_y = pvbuf + image->offsets[0];
+            for (i = 0; i < height; i++) {
+                memcpy (dst_y, inbuf + i * width, width);
+                dst_y += image->pitches[0];
+            }
+
+#ifdef USE_SRC_FMT_NV12
+            dst_uv = pvbuf + image->offsets[1];
+            for (i = 0; i < height_uv; i++) {
+                memcpy(dst_uv, inbuf_uv + i * width_uv, width_uv);
+                dst_uv += image->pitches[1];
+            }
+#else //USE_SRC_FMT_NV21
+            dst_uv = pvbuf + image->offsets[1];
+            for (i = 0; i < height_uv; i ++) {
+                for (j = 0; j < width_uv; j += 2) {
+                    dst_uv[j] = inbuf_uv[j+1];  //u
+                    dst_uv[j+1] = inbuf_uv[j];  //v
+                }
+                dst_uv += image->pitches[1];
+                inbuf_uv += width_uv;
+            }
+#endif
+#endif //USE_SRC_FMT_YUV420
             
             vaUnmapBuffer(va_display, image->buf);	
             if (va_status != VA_STATUS_SUCCESS)	 
@@ -1469,12 +1519,12 @@
                    
             MixVideoFrame * frame = mix_videoframe_new();
             
-            if (mix->ref_fame == NULL)
+            if (mix->ref_frame == NULL)
             {
                 ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 1);
                 
                 ret = mix_surfacepool_get_frame_with_ci_frameidx 
-                    (parent->surfacepool, &mix->ref_fame, frame);
+                    (parent->surfacepool, &mix->ref_frame, frame);
                 if (ret != MIX_RESULT_SUCCESS)  //#ifdef SLEEP_SURFACE not used
                 {
                     LOG_E( 
@@ -1483,12 +1533,12 @@
                 }
             }
             
-            if (mix->rec_fame == NULL)	
+            if (mix->rec_frame == NULL)	
             {
                 ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 2);        
                 
                 ret = mix_surfacepool_get_frame_with_ci_frameidx
-                    (parent->surfacepool, &mix->rec_fame, frame);
+                    (parent->surfacepool, &mix->rec_frame, frame);
 
                 if (ret != MIX_RESULT_SUCCESS)
                 {
@@ -1498,13 +1548,13 @@
                 }
             }
 
-            //mix_videoframe_unref (mix->cur_fame);
+            //mix_videoframe_unref (mix->cur_frame);
 
             if (parent->need_display) {
-                mix->cur_fame = NULL;		
+                mix->cur_frame = NULL;		
             }
             
-            if (mix->cur_fame == NULL)
+            if (mix->cur_frame == NULL)
             {
                 guint ci_idx;
                 memcpy (&ci_idx, bufin->data, bufin->size);
@@ -1524,7 +1574,7 @@
                 ret = mix_videoframe_set_ci_frame_idx (frame, ci_idx);        
                 
                 ret = mix_surfacepool_get_frame_with_ci_frameidx
-                    (parent->surfacepool, &mix->cur_fame, frame);
+                    (parent->surfacepool, &mix->cur_frame, frame);
 
                 if (ret != MIX_RESULT_SUCCESS)
                 {
@@ -1534,7 +1584,7 @@
                 }			
             }
             
-            ret = mix_videoframe_get_frame_id(mix->cur_fame, &surface);
+            ret = mix_videoframe_get_frame_id(mix->cur_frame, &surface);
             
         }
         
@@ -1542,6 +1592,7 @@
         LOG_I( "va_context = 0x%08x\n",(guint)va_context);
         LOG_I( "surface = 0x%08x\n",(guint)surface);	        
         LOG_I( "va_display = 0x%08x\n",(guint)va_display);
+	
  
         va_status = vaBeginPicture(va_display, va_context, surface);
         if (va_status != VA_STATUS_SUCCESS)	 
@@ -1549,67 +1600,71 @@
             LOG_E( "Failed vaBeginPicture\n");
             return MIX_RESULT_FAIL;
         }	
-
-        LOG_V( "mix_videofmtenc_h264_send_seq_params\n");	
-		
-        if (mix->encoded_frames == 0) {
-            mix_videofmtenc_h264_send_seq_params (mix);
-            if (ret != MIX_RESULT_SUCCESS)
+        
+        ret = mix_videofmtenc_h264_send_encode_command (mix);
+        if (ret != MIX_RESULT_SUCCESS)
+        {
+            LOG_E ( 
+                    "Failed mix_videofmtenc_h264_send_encode_command\n");	
+            return MIX_RESULT_FAIL;
+        }			
+        
+        
+        if ((parent->va_rcmode == VA_RC_NONE) || mix->encoded_frames == 0) {
+            
+            va_status = vaEndPicture (va_display, va_context);
+            if (va_status != VA_STATUS_SUCCESS)	 
             {
-                LOG_E( 
-                        "Failed mix_videofmtenc_h264_send_seq_params\n");
+                LOG_E( "Failed vaEndPicture\n");		
                 return MIX_RESULT_FAIL;
             }
         }
         
-        ret = mix_videofmtenc_h264_send_picture_parameter (mix);	
-        
-        if (ret != MIX_RESULT_SUCCESS)
-        {
-           LOG_E( 
-                   "Failed mix_videofmtenc_h264_send_picture_parameter\n");	
-           return MIX_RESULT_FAIL;
+        if (mix->encoded_frames == 0) {
+            mix->encoded_frames ++;
+            mix->last_coded_buf = mix->coded_buf[mix->coded_buf_index];
+            mix->coded_buf_index ++; 
+            mix->coded_buf_index %=2;
+            
+            mix->last_frame = mix->cur_frame;
+            
+            
+            /* determine the picture type*/
+            if ((mix->encoded_frames % parent->intra_period) == 0) {
+                mix->is_intra = TRUE;
+            } else {
+                mix->is_intra = FALSE;
+            }						
+            
+            tmp_frame = mix->rec_frame;
+            mix->rec_frame= mix->ref_frame;
+            mix->ref_frame = tmp_frame;			
+            
+            
         }
         
-        ret = mix_videofmtenc_h264_send_slice_parameter (mix);
-        if (ret != MIX_RESULT_SUCCESS)
-        {            
-            LOG_E( 
-                    "Failed mix_videofmtenc_h264_send_slice_parameter\n");	
-            return MIX_RESULT_FAIL;
-        }		
-        
-        LOG_V( "before vaEndPicture\n");	
-
-        va_status = vaEndPicture (va_display, va_context);
-        if (va_status != VA_STATUS_SUCCESS)	 
-        {
-            LOG_E( "Failed vaEndPicture\n");		
-            return MIX_RESULT_FAIL;
-        }				
-    
         
         LOG_V( "vaSyncSurface\n");	
         
-        va_status = vaSyncSurface(va_display, surface);
+        va_status = vaSyncSurface(va_display, mix->last_frame->frame_id);
         if (va_status != VA_STATUS_SUCCESS)	 
         {
             LOG_E( "Failed vaSyncSurface\n");		
-            return MIX_RESULT_FAIL;
-        }				
-        
+			
+            //return MIX_RESULT_FAIL;
+        }				      
 
         LOG_V( 
                 "Start to get encoded data\n");		
-        
+		
         /*get encoded data from the VA buffer*/
-        va_status = vaMapBuffer (va_display, mix->coded_buf, (void **)&buf);
+        va_status = vaMapBuffer (va_display, mix->last_coded_buf, (void **)&buf);
         if (va_status != VA_STATUS_SUCCESS)	 
         {
             LOG_E( "Failed vaMapBuffer\n");	
             return MIX_RESULT_FAIL;
-        }			
-
+        }				
+	
         // first 4 bytes is the size of the buffer
         memcpy (&(iovout->data_size), (void*)buf, 4); 
         //size = (guint*) buf;
@@ -1620,6 +1675,7 @@
 
         //We will support two buffer mode, one is application allocates the buffer and passes to encode, 
         //the other is encode allocate memory
+
         
         if (iovout->data == NULL) { //means  app doesn't allocate the buffer, so _encode will allocate it.
             iovout->data = g_malloc (size);  // In case we have lots of 0x000001 start code, and we replace them with 4 bytes length prefixed
@@ -1637,15 +1693,15 @@
             guint zero_byte_count = 0;	
             guint prefix_length = 0;				
             guint8 nal_unit_type = 0; 
-	     guint8 * payload = buf + 16;
+            guint8 * payload = buf + 16;
 
             while ((payload[pos++] == 0x00)) {                
                 zero_byte_count ++;
                 if (pos >= iovout->data_size)  //to make sure the buffer to be accessed is valid
                     break;
             }			 
-			
-	     nal_unit_type = (guint8)(payload[pos] & 0x1f);
+            
+            nal_unit_type = (guint8)(payload[pos] & 0x1f);
             prefix_length = zero_byte_count + 1;		 
 
             LOG_I ("nal_unit_type = %d\n", nal_unit_type);		 
@@ -1675,34 +1731,51 @@
         iovout->data_size = size;
         LOG_I( 
                 "out size is = %d\n", iovout->data_size);	
-        
-        va_status = vaUnmapBuffer (va_display, mix->coded_buf);
+       
+        va_status = vaUnmapBuffer (va_display, mix->last_coded_buf);
         if (va_status != VA_STATUS_SUCCESS)	 
         {
             LOG_E( "Failed vaUnmapBuffer\n");				
             return MIX_RESULT_FAIL;
         }		
 	
-        LOG_V( "get encoded data done\n");		
-#if 0
-        if (parent->drawable) {
-            va_status = vaPutSurface(va_display, surface, (Drawable)parent->drawable,
-                    0,0, width, height,
-                    0,0, width, height,
-                    NULL,0,0);
-        } 
-		
-#ifdef SHOW_SRC
-        else {
+        LOG_V( "get encoded data done\n");	
 
-            va_status = vaPutSurface(va_display, surface, win,
-                    0,0, width, height,
-                    0,0, width, height,
-                    NULL,0,0);		
-        }
-#endif //SHOW_SRC
-#endif
-
+        if (!((parent->va_rcmode == VA_RC_NONE) || mix->encoded_frames == 1)) {
+            
+            va_status = vaEndPicture (va_display, va_context);
+            if (va_status != VA_STATUS_SUCCESS)	 
+            {
+                LOG_E( "Failed vaEndPicture\n");		
+                return MIX_RESULT_FAIL;
+            }
+        }		
+                
+        if (mix->encoded_frames == 1) {
+            va_status = vaBeginPicture(va_display, va_context, surface);
+            if (va_status != VA_STATUS_SUCCESS)	 
+            {
+                LOG_E( "Failed vaBeginPicture\n");
+                return MIX_RESULT_FAIL;
+            }				
+            
+            ret = mix_videofmtenc_h264_send_encode_command (mix);
+            if (ret != MIX_RESULT_SUCCESS)
+            {
+                LOG_E ( 
+                        "Failed mix_videofmtenc_h264_send_encode_command\n");	
+                return MIX_RESULT_FAIL;
+            }				
+            
+            va_status = vaEndPicture (va_display, va_context);
+            if (va_status != VA_STATUS_SUCCESS)	 
+            {
+                LOG_E( "Failed vaEndPicture\n");		
+                return MIX_RESULT_FAIL;
+            }					
+            
+        }	
+       
         VASurfaceStatus status;
         
         /*query the status of current surface*/
@@ -1716,7 +1789,13 @@
         mix->pic_skipped = status & VASurfaceSkipped;		
 
         if (parent->need_display) {
-            ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_fame);	
+    		ret = mix_videoframe_set_sync_flag(mix->cur_frame, TRUE);
+    		if (ret != MIX_RESULT_SUCCESS) {
+    			LOG_E("Failed to set sync_flag\n");
+                return ret;
+    		}
+
+            ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_frame);	
             if (ret != MIX_RESULT_SUCCESS)
             {            
                 LOG_E( 
@@ -1728,25 +1807,30 @@
         
         /*update the reference surface and reconstructed surface */
         if (!mix->pic_skipped) {
-            tmp_fame = mix->rec_fame;
-            mix->rec_fame= mix->ref_fame;
-            mix->ref_fame = tmp_fame;
+            tmp_frame = mix->rec_frame;
+            mix->rec_frame= mix->ref_frame;
+            mix->ref_frame = tmp_frame;
         } 			
                 
 #if 0
-        if (mix->ref_fame != NULL)
-            mix_videoframe_unref (mix->ref_fame);
-        mix->ref_fame = mix->rec_fame;
+        if (mix->ref_frame != NULL)
+            mix_videoframe_unref (mix->ref_frame);
+        mix->ref_frame = mix->rec_frame;
         
-        mix_videoframe_unref (mix->cur_fame);
+        mix_videoframe_unref (mix->cur_frame);
 #endif		
-
-        if (!(parent->need_display)) {
-            mix_videoframe_unref (mix->cur_fame);
-            mix->cur_fame = NULL;
-        }
         
         mix->encoded_frames ++;
+        mix->last_coded_buf = mix->coded_buf[mix->coded_buf_index];
+        mix->coded_buf_index ++; 
+        mix->coded_buf_index %=2;
+        mix->last_frame = mix->cur_frame;
+
+
+        if (!(parent->need_display)) {
+            mix_videoframe_unref (mix->cur_frame);
+            mix->cur_frame = NULL;
+        }
     }
     else
     {
@@ -1754,8 +1838,7 @@
                 "not H264 video encode Object\n");	
         return MIX_RESULT_FAIL;		
     }
-    
-    
+        
     LOG_V( "end\n");		
  
     return MIX_RESULT_SUCCESS;
@@ -1952,3 +2035,46 @@
     
 }
 
+MIX_RESULT mix_videofmtenc_h264_send_encode_command (MixVideoFormatEnc_H264 *mix)
+{
+    MIX_RESULT ret = MIX_RESULT_SUCCESS;
+
+    LOG_V( "Begin\n");		
+
+    if (MIX_IS_VIDEOFORMATENC_H264(mix))
+    {
+        if (mix->encoded_frames == 0) {
+            mix_videofmtenc_h264_send_seq_params (mix);
+            if (ret != MIX_RESULT_SUCCESS)
+            {
+                LOG_E( 
+                        "Failed mix_videofmtenc_h264_send_seq_params\n");
+                return MIX_RESULT_FAIL;
+            }
+        }
+        
+        ret = mix_videofmtenc_h264_send_picture_parameter (mix);	
+        
+        if (ret != MIX_RESULT_SUCCESS)
+        {
+            LOG_E( 
+                    "Failed mix_videofmtenc_h264_send_picture_parameter\n");	
+            return MIX_RESULT_FAIL;
+        }
+        
+        ret = mix_videofmtenc_h264_send_slice_parameter (mix);
+        if (ret != MIX_RESULT_SUCCESS)
+        {            
+            LOG_E( 
+                    "Failed mix_videofmtenc_h264_send_slice_parameter\n");	
+            return MIX_RESULT_FAIL;
+        }		
+        
+    }
+
+    LOG_V( "End\n");		
+	
+
+	return MIX_RESULT_SUCCESS;
+}
+
diff --git a/mix_video/src/mixvideoformatenc_h264.h b/mix_video/src/mixvideoformatenc_h264.h
index eeef2d9..0ef0e18 100644
--- a/mix_video/src/mixvideoformatenc_h264.h
+++ b/mix_video/src/mixvideoformatenc_h264.h
@@ -34,7 +34,8 @@
 	/*< public > */
     MixVideoFormatEnc parent;
 
-    VABufferID      coded_buf;
+    VABufferID      coded_buf[2];
+    VABufferID      last_coded_buf;
     VABufferID      seq_param_buf;
     VABufferID      pic_param_buf;
     VABufferID      slice_param_buf;	
@@ -42,9 +43,10 @@
     VASurfaceID *   surfaces;
     guint           surface_num;	
 
-    MixVideoFrame  *cur_fame;	//current input frame to be encoded;	
-    MixVideoFrame  *ref_fame;  //reference frame
-    MixVideoFrame  *rec_fame;	//reconstructed frame;	
+    MixVideoFrame  *cur_frame;	//current input frame to be encoded;	
+    MixVideoFrame  *ref_frame;  //reference frame
+    MixVideoFrame  *rec_frame;	//reconstructed frame;	
+    MixVideoFrame  *last_frame;	//last frame;	
 
     guint basic_unit_size;  //for rate control
     guint disable_deblocking_filter_idc;
@@ -58,6 +60,7 @@
     gboolean    is_intra;
 
     guint       coded_buf_size;
+    guint coded_buf_index;
 
 	/*< public > */
 };
@@ -125,13 +128,15 @@
 MIX_RESULT mix_videofmtenc_h264_flush(MixVideoFormatEnc *mix);
 MIX_RESULT mix_videofmtenc_h264_eos(MixVideoFormatEnc *mix);
 MIX_RESULT mix_videofmtenc_h264_deinitialize(MixVideoFormatEnc *mix);
-MIX_RESULT mix_videofmtenc_h264_get_max_encoded_buf_size (MixVideoFormatEnc *mix, guint * max_size);
 
 /* Local Methods */
 
+MIX_RESULT mix_videofmtenc_h264_get_max_encoded_buf_size (MixVideoFormatEnc *mix, guint *max_size);
 MIX_RESULT mix_videofmtenc_h264_process_encode (MixVideoFormatEnc_H264 *mix, MixBuffer * bufin, 
         MixIOVec * iovout);
 MIX_RESULT mix_videofmtenc_h264_AnnexB_to_length_prefixed (
         guint8 * bufin, guint bufin_len, guint8* bufout, guint *bufout_len);
 
+MIX_RESULT mix_videofmtenc_h264_send_encode_command (MixVideoFormatEnc_H264 *mix);
+
 #endif /* __MIX_VIDEOFORMATENC_H264_H__ */
diff --git a/mix_video/src/mixvideoformatenc_mpeg4.c b/mix_video/src/mixvideoformatenc_mpeg4.c
index e58976b..25b3b3e 100644
--- a/mix_video/src/mixvideoformatenc_mpeg4.c
+++ b/mix_video/src/mixvideoformatenc_mpeg4.c
@@ -44,15 +44,17 @@
     self->encoded_frames = 0;

     self->pic_skipped = FALSE;

     self->is_intra = TRUE;

-    self->cur_fame = NULL;

-    self->ref_fame = NULL;

-    self->rec_fame = NULL;	

+    self->cur_frame = NULL;

+    self->ref_frame = NULL;

+    self->rec_frame = NULL;	

 

     self->ci_shared_surfaces = NULL;

     self->surfaces= NULL;

     self->surface_num = 0;

+    self->coded_buf_index = 0;

 

     parent->initialized = FALSE;

+	

 }

 

 static void mix_videoformatenc_mpeg4_class_init(

@@ -570,7 +572,7 @@
                 "mix_surfacepool_initialize\n");			

         

         ret = mix_surfacepool_initialize(parent->surfacepool,

-                self->surfaces, parent->ci_frame_num + numSurfaces);

+                self->surfaces, parent->ci_frame_num + numSurfaces, va_display);

         

         switch (ret)

         {

@@ -626,7 +628,7 @@
                 VAEncCodedBufferType,

                 self->coded_buf_size,  //

                 1, NULL,

-                &self->coded_buf);

+                &self->coded_buf[0]);

         

         if (va_status != VA_STATUS_SUCCESS)	 

         {

@@ -636,7 +638,24 @@
             g_mutex_unlock(parent->objectlock);

             return MIX_RESULT_FAIL;

         }

+

+

+        /*Create coded buffer for output*/

+        va_status = vaCreateBuffer (va_display, parent->va_context,

+                VAEncCodedBufferType,

+                self->coded_buf_size,  //

+                1, NULL,

+                &(self->coded_buf[1]));

         

+        if (va_status != VA_STATUS_SUCCESS)	 

+        {

+            LOG_E( 

+                    "Failed to vaCreateBuffer: VAEncCodedBufferType\n");	

+            g_free (surfaces);			

+            g_mutex_unlock(parent->objectlock);

+            return MIX_RESULT_FAIL;

+        }

+		

 #ifdef SHOW_SRC

         Display * display = XOpenDisplay (NULL);

 

@@ -776,24 +795,24 @@
     g_mutex_lock(mix->objectlock);

     

     /*unref the current source surface*/ 

-    if (self->cur_fame != NULL)

+    if (self->cur_frame != NULL)

     {

-        mix_videoframe_unref (self->cur_fame);

-        self->cur_fame = NULL;

+        mix_videoframe_unref (self->cur_frame);

+        self->cur_frame = NULL;

     }

     

     /*unref the reconstructed surface*/ 

-    if (self->rec_fame != NULL)

+    if (self->rec_frame != NULL)

     {

-        mix_videoframe_unref (self->rec_fame);

-        self->rec_fame = NULL;

+        mix_videoframe_unref (self->rec_frame);

+        self->rec_frame = NULL;

     }

 

     /*unref the reference surface*/ 

-    if (self->ref_fame != NULL)

+    if (self->ref_frame != NULL)

     {

-        mix_videoframe_unref (self->ref_fame);

-        self->ref_fame = NULL;       

+        mix_videoframe_unref (self->ref_frame);

+        self->ref_frame = NULL;       

     }

     

     /*reset the properities*/    

@@ -850,25 +869,25 @@
 

 #if 0

     /*unref the current source surface*/ 

-    if (self->cur_fame != NULL)

+    if (self->cur_frame != NULL)

     {

-        mix_videoframe_unref (self->cur_fame);

-        self->cur_fame = NULL;

+        mix_videoframe_unref (self->cur_frame);

+        self->cur_frame = NULL;

     }

 #endif	

     

     /*unref the reconstructed surface*/ 

-    if (self->rec_fame != NULL)

+    if (self->rec_frame != NULL)

     {

-        mix_videoframe_unref (self->rec_fame);

-        self->rec_fame = NULL;

+        mix_videoframe_unref (self->rec_frame);

+        self->rec_frame = NULL;

     }

 

     /*unref the reference surface*/ 

-    if (self->ref_fame != NULL)

+    if (self->ref_frame != NULL)

     {

-        mix_videoframe_unref (self->ref_fame);

-        self->ref_fame = NULL;       

+        mix_videoframe_unref (self->ref_frame);

+        self->ref_frame = NULL;       

     }	

 

     LOG_V( "Release surfaces\n");			

@@ -1047,9 +1066,9 @@
         parent = MIX_VIDEOFORMATENC(&(mix->parent));

         

         /*set picture params for HW*/

-        mpeg4_pic_param.reference_picture = mix->ref_fame->frame_id;  

-        mpeg4_pic_param.reconstructed_picture = mix->rec_fame->frame_id;

-        mpeg4_pic_param.coded_buf = mix->coded_buf;

+        mpeg4_pic_param.reference_picture = mix->ref_frame->frame_id;  

+        mpeg4_pic_param.reconstructed_picture = mix->rec_frame->frame_id;

+        mpeg4_pic_param.coded_buf = mix->coded_buf[mix->coded_buf_index];

         mpeg4_pic_param.picture_width = parent->picture_width;

         mpeg4_pic_param.picture_height = parent->picture_height;

         mpeg4_pic_param.vop_time_increment= mix->encoded_frames;	

@@ -1065,6 +1084,8 @@
                 mpeg4_pic_param.reconstructed_picture);	

         LOG_I( "coded_buf = 0x%08x\n", 

                 mpeg4_pic_param.coded_buf);	

+        LOG_I( "coded_buf_index = %d\n", 

+                mix->coded_buf_index);			

         LOG_I( "picture_width = %d\n", 

                 mpeg4_pic_param.picture_width);	

         LOG_I( "picture_height = %d\n", 

@@ -1206,7 +1227,7 @@
     gulong surface = 0;

     guint16 width, height;

     

-    MixVideoFrame *  tmp_fame;

+    MixVideoFrame *  tmp_frame;

     guint8 *buf;

     

     if ((mix == NULL) || (bufin == NULL) || (iovout == NULL)) {

@@ -1256,9 +1277,9 @@
             LOG_V( 

                     "We are NOT in share buffer mode\n");		

             

-            if (mix->ref_fame == NULL)

+            if (mix->ref_frame == NULL)

             {

-                ret = mix_surfacepool_get(parent->surfacepool, &mix->ref_fame);

+                ret = mix_surfacepool_get(parent->surfacepool, &mix->ref_frame);

                 if (ret != MIX_RESULT_SUCCESS)  //#ifdef SLEEP_SURFACE not used

                 {

                     LOG_E( 

@@ -1267,9 +1288,9 @@
                 }

             }

             

-            if (mix->rec_fame == NULL)	

+            if (mix->rec_frame == NULL)	

             {

-                ret = mix_surfacepool_get(parent->surfacepool, &mix->rec_fame);

+                ret = mix_surfacepool_get(parent->surfacepool, &mix->rec_frame);

                 if (ret != MIX_RESULT_SUCCESS)

                 {

                     LOG_E( 

@@ -1279,12 +1300,12 @@
             }

 

             if (parent->need_display) {

-                mix->cur_fame = NULL;				

+                mix->cur_frame = NULL;				

             }

 			

-            if (mix->cur_fame == NULL)

+            if (mix->cur_frame == NULL)

             {

-                ret = mix_surfacepool_get(parent->surfacepool, &mix->cur_fame);

+                ret = mix_surfacepool_get(parent->surfacepool, &mix->cur_frame);

                 if (ret != MIX_RESULT_SUCCESS)

                 {

                     LOG_E( 

@@ -1305,7 +1326,7 @@
             LOG_V( 

                     "map source data to surface\n");	

             

-            ret = mix_videoframe_get_frame_id(mix->cur_fame, &surface);

+            ret = mix_videoframe_get_frame_id(mix->cur_frame, &surface);

             if (ret != MIX_RESULT_SUCCESS)

             {

                 LOG_E( 

@@ -1405,12 +1426,12 @@
                    

             MixVideoFrame * frame = mix_videoframe_new();

             

-            if (mix->ref_fame == NULL)

+            if (mix->ref_frame == NULL)

             {

                 ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 1);

                 

                 ret = mix_surfacepool_get_frame_with_ci_frameidx 

-                    (parent->surfacepool, &mix->ref_fame, frame);

+                    (parent->surfacepool, &mix->ref_frame, frame);

                 if (ret != MIX_RESULT_SUCCESS)  //#ifdef SLEEP_SURFACE not used

                 {

                     LOG_E( 

@@ -1419,12 +1440,12 @@
                 }

             }

             

-            if (mix->rec_fame == NULL)	

+            if (mix->rec_frame == NULL)	

             {

                 ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 2);        

                 

                 ret = mix_surfacepool_get_frame_with_ci_frameidx

-                    (parent->surfacepool, &mix->rec_fame, frame);

+                    (parent->surfacepool, &mix->rec_frame, frame);

 

                 if (ret != MIX_RESULT_SUCCESS)

                 {

@@ -1435,10 +1456,10 @@
             }

 

             if (parent->need_display) {

-                mix->cur_fame = NULL;		

+                mix->cur_frame = NULL;		

             }			

             

-            if (mix->cur_fame == NULL)

+            if (mix->cur_frame == NULL)

             {

                 guint ci_idx;

                 memcpy (&ci_idx, bufin->data, bufin->size);

@@ -1458,7 +1479,7 @@
                 ret = mix_videoframe_set_ci_frame_idx (frame, ci_idx);        

                 

                 ret = mix_surfacepool_get_frame_with_ci_frameidx

-                    (parent->surfacepool, &mix->cur_fame, frame);

+                    (parent->surfacepool, &mix->cur_frame, frame);

 

                 if (ret != MIX_RESULT_SUCCESS)

                 {

@@ -1468,7 +1489,7 @@
                 }			

             }

             

-            ret = mix_videoframe_get_frame_id(mix->cur_fame, &surface);

+            ret = mix_videoframe_get_frame_id(mix->cur_frame, &surface);

             

         }

         

@@ -1476,60 +1497,64 @@
         LOG_I( "va_context = 0x%08x\n",(guint)va_context);

         LOG_I( "surface = 0x%08x\n",(guint)surface);	        

         LOG_I( "va_display = 0x%08x\n",(guint)va_display);

- 

+		

+

         va_status = vaBeginPicture(va_display, va_context, surface);

         if (va_status != VA_STATUS_SUCCESS)	 

         {

             LOG_E( "Failed vaBeginPicture\n");

             return MIX_RESULT_FAIL;

         }	

-

-        LOG_V( "mix_videofmtenc_mpeg4_send_seq_params\n");	

-		

-        if (mix->encoded_frames == 0) {

-            mix_videofmtenc_mpeg4_send_seq_params (mix);

-            if (ret != MIX_RESULT_SUCCESS)

+        

+        ret = mix_videofmtenc_mpeg4_send_encode_command (mix);

+        if (ret != MIX_RESULT_SUCCESS)

+        {

+            LOG_E ( 

+                    "Failed mix_videofmtenc_h264_send_encode_command\n");	

+            return MIX_RESULT_FAIL;

+        }			

+        

+        

+        if ((parent->va_rcmode == VA_RC_NONE) || mix->encoded_frames == 0) {

+            

+            va_status = vaEndPicture (va_display, va_context);

+            if (va_status != VA_STATUS_SUCCESS)	 

             {

-                LOG_E( 

-                        "Failed mix_videofmtenc_mpeg4_send_seq_params\n");

+                LOG_E( "Failed vaEndPicture\n");		

                 return MIX_RESULT_FAIL;

             }

         }

         

-        ret = mix_videofmtenc_mpeg4_send_picture_parameter (mix);	

-        

-        if (ret != MIX_RESULT_SUCCESS)

-        {

-           LOG_E( 

-                   "Failed mix_videofmtenc_mpeg4_send_picture_parameter\n");	

-           return MIX_RESULT_FAIL;

+        if (mix->encoded_frames == 0) {

+            mix->encoded_frames ++;

+            mix->last_coded_buf = mix->coded_buf[mix->coded_buf_index];

+            mix->coded_buf_index ++; 

+            mix->coded_buf_index %=2;

+            

+            mix->last_frame = mix->cur_frame;

+            

+            

+            /* determine the picture type*/

+            if ((mix->encoded_frames % parent->intra_period) == 0) {

+                mix->is_intra = TRUE;

+            } else {

+                mix->is_intra = FALSE;

+            }						

+            

+            tmp_frame = mix->rec_frame;

+            mix->rec_frame= mix->ref_frame;

+            mix->ref_frame = tmp_frame;			

+            

+            

         }

         

-        ret = mix_videofmtenc_mpeg4_send_slice_parameter (mix);

-        if (ret != MIX_RESULT_SUCCESS)

-        {            

-            LOG_E( 

-                    "Failed mix_videofmtenc_mpeg4_send_slice_parameter\n");	

-            return MIX_RESULT_FAIL;

-        }		

-        

-        LOG_V( "before vaEndPicture\n");	

-

-        va_status = vaEndPicture (va_display, va_context);

-        if (va_status != VA_STATUS_SUCCESS)	 

-        {

-            LOG_E( "Failed vaEndPicture\n");		

-            return MIX_RESULT_FAIL;

-        }				

-    

-        

         LOG_V( "vaSyncSurface\n");	

         

-        va_status = vaSyncSurface(va_display, surface);

+        va_status = vaSyncSurface(va_display, mix->last_frame->frame_id);

         if (va_status != VA_STATUS_SUCCESS)	 

         {

             LOG_E( "Failed vaSyncSurface\n");		

-            return MIX_RESULT_FAIL;

+            //return MIX_RESULT_FAIL;

         }				

         

 

@@ -1537,7 +1562,7 @@
                 "Start to get encoded data\n");		

         

         /*get encoded data from the VA buffer*/

-        va_status = vaMapBuffer (va_display, mix->coded_buf, (void **)&buf);

+        va_status = vaMapBuffer (va_display, mix->last_coded_buf, (void **)&buf);

         if (va_status != VA_STATUS_SUCCESS)	 

         {

             LOG_E( "Failed vaMapBuffer\n");	

@@ -1563,7 +1588,7 @@
         LOG_I( 

                 "out size is = %d\n", iovout->data_size);	

         

-        va_status = vaUnmapBuffer (va_display, mix->coded_buf);

+        va_status = vaUnmapBuffer (va_display, mix->last_coded_buf);

         if (va_status != VA_STATUS_SUCCESS)	 

         {

             LOG_E( "Failed vaUnmapBuffer\n");				

@@ -1572,24 +1597,40 @@
 	

         LOG_V( "get encoded data done\n");		

 

-#if 0

-        if (parent->drawable) {

-            va_status = vaPutSurface(va_display, surface, (Drawable)parent->drawable,

-                    0,0, width, height,

-                    0,0, width, height,

-                    NULL,0,0);

-        } 

-		

-#ifdef SHOW_SRC

-        else {

-

-            va_status = vaPutSurface(va_display, surface, win,

-                    0,0, width, height,

-                    0,0, width, height,

-                    NULL,0,0);		

-        }

-#endif //SHOW_SRC

-#endif

+       if (!((parent->va_rcmode == VA_RC_NONE) || mix->encoded_frames == 1)) {

+            

+            va_status = vaEndPicture (va_display, va_context);

+            if (va_status != VA_STATUS_SUCCESS)	 

+            {

+                LOG_E( "Failed vaEndPicture\n");		

+                return MIX_RESULT_FAIL;

+            }

+        }		

+                

+        if (mix->encoded_frames == 1) {

+            va_status = vaBeginPicture(va_display, va_context, surface);

+            if (va_status != VA_STATUS_SUCCESS)	 

+            {

+                LOG_E( "Failed vaBeginPicture\n");

+                return MIX_RESULT_FAIL;

+            }				

+            

+            ret = mix_videofmtenc_mpeg4_send_encode_command (mix);

+            if (ret != MIX_RESULT_SUCCESS)

+            {

+                LOG_E ( 

+                        "Failed mix_videofmtenc_h264_send_encode_command\n");	

+                return MIX_RESULT_FAIL;

+            }				

+            

+            va_status = vaEndPicture (va_display, va_context);

+            if (va_status != VA_STATUS_SUCCESS)	 

+            {

+                LOG_E( "Failed vaEndPicture\n");		

+                return MIX_RESULT_FAIL;

+            }					

+            

+        }	

 

         VASurfaceStatus status;

         

@@ -1603,41 +1644,48 @@
         }				

         mix->pic_skipped = status & VASurfaceSkipped;		

 

-	//ret = mix_framemanager_enqueue(parent->framemgr, mix->rec_fame);	

+	//ret = mix_framemanager_enqueue(parent->framemgr, mix->rec_frame);	

 

        if (parent->need_display) {

-	ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_fame);	

-        if (ret != MIX_RESULT_SUCCESS)

-        {            

-            LOG_E( 

-                    "Failed mix_framemanager_enqueue\n");	

-            return MIX_RESULT_FAIL;

-        }		

-        }	

-		

-        

+			ret = mix_videoframe_set_sync_flag(mix->cur_frame, TRUE);

+			if (ret != MIX_RESULT_SUCCESS) {

+				LOG_E("Failed to set sync_flag\n");

+				return ret;

+			}

+

+			ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_frame);

+			if (ret != MIX_RESULT_SUCCESS) {

+				LOG_E("Failed mix_framemanager_enqueue\n");

+				return MIX_RESULT_FAIL;

+			}

+		}

+

         /*update the reference surface and reconstructed surface */

         if (!mix->pic_skipped) {

-            tmp_fame = mix->rec_fame;

-            mix->rec_fame= mix->ref_fame;

-            mix->ref_fame = tmp_fame;

+            tmp_frame = mix->rec_frame;

+            mix->rec_frame= mix->ref_frame;

+            mix->ref_frame = tmp_frame;

         } 			

         

         

 #if 0

-        if (mix->ref_fame != NULL)

-            mix_videoframe_unref (mix->ref_fame);

-        mix->ref_fame = mix->rec_fame;

+        if (mix->ref_frame != NULL)

+            mix_videoframe_unref (mix->ref_frame);

+        mix->ref_frame = mix->rec_frame;

         

-        mix_videoframe_unref (mix->cur_fame);

+        mix_videoframe_unref (mix->cur_frame);

 #endif		

-

-        if (!(parent->need_display)) {

-            mix_videoframe_unref (mix->cur_fame);

-            mix->cur_fame = NULL;

-        }

         

         mix->encoded_frames ++;

+        mix->last_coded_buf = mix->coded_buf[mix->coded_buf_index];

+        mix->coded_buf_index ++; 

+        mix->coded_buf_index %=2;

+        mix->last_frame = mix->cur_frame;

+

+        if (!(parent->need_display)) {

+            mix_videoframe_unref (mix->cur_frame);

+            mix->cur_frame = NULL;

+        }

     }

     else

     {

@@ -1711,3 +1759,45 @@
 	

     return MIX_RESULT_SUCCESS;    

 }

+

+MIX_RESULT mix_videofmtenc_mpeg4_send_encode_command (MixVideoFormatEnc_MPEG4 *mix)

+{

+    MIX_RESULT ret = MIX_RESULT_SUCCESS;

+

+    LOG_V( "Begin\n");		

+

+    if (MIX_IS_VIDEOFORMATENC_MPEG4(mix))

+    {

+        if (mix->encoded_frames == 0) {

+            mix_videofmtenc_mpeg4_send_seq_params (mix);

+            if (ret != MIX_RESULT_SUCCESS)

+            {

+                LOG_E( 

+                        "Failed mix_videofmtenc_h264_send_seq_params\n");

+                return MIX_RESULT_FAIL;

+            }

+        }

+        

+        ret = mix_videofmtenc_mpeg4_send_picture_parameter (mix);	

+        

+        if (ret != MIX_RESULT_SUCCESS)

+        {

+            LOG_E( 

+                    "Failed mix_videofmtenc_h264_send_picture_parameter\n");	

+            return MIX_RESULT_FAIL;

+        }

+        

+        ret = mix_videofmtenc_mpeg4_send_slice_parameter (mix);

+        if (ret != MIX_RESULT_SUCCESS)

+        {            

+            LOG_E( 

+                    "Failed mix_videofmtenc_h264_send_slice_parameter\n");	

+            return MIX_RESULT_FAIL;

+        }		

+        

+    }

+

+    LOG_V( "End\n");			

+

+	return MIX_RESULT_SUCCESS;

+}

diff --git a/mix_video/src/mixvideoformatenc_mpeg4.h b/mix_video/src/mixvideoformatenc_mpeg4.h
index dc26efe..4a7deb1 100644
--- a/mix_video/src/mixvideoformatenc_mpeg4.h
+++ b/mix_video/src/mixvideoformatenc_mpeg4.h
@@ -35,7 +35,8 @@
 	MixVideoFormatEnc parent;

 

 

-    	VABufferID      coded_buf;

+    	VABufferID      coded_buf[2];

+    	VABufferID      last_coded_buf;		

     	VABufferID      seq_param_buf;

     	VABufferID      pic_param_buf;

     	VABufferID      slice_param_buf;	

@@ -43,9 +44,11 @@
 	VASurfaceID * surfaces;

 	guint surface_num;	

 

-	MixVideoFrame  *cur_fame;	//current input frame to be encoded;	

-	MixVideoFrame  *ref_fame;  //reference frame

-	MixVideoFrame  *rec_fame;	//reconstructed frame;	

+	MixVideoFrame  *cur_frame;	//current input frame to be encoded;	

+	MixVideoFrame  *ref_frame;  //reference frame

+	MixVideoFrame  *rec_frame;	//reconstructed frame;	

+	MixVideoFrame  *last_frame;	//last frame;	

+	

 

 	guchar  profile_and_level_indication;

  	guint fixed_vop_time_increment;

@@ -59,6 +62,8 @@
 	gboolean is_intra;

 

 	guint coded_buf_size;

+	guint coded_buf_index;

+		

 

 	/*< public > */

 };

@@ -132,6 +137,7 @@
 

 MIX_RESULT mix_videofmtenc_mpeg4_process_encode (MixVideoFormatEnc_MPEG4 *mix, MixBuffer * bufin, 

 	MixIOVec * iovout);

+MIX_RESULT mix_videofmtenc_mpeg4_send_encode_command (MixVideoFormatEnc_MPEG4 *mix);

 

 #endif /* __MIX_VIDEOFORMATENC_MPEG4_H__ */

 

diff --git a/mix_video/src/mixvideoformatenc_preview.c b/mix_video/src/mixvideoformatenc_preview.c
index 17b9a4b..6aeeb9e 100644
--- a/mix_video/src/mixvideoformatenc_preview.c
+++ b/mix_video/src/mixvideoformatenc_preview.c
@@ -44,9 +44,9 @@
     self->encoded_frames = 0;
     self->pic_skipped = FALSE;
     self->is_intra = TRUE;
-    self->cur_fame = NULL;
-    self->ref_fame = NULL;
-    self->rec_fame = NULL;	
+    self->cur_frame = NULL;
+    self->ref_frame = NULL;
+    self->rec_frame = NULL;	
 
     self->ci_shared_surfaces = NULL;
     self->surfaces= NULL;
@@ -523,7 +523,7 @@
                 "mix_surfacepool_initialize\n");			
         
         ret = mix_surfacepool_initialize(parent->surfacepool,
-                self->surfaces, parent->ci_frame_num + numSurfaces);
+                self->surfaces, parent->ci_frame_num + numSurfaces, va_display);
         
         switch (ret)
         {
@@ -720,25 +720,25 @@
 
 #if 0    
     /*unref the current source surface*/ 
-    if (self->cur_fame != NULL)
+    if (self->cur_frame != NULL)
     {
-        mix_videoframe_unref (self->cur_fame);
-        self->cur_fame = NULL;
+        mix_videoframe_unref (self->cur_frame);
+        self->cur_frame = NULL;
     }
 #endif		
     
     /*unref the reconstructed surface*/ 
-    if (self->rec_fame != NULL)
+    if (self->rec_frame != NULL)
     {
-        mix_videoframe_unref (self->rec_fame);
-        self->rec_fame = NULL;
+        mix_videoframe_unref (self->rec_frame);
+        self->rec_frame = NULL;
     }
 
     /*unref the reference surface*/ 
-    if (self->ref_fame != NULL)
+    if (self->ref_frame != NULL)
     {
-        mix_videoframe_unref (self->ref_fame);
-        self->ref_fame = NULL;       
+        mix_videoframe_unref (self->ref_frame);
+        self->ref_frame = NULL;       
     }
     
     /*reset the properities*/    
@@ -795,25 +795,25 @@
 
 #if 0
     /*unref the current source surface*/ 
-    if (self->cur_fame != NULL)
+    if (self->cur_frame != NULL)
     {
-        mix_videoframe_unref (self->cur_fame);
-        self->cur_fame = NULL;
+        mix_videoframe_unref (self->cur_frame);
+        self->cur_frame = NULL;
     }
 #endif	
     
     /*unref the reconstructed surface*/ 
-    if (self->rec_fame != NULL)
+    if (self->rec_frame != NULL)
     {
-        mix_videoframe_unref (self->rec_fame);
-        self->rec_fame = NULL;
+        mix_videoframe_unref (self->rec_frame);
+        self->rec_frame = NULL;
     }
 
     /*unref the reference surface*/ 
-    if (self->ref_fame != NULL)
+    if (self->ref_frame != NULL)
     {
-        mix_videoframe_unref (self->ref_fame);
-        self->ref_fame = NULL;       
+        mix_videoframe_unref (self->ref_frame);
+        self->ref_frame = NULL;       
     }	
 
     LOG_V( "Release surfaces\n");			
@@ -881,7 +881,7 @@
     gulong surface = 0;
     guint16 width, height;
     
-    //MixVideoFrame *  tmp_fame;
+    //MixVideoFrame *  tmp_frame;
     //guint8 *buf;
     
     if ((mix == NULL) || (bufin == NULL) || (iovout == NULL)) {
@@ -921,9 +921,9 @@
             LOG_V( 
                     "We are NOT in share buffer mode\n");		
             
-            if (mix->ref_fame == NULL)
+            if (mix->ref_frame == NULL)
             {
-                ret = mix_surfacepool_get(parent->surfacepool, &mix->ref_fame);
+                ret = mix_surfacepool_get(parent->surfacepool, &mix->ref_frame);
                 if (ret != MIX_RESULT_SUCCESS)  //#ifdef SLEEP_SURFACE not used
                 {
                     LOG_E( 
@@ -932,9 +932,9 @@
                 }
             }
             
-            if (mix->rec_fame == NULL)	
+            if (mix->rec_frame == NULL)	
             {
-                ret = mix_surfacepool_get(parent->surfacepool, &mix->rec_fame);
+                ret = mix_surfacepool_get(parent->surfacepool, &mix->rec_frame);
                 if (ret != MIX_RESULT_SUCCESS)
                 {
                     LOG_E( 
@@ -944,12 +944,12 @@
             }
 
             if (parent->need_display) {
-                mix->cur_fame = NULL;				
+                mix->cur_frame = NULL;				
             }
             
-            if (mix->cur_fame == NULL)
+            if (mix->cur_frame == NULL)
             {
-                ret = mix_surfacepool_get(parent->surfacepool, &mix->cur_fame);
+                ret = mix_surfacepool_get(parent->surfacepool, &mix->cur_frame);
                 if (ret != MIX_RESULT_SUCCESS)
                 {
                     LOG_E( 
@@ -970,7 +970,7 @@
             LOG_V( 
                     "map source data to surface\n");	
             
-            ret = mix_videoframe_get_frame_id(mix->cur_fame, &surface);
+            ret = mix_videoframe_get_frame_id(mix->cur_frame, &surface);
             if (ret != MIX_RESULT_SUCCESS)
             {
                 LOG_E( 
@@ -1070,12 +1070,12 @@
                    
             MixVideoFrame * frame = mix_videoframe_new();
             
-            if (mix->ref_fame == NULL)
+            if (mix->ref_frame == NULL)
             {
                 ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 1);
                 
                 ret = mix_surfacepool_get_frame_with_ci_frameidx 
-                    (parent->surfacepool, &mix->ref_fame, frame);
+                    (parent->surfacepool, &mix->ref_frame, frame);
                 if (ret != MIX_RESULT_SUCCESS)  //#ifdef SLEEP_SURFACE not used
                 {
                     LOG_E( 
@@ -1084,12 +1084,12 @@
                 }
             }
             
-            if (mix->rec_fame == NULL)	
+            if (mix->rec_frame == NULL)	
             {
                 ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 2);        
                 
                 ret = mix_surfacepool_get_frame_with_ci_frameidx
-                    (parent->surfacepool, &mix->rec_fame, frame);
+                    (parent->surfacepool, &mix->rec_frame, frame);
 
                 if (ret != MIX_RESULT_SUCCESS)
                 {
@@ -1099,13 +1099,13 @@
                 }
             }
 
-            //mix_videoframe_unref (mix->cur_fame);
+            //mix_videoframe_unref (mix->cur_frame);
 
             if (parent->need_display) {
-                mix->cur_fame = NULL;		
+                mix->cur_frame = NULL;		
             }
             
-            if (mix->cur_fame == NULL)
+            if (mix->cur_frame == NULL)
             {
                 guint ci_idx;
                 memcpy (&ci_idx, bufin->data, bufin->size);
@@ -1125,7 +1125,7 @@
                 ret = mix_videoframe_set_ci_frame_idx (frame, ci_idx);        
                 
                 ret = mix_surfacepool_get_frame_with_ci_frameidx
-                    (parent->surfacepool, &mix->cur_fame, frame);
+                    (parent->surfacepool, &mix->cur_frame, frame);
 
                 if (ret != MIX_RESULT_SUCCESS)
                 {
@@ -1135,7 +1135,7 @@
                 }			
             }
             
-            ret = mix_videoframe_get_frame_id(mix->cur_fame, &surface);
+            ret = mix_videoframe_get_frame_id(mix->cur_frame, &surface);
             
         }
         
@@ -1156,7 +1156,14 @@
         	
 
         if (parent->need_display) {
-            ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_fame);	
+
+    		ret = mix_videoframe_set_sync_flag(mix->cur_frame, TRUE);
+    		if (ret != MIX_RESULT_SUCCESS) {
+    			LOG_E("Failed to set sync_flag\n");
+                return ret;
+    		}
+
+            ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_frame);	
             if (ret != MIX_RESULT_SUCCESS)
             {            
                 LOG_E( 
@@ -1167,8 +1174,8 @@
 
 
         if (!(parent->need_display)) {
-            mix_videoframe_unref (mix->cur_fame);
-            mix->cur_fame = NULL;
+            mix_videoframe_unref (mix->cur_frame);
+            mix->cur_frame = NULL;
         }
         
         mix->encoded_frames ++;
diff --git a/mix_video/src/mixvideoformatenc_preview.h b/mix_video/src/mixvideoformatenc_preview.h
index dd404e2..45ae101 100644
--- a/mix_video/src/mixvideoformatenc_preview.h
+++ b/mix_video/src/mixvideoformatenc_preview.h
@@ -42,9 +42,9 @@
 	VASurfaceID *   surfaces;
 	guint           surface_num;	
 
-	MixVideoFrame  *cur_fame;	//current input frame to be encoded;	
-	MixVideoFrame  *ref_fame;  //reference frame
-	MixVideoFrame  *rec_fame;	//reconstructed frame;	
+	MixVideoFrame  *cur_frame;	//current input frame to be encoded;	
+	MixVideoFrame  *ref_frame;  //reference frame
+	MixVideoFrame  *rec_frame;	//reconstructed frame;	
 
 	guint basic_unit_size;  //for rate control
 	guint disable_deblocking_filter_idc;
diff --git a/mix_video/src/mixvideoframe.c b/mix_video/src/mixvideoframe.c
index 2bea5d0..64d7831 100644
--- a/mix_video/src/mixvideoframe.c
+++ b/mix_video/src/mixvideoframe.c
@@ -8,9 +8,24 @@
 
 /**
  * SECTION:mixvideoframe
- * @short_description: VideoConfig parameters
- *
- * A data object which stores videoconfig specific parameters.
+ * @short_description: MI-X Video Frame Object 
+ * 
+ * <para>
+ * The MixVideoFrame object will be created by 
+ * MixVideo and provided to the MMF/App in the 
+ * MixVideo mix_video_get_frame() function.
+ * </para>
+ * <para> 
+ * mix_video_release_frame() must be used 
+ * to release frame object returned from 
+ * mix_video_get_frame(). Caller must not 
+ * use mix_videoframe_ref() or mix_videoframe_unref() 
+ * or adjust the reference count directly in any way. 
+ * This object can be supplied in the mix_video_render() 
+ * function to render the associated video frame. 
+ * The MMF/App can release this object when it no longer 
+ * needs to display/re-display this frame.
+ * </para> 
  */
 
 
@@ -41,7 +56,6 @@
 	self->frame_id = VA_INVALID_SURFACE;
 	self->timestamp = 0;
 	self->discontinuity = FALSE;
-	self->frame_structure = VA_FRAME_PICTURE;
 
 	MixVideoFramePrivate *priv = MIX_VIDEOFRAME_GET_PRIVATE(self);
 	self->reserved1 = priv;
@@ -55,9 +69,12 @@
 	/* set stuff for skipped frames */
 	priv -> is_skipped = FALSE;
 	priv -> real_frame = NULL;
+	priv -> sync_flag  = FALSE;
+	priv -> frame_structure = VA_FRAME_PICTURE;
+
+	priv -> va_display = NULL;
 
 	g_static_rec_mutex_init (&priv -> lock);
-
 }
 
 static void mix_videoframe_class_init(MixVideoFrameClass * klass) {
@@ -137,6 +154,8 @@
 			g_static_rec_mutex_unlock (&priv->lock);
 			return;
 		}
+
+		mix_videoframe_reset(obj);
 		mix_surfacepool_put(pool, obj);
 	}
 
@@ -198,7 +217,6 @@
 		this_target->frame_id = this_src->frame_id;
 		this_target->timestamp = this_src->timestamp;
 		this_target->discontinuity = this_src->discontinuity;
-		this_target->frame_structure = this_src->frame_structure;
 
 		// Now chainup base class
 		if (parent_class->copy) {
@@ -233,8 +251,7 @@
 		/* TODO: add comparison for other properties */
 		if (this_first->frame_id == this_second->frame_id
 				&& this_first->timestamp == this_second->timestamp
-				&& this_first->discontinuity == this_second->discontinuity 
-				&& this_first->frame_structure == this_second->frame_structure) {
+				&& this_first->discontinuity == this_second->discontinuity) {
 			// members within this scope equal. chaining up.
 			MixParamsClass *klass = MIX_PARAMS_CLASS(parent_class);
 			if (klass->equal)
@@ -315,14 +332,16 @@
 MIX_RESULT mix_videoframe_set_frame_structure(MixVideoFrame * obj,
 		guint32 frame_structure) {
 	MIX_VIDEOFRAME_SETTER_CHECK_INPUT (obj);
-	obj->frame_structure = frame_structure;
+	MixVideoFramePrivate *priv = VIDEOFRAME_PRIVATE(obj);
+	priv->frame_structure = frame_structure;
 	return MIX_RESULT_SUCCESS;
 }
 
 MIX_RESULT mix_videoframe_get_frame_structure(MixVideoFrame * obj,
 		guint32* frame_structure) {
 	MIX_VIDEOFRAME_GETTER_CHECK_INPUT (obj, frame_structure);
-	*frame_structure = obj->frame_structure;
+	MixVideoFramePrivate *priv = VIDEOFRAME_PRIVATE(obj);
+	*frame_structure = priv->frame_structure;
 	return MIX_RESULT_SUCCESS;
 }
 
@@ -356,6 +375,7 @@
 MIX_RESULT mix_videoframe_set_is_skipped(MixVideoFrame *obj,
 		gboolean is_skipped) {
 
+	MIX_VIDEOFRAME_SETTER_CHECK_INPUT (obj);
 	VIDEOFRAME_PRIVATE(obj) -> is_skipped = is_skipped;
 
 	return MIX_RESULT_SUCCESS;
@@ -374,6 +394,7 @@
 MIX_RESULT mix_videoframe_set_real_frame(MixVideoFrame *obj,
 		MixVideoFrame *real) {
 
+	MIX_VIDEOFRAME_SETTER_CHECK_INPUT (obj);
 	VIDEOFRAME_PRIVATE(obj) -> real_frame = real;
 
 	return MIX_RESULT_SUCCESS;
@@ -389,3 +410,70 @@
 	return MIX_RESULT_SUCCESS;
 }
 
+MIX_RESULT mix_videoframe_reset(MixVideoFrame *obj) {
+
+	MIX_VIDEOFRAME_SETTER_CHECK_INPUT (obj);
+	MixVideoFramePrivate *priv = VIDEOFRAME_PRIVATE(obj);
+
+	obj->timestamp = 0;
+	obj->discontinuity = FALSE;
+
+	priv -> is_skipped = FALSE;
+	priv -> real_frame = NULL;
+	priv -> sync_flag  = FALSE;
+	priv -> frame_structure = VA_FRAME_PICTURE;
+
+	return MIX_RESULT_SUCCESS;
+}
+
+
+MIX_RESULT mix_videoframe_set_sync_flag(MixVideoFrame *obj, gboolean sync_flag) {
+	MIX_VIDEOFRAME_SETTER_CHECK_INPUT (obj);
+	MixVideoFramePrivate *priv = VIDEOFRAME_PRIVATE(obj);
+
+	priv -> sync_flag = sync_flag;
+	if (priv->real_frame && priv->real_frame != obj) {
+		mix_videoframe_set_sync_flag(priv->real_frame, sync_flag);
+	}
+
+	return MIX_RESULT_SUCCESS;
+}
+
+MIX_RESULT mix_videoframe_get_sync_flag(MixVideoFrame *obj, gboolean *sync_flag) {
+	MIX_VIDEOFRAME_GETTER_CHECK_INPUT(obj, sync_flag);
+	MixVideoFramePrivate *priv = VIDEOFRAME_PRIVATE(obj);
+	if (priv->real_frame && priv->real_frame != obj) {
+		return mix_videoframe_get_sync_flag(priv->real_frame, sync_flag);
+	} else {
+		*sync_flag = priv -> sync_flag;
+	}
+	return MIX_RESULT_SUCCESS;
+}
+
+MIX_RESULT mix_videoframe_set_vadisplay(MixVideoFrame * obj, void *va_display) {
+
+	MIX_VIDEOFRAME_SETTER_CHECK_INPUT (obj);
+	MixVideoFramePrivate *priv = VIDEOFRAME_PRIVATE(obj);
+
+	priv -> va_display = va_display;
+        if (priv->real_frame && priv->real_frame != obj) {
+                mix_videoframe_set_vadisplay(priv->real_frame, va_display);
+        }
+
+	return MIX_RESULT_SUCCESS;
+}
+
+MIX_RESULT mix_videoframe_get_vadisplay(MixVideoFrame * obj, void **va_display) {
+
+        MIX_VIDEOFRAME_GETTER_CHECK_INPUT(obj, va_display);
+        MixVideoFramePrivate *priv = VIDEOFRAME_PRIVATE(obj);
+
+        if (priv->real_frame && priv->real_frame != obj) {
+                return mix_videoframe_get_vadisplay(priv->real_frame, va_display);
+        } else {
+                *va_display = priv -> va_display;
+        }
+
+	return MIX_RESULT_SUCCESS;
+}
+
diff --git a/mix_video/src/mixvideoframe.h b/mix_video/src/mixvideoframe.h
index 02338dd..1178d25 100644
--- a/mix_video/src/mixvideoframe.h
+++ b/mix_video/src/mixvideoframe.h
@@ -68,15 +68,36 @@
 	MixParams parent;
 
 	/*< public > */
+	
+	/* ID associated with the decoded frame */
 	gulong frame_id;
+	
+	/* ID associated with the CI frame 
+	 * (used for encode only) */	
 	guint ci_frame_idx;	
+	
+	/* 64 bit timestamp. For decode, 
+	 * this is preserved from the corresponding 
+	 * MixVideoDecodeParams field. For encode, 
+	 * this is created during encoding. */
 	guint64 timestamp;
+	
+	/* Flag indicating whether there 
+	 * is a discontinuity. For decode, 
+	 * this is preserved from the corresponding 
+	 * MixVideoDecodeParams field. */
 	gboolean discontinuity;
-	guint32 frame_structure; // 0: frame, 1: top field, 2: bottom field
 
+	/* Reserved for future use */ 
 	void *reserved1;
+	
+	/* Reserved for future use */ 
 	void *reserved2;
+	
+	/* Reserved for future use */ 
 	void *reserved3;
+	
+	/* Reserved for future use */ 
 	void *reserved4;
 };
 
@@ -110,7 +131,7 @@
 /**
  * mix_videoframe_ref:
  * @mix: object to add reference
- * @returns: the MixVideoFrame instance where reference count has been increased.
+ * @returns: the #MixVideoFrame instance where reference count has been increased.
  *
  * Add reference count.
  */
@@ -126,19 +147,91 @@
 
 /* Class Methods */
 
+/**
+ * mix_videoframe_set_frame_id:
+ * @obj: #MixVideoFrame object
+ * @frame_id: ID associated with the decoded frame  
+ * @returns: <link linkend="MixVideo-mixvideodef">Common Video Error Return Codes</link>
+ *
+ * Set Frame ID 
+ */
 MIX_RESULT mix_videoframe_set_frame_id(MixVideoFrame * obj, gulong frame_id);
+
+/**
+ * mix_videoframe_get_frame_id:
+ * @obj: #MixVideoFrame object
+ * @frame_id: frame ID to be returned   
+ * @returns: <link linkend="MixVideo-mixvideodef">Common Video Error Return Codes</link>
+ *
+ * Get Frame ID 
+ */
 MIX_RESULT mix_videoframe_get_frame_id(MixVideoFrame * obj, gulong * frame_id);
 
+/**
+ * mix_videoframe_set_ci_frame_idx:
+ * @obj: #MixVideoFrame object
+ * @ci_frame_idx: ID associated with the CI frame (used for encode only)   
+ * @returns: <link linkend="MixVideo-mixvideodef">Common Video Error Return Codes</link>
+ *
+ * Set CI Frame ID 
+ */
 MIX_RESULT mix_videoframe_set_ci_frame_idx(MixVideoFrame * obj, guint ci_frame_idx);
+
+/**
+ * mix_videoframe_get_ci_frame_idx:
+ * @obj: #MixVideoFrame object
+ * @ci_frame_idx: CI Frame ID to be returned   
+ * @returns: <link linkend="MixVideo-mixvideodef">Common Video Error Return Codes</link>
+ *
+ * Get CI Frame ID 
+ */
 MIX_RESULT mix_videoframe_get_ci_frame_idx(MixVideoFrame * obj, guint * ci_frame_idx);
 
+/**
+ * mix_videoframe_set_timestamp:
+ * @obj: #MixVideoFrame object
+ * @timestamp: Frame timestamp   
+ * @returns: <link linkend="MixVideo-mixvideodef">Common Video Error Return Codes</link>
+ *
+ * Set Frame timestamp 
+ */
 MIX_RESULT mix_videoframe_set_timestamp(MixVideoFrame * obj, guint64 timestamp);
+
+/**
+ * mix_videoframe_get_timestamp:
+ * @obj: #MixVideoFrame object
+ * @timestamp: Frame timestamp to be returned   
+ * @returns: <link linkend="MixVideo-mixvideodef">Common Video Error Return Codes</link>
+ *
+ * Get Frame timestamp 
+ */
 MIX_RESULT mix_videoframe_get_timestamp(MixVideoFrame * obj, guint64 * timestamp);
 
+/**
+ * mix_videoframe_set_discontinuity:
+ * @obj: #MixVideoFrame object
+ * @discontinuity: Discontinuity flag   
+ * @returns: <link linkend="MixVideo-mixvideodef">Common Video Error Return Codes</link>
+ *
+ * Get discontinuity flag 
+ */
 MIX_RESULT mix_videoframe_set_discontinuity(MixVideoFrame * obj, gboolean discontinuity);
+
+/**
+ * mix_videoframe_get_discontinuity:
+ * @obj: #MixVideoFrame object
+ * @discontinuity: Discontinuity flag to be returned  
+ * @returns: <link linkend="MixVideo-mixvideodef">Common Video Error Return Codes</link>
+ *
+ * Get discontinuity flag 
+ */
 MIX_RESULT mix_videoframe_get_discontinuity(MixVideoFrame * obj, gboolean * discontinuity);
 
-MIX_RESULT mix_videoframe_set_frame_structure(MixVideoFrame * obj, guint32 frame_structure);
-MIX_RESULT mix_videoframe_get_frame_structure(MixVideoFrame * obj, guint32* frame_structure);
+/**
+ * TODO: Add document the following 2 functions
+ *
+ */
+MIX_RESULT mix_videoframe_set_vadisplay(MixVideoFrame * obj, void *va_display);
+MIX_RESULT mix_videoframe_get_vadisplay(MixVideoFrame * obj, void **va_display);
 
 #endif /* __MIX_VIDEOFRAME_H__ */
diff --git a/mix_video/src/mixvideoframe_private.h b/mix_video/src/mixvideoframe_private.h
index 5d4b894..d49fe38 100644
--- a/mix_video/src/mixvideoframe_private.h
+++ b/mix_video/src/mixvideoframe_private.h
@@ -30,6 +30,9 @@
   gboolean is_skipped;
   MixVideoFrame *real_frame;
   GStaticRecMutex lock;
+  gboolean sync_flag;
+  guint32 frame_structure; // 0: frame, 1: top field, 2: bottom field
+  void *va_display;	
 };
 
 /**
@@ -64,5 +67,20 @@
 MIX_RESULT
 mix_videoframe_get_real_frame (MixVideoFrame *obj,  MixVideoFrame **real);
 
+MIX_RESULT
+mix_videoframe_reset(MixVideoFrame *obj);
+
+MIX_RESULT
+mix_videoframe_set_sync_flag(MixVideoFrame *obj, gboolean sync_flag);
+
+MIX_RESULT
+mix_videoframe_get_sync_flag(MixVideoFrame *obj, gboolean *sync_flag);
+
+MIX_RESULT 
+mix_videoframe_set_frame_structure(MixVideoFrame * obj, guint32 frame_structure);
+
+MIX_RESULT 
+mix_videoframe_get_frame_structure(MixVideoFrame * obj, guint32* frame_structure);
+
 
 #endif /* __MIX_VIDEOFRAME_PRIVATE_H__ */
diff --git a/mix_video/src/mixvideorenderparams.c b/mix_video/src/mixvideorenderparams.c
index 0dc8be7..12a711c 100644
--- a/mix_video/src/mixvideorenderparams.c
+++ b/mix_video/src/mixvideorenderparams.c
@@ -260,7 +260,7 @@
 
 	/* dup */
 	if (display) {
-		obj->display = mix_display_dup(display);
+		obj->display = mix_display_ref(display);
 	}
 
 	return MIX_RESULT_SUCCESS;
@@ -273,7 +273,7 @@
 
 	/* dup? */
 	if (obj->display) {
-		*display = mix_display_dup(obj->display);
+		*display = mix_display_ref(obj->display);
 	}
 
 	return MIX_RESULT_SUCCESS;