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;