Fixed memory leak in H.264 encoder.
Change-Id: I808dc7b68f1e83679c2cfd2b05caff037e190a5e
diff --git a/mix_video/src/mixvideoformatenc_h264.c b/mix_video/src/mixvideoformatenc_h264.c
index 32e1bdb..db532e4 100644
--- a/mix_video/src/mixvideoformatenc_h264.c
+++ b/mix_video/src/mixvideoformatenc_h264.c
@@ -45,6 +45,7 @@
self->cur_frame = NULL;
self->ref_frame = NULL;
self->rec_frame = NULL;
+ self->lookup_frame = NULL;
#ifdef ANDROID
self->last_mix_buffer = NULL;
#endif
@@ -64,7 +65,7 @@
GObjectClass *gobject_class = (GObjectClass *) klass;
/* direct parent class */
- MixVideoFormatEncClass *video_formatenc_class =
+ MixVideoFormatEncClass *video_formatenc_class =
MIX_VIDEOFORMATENC_CLASS(klass);
/* parent class for later use */
@@ -117,10 +118,10 @@
LOG_V( "mix_videofmtenc_h264_getcaps\n");
if (mix == NULL) {
- LOG_E( "mix == NULL\n");
- return MIX_RESULT_NULL_PTR;
+ LOG_E( "mix == NULL\n");
+ return MIX_RESULT_NULL_PTR;
}
-
+
if (parent_class->getcaps) {
return parent_class->getcaps(mix, msg);
@@ -128,7 +129,7 @@
return MIX_RESULT_SUCCESS;
}
-MIX_RESULT mix_videofmtenc_h264_initialize(MixVideoFormatEnc *mix,
+MIX_RESULT mix_videofmtenc_h264_initialize(MixVideoFormatEnc *mix,
MixVideoConfigParamsEnc * config_params_enc,
MixFrameManager * frame_mgr,
MixBufferPool * input_buf_pool,
@@ -138,624 +139,624 @@
MIX_RESULT ret = MIX_RESULT_SUCCESS;
MixVideoFormatEnc *parent = NULL;
MixVideoConfigParamsEncH264 * config_params_enc_h264;
-
+
VAStatus va_status = VA_STATUS_SUCCESS;
VASurfaceID * surfaces = NULL;
-
+
gint va_max_num_profiles, va_max_num_entrypoints, va_max_num_attribs;
gint va_num_profiles, va_num_entrypoints;
VAProfile *va_profiles = NULL;
VAEntrypoint *va_entrypoints = NULL;
- VAConfigAttrib va_attrib[2];
- guint index;
-
+ VAConfigAttrib va_attrib[2];
+ guint index;
+
/*frame_mgr and input_buf_pool is reservered for future use*/
-
+
if (mix == NULL || config_params_enc == NULL || va_display == NULL) {
- LOG_E(
- "mix == NULL || config_params_enc == NULL || va_display == NULL\n");
+ LOG_E(
+ "mix == NULL || config_params_enc == NULL || va_display == NULL\n");
return MIX_RESULT_NULL_PTR;
}
LOG_V( "begin\n");
-
+
/* Chainup parent method. */
if (parent_class->initialize) {
ret = parent_class->initialize(mix, config_params_enc,
- frame_mgr, input_buf_pool, surface_pool,
+ frame_mgr, input_buf_pool, surface_pool,
va_display);
}
-
+
if (ret != MIX_RESULT_SUCCESS)
{
return ret;
}
-
+
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
return MIX_RESULT_INVALID_PARAM;
-
+
parent = MIX_VIDEOFORMATENC(&(mix->parent));
MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
-
+
if (MIX_IS_VIDEOCONFIGPARAMSENC_H264 (config_params_enc)) {
- config_params_enc_h264 =
+ config_params_enc_h264 =
MIX_VIDEOCONFIGPARAMSENC_H264 (config_params_enc);
} else {
- LOG_V(
+ LOG_V(
"mix_videofmtenc_h264_initialize: no h264 config params found\n");
return MIX_RESULT_FAIL;
}
-
- g_mutex_lock(parent->objectlock);
-
- LOG_V(
+
+ g_mutex_lock(parent->objectlock);
+
+ LOG_V(
"Start to get properities from h.264 params\n");
-
+
/* get properties from H264 params Object, which is special to H264 format*/
- ret = mix_videoconfigparamsenc_h264_get_bus (config_params_enc_h264,
+ ret = mix_videoconfigparamsenc_h264_get_bus (config_params_enc_h264,
&self->basic_unit_size);
-
+
if (ret != MIX_RESULT_SUCCESS) {
- LOG_E(
- "Failed to mix_videoconfigparamsenc_h264_get_bus\n");
+ LOG_E(
+ "Failed to mix_videoconfigparamsenc_h264_get_bus\n");
goto cleanup;
- }
-
-
+ }
+
+
ret = mix_videoconfigparamsenc_h264_get_dlk (config_params_enc_h264,
&self->disable_deblocking_filter_idc);
-
+
if (ret != MIX_RESULT_SUCCESS) {
- LOG_E(
- "Failed to mix_videoconfigparamsenc_h264_get_dlk\n");
+ LOG_E(
+ "Failed to mix_videoconfigparamsenc_h264_get_dlk\n");
goto cleanup;
- }
-
-
+ }
+
+
ret = mix_videoconfigparamsenc_h264_get_slice_num (config_params_enc_h264,
&self->slice_num);
-
+
if (ret != MIX_RESULT_SUCCESS) {
- LOG_E(
- "Failed to mix_videoconfigparamsenc_h264_get_slice_num\n");
+ LOG_E(
+ "Failed to mix_videoconfigparamsenc_h264_get_slice_num\n");
goto cleanup;
- }
-
+ }
+
ret = mix_videoconfigparamsenc_h264_get_delimiter_type (config_params_enc_h264,
&self->delimiter_type);
-
+
if (ret != MIX_RESULT_SUCCESS) {
- LOG_E (
- "Failed to mix_videoconfigparamsenc_h264_get_delimiter_type\n");
+ LOG_E (
+ "Failed to mix_videoconfigparamsenc_h264_get_delimiter_type\n");
goto cleanup;
- }
+ }
ret = mix_videoconfigparamsenc_h264_get_IDR_interval(config_params_enc_h264,
&self->idr_interval);
-
+
if (ret != MIX_RESULT_SUCCESS) {
- LOG_E (
- "Failed to mix_videoconfigparamsenc_h264_get_IDR_interval\n");
+ LOG_E (
+ "Failed to mix_videoconfigparamsenc_h264_get_IDR_interval\n");
goto cleanup;
- }
-
- LOG_V(
+ }
+
+ LOG_V(
"======H264 Encode Object properities======:\n");
-
- LOG_I( "self->basic_unit_size = %d\n",
- self->basic_unit_size);
- LOG_I( "self->disable_deblocking_filter_idc = %d\n",
- self->disable_deblocking_filter_idc);
- LOG_I( "self->slice_num = %d\n",
- self->slice_num);
- LOG_I ("self->delimiter_type = %d\n",
- self->delimiter_type);
- LOG_I ("self->idr_interval = %d\n",
- self->idr_interval);
-
- LOG_V(
+
+ LOG_I( "self->basic_unit_size = %d\n",
+ self->basic_unit_size);
+ LOG_I( "self->disable_deblocking_filter_idc = %d\n",
+ self->disable_deblocking_filter_idc);
+ LOG_I( "self->slice_num = %d\n",
+ self->slice_num);
+ LOG_I ("self->delimiter_type = %d\n",
+ self->delimiter_type);
+ LOG_I ("self->idr_interval = %d\n",
+ self->idr_interval);
+
+ LOG_V(
"Get properities from params done\n");
- parent->va_display = va_display;
-
+ parent->va_display = va_display;
+
LOG_V( "Get Display\n");
- LOG_I( "Display = 0x%08x\n",
- (guint)va_display);
-
-
+ LOG_I( "Display = 0x%08x\n",
+ (guint)va_display);
+
+
#if 0
/* query the vender information, can ignore*/
va_vendor = vaQueryVendorString (va_display);
- LOG_I( "Vendor = %s\n",
- va_vendor);
-#endif
-
+ LOG_I( "Vendor = %s\n",
+ va_vendor);
+#endif
+
/*get the max number for profiles/entrypoints/attribs*/
va_max_num_profiles = vaMaxNumProfiles(va_display);
- LOG_I( "va_max_num_profiles = %d\n",
- va_max_num_profiles);
-
+ LOG_I( "va_max_num_profiles = %d\n",
+ va_max_num_profiles);
+
va_max_num_entrypoints = vaMaxNumEntrypoints(va_display);
- LOG_I( "va_max_num_entrypoints = %d\n",
- va_max_num_entrypoints);
-
+ LOG_I( "va_max_num_entrypoints = %d\n",
+ va_max_num_entrypoints);
+
va_max_num_attribs = vaMaxNumConfigAttributes(va_display);
- LOG_I( "va_max_num_attribs = %d\n",
- va_max_num_attribs);
-
+ LOG_I( "va_max_num_attribs = %d\n",
+ va_max_num_attribs);
+
va_profiles = g_malloc(sizeof(VAProfile)*va_max_num_profiles);
- va_entrypoints = g_malloc(sizeof(VAEntrypoint)*va_max_num_entrypoints);
-
- if (va_profiles == NULL || va_entrypoints ==NULL)
+ va_entrypoints = g_malloc(sizeof(VAEntrypoint)*va_max_num_entrypoints);
+
+ if (va_profiles == NULL || va_entrypoints ==NULL)
{
- LOG_E(
- "!va_profiles || !va_entrypoints\n");
+ LOG_E(
+ "!va_profiles || !va_entrypoints\n");
ret = MIX_RESULT_NO_MEMORY;
- goto cleanup;
+ goto cleanup;
}
-
- LOG_I(
- "va_profiles = 0x%08x\n", (guint)va_profiles);
-
+
+ LOG_I(
+ "va_profiles = 0x%08x\n", (guint)va_profiles);
+
LOG_V( "vaQueryConfigProfiles\n");
-
-
+
+
va_status = vaQueryConfigProfiles (va_display, va_profiles, &va_num_profiles);
-
- if (va_status != VA_STATUS_SUCCESS)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to call vaQueryConfigProfiles\n");
-
+ LOG_E(
+ "Failed to call vaQueryConfigProfiles\n");
+
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
LOG_V( "vaQueryConfigProfiles Done\n");
-
-
-
+
+
+
/*check whether profile is supported*/
for(index= 0; index < va_num_profiles; index++) {
if(parent->va_profile == va_profiles[index])
break;
}
-
- if(index == va_num_profiles)
+
+ if(index == va_num_profiles)
{
- LOG_E( "Profile not supported\n");
+ LOG_E( "Profile not supported\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
LOG_V( "vaQueryConfigEntrypoints\n");
-
-
+
+
/*Check entry point*/
- va_status = vaQueryConfigEntrypoints(va_display,
- parent->va_profile,
+ va_status = vaQueryConfigEntrypoints(va_display,
+ parent->va_profile,
va_entrypoints, &va_num_entrypoints);
-
- if (va_status != VA_STATUS_SUCCESS)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to call vaQueryConfigEntrypoints\n");
+ LOG_E(
+ "Failed to call vaQueryConfigEntrypoints\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
for (index = 0; index < va_num_entrypoints; index ++) {
if (va_entrypoints[index] == VAEntrypointEncSlice) {
break;
}
}
-
+
if (index == va_num_entrypoints) {
- LOG_E( "Entrypoint not found\n");
+ LOG_E( "Entrypoint not found\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
- }
-
+ goto cleanup;
+ }
+
va_attrib[0].type = VAConfigAttribRTFormat;
va_attrib[1].type = VAConfigAttribRateControl;
-
+
LOG_V( "vaGetConfigAttributes\n");
-
- va_status = vaGetConfigAttributes(va_display, parent->va_profile,
+
+ va_status = vaGetConfigAttributes(va_display, parent->va_profile,
parent->va_entrypoint,
- &va_attrib[0], 2);
-
- if (va_status != VA_STATUS_SUCCESS)
+ &va_attrib[0], 2);
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to call vaGetConfigAttributes\n");
+ LOG_E(
+ "Failed to call vaGetConfigAttributes\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
if ((va_attrib[0].value & parent->va_format) == 0) {
- LOG_E( "Matched format not found\n");
+ LOG_E( "Matched format not found\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
- }
-
-
+ goto cleanup;
+ }
+
+
if ((va_attrib[1].value & parent->va_rcmode) == 0) {
- LOG_E( "RC mode not found\n");
+ LOG_E( "RC mode not found\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
va_attrib[0].value = parent->va_format; //VA_RT_FORMAT_YUV420;
- va_attrib[1].value = parent->va_rcmode;
-
+ va_attrib[1].value = parent->va_rcmode;
+
LOG_V( "======VA Configuration======\n");
-
- LOG_I( "profile = %d\n",
- parent->va_profile);
- LOG_I( "va_entrypoint = %d\n",
- parent->va_entrypoint);
- LOG_I( "va_attrib[0].type = %d\n",
- va_attrib[0].type);
- LOG_I( "va_attrib[1].type = %d\n",
- va_attrib[1].type);
- LOG_I( "va_attrib[0].value (Format) = %d\n",
- va_attrib[0].value);
- LOG_I( "va_attrib[1].value (RC mode) = %d\n",
- va_attrib[1].value);
-
+
+ LOG_I( "profile = %d\n",
+ parent->va_profile);
+ LOG_I( "va_entrypoint = %d\n",
+ parent->va_entrypoint);
+ LOG_I( "va_attrib[0].type = %d\n",
+ va_attrib[0].type);
+ LOG_I( "va_attrib[1].type = %d\n",
+ va_attrib[1].type);
+ LOG_I( "va_attrib[0].value (Format) = %d\n",
+ va_attrib[0].value);
+ LOG_I( "va_attrib[1].value (RC mode) = %d\n",
+ va_attrib[1].value);
+
LOG_V( "vaCreateConfig\n");
-
- va_status = vaCreateConfig(va_display, parent->va_profile,
- parent->va_entrypoint,
+
+ va_status = vaCreateConfig(va_display, parent->va_profile,
+ parent->va_entrypoint,
&va_attrib[0], 2, &(parent->va_config));
-
- if (va_status != VA_STATUS_SUCCESS)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E( "Failed vaCreateConfig\n");
+ LOG_E( "Failed vaCreateConfig\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
/*TODO: compute the surface number*/
int numSurfaces;
-
+
if (parent->share_buf_mode) {
numSurfaces = 2;
}
else {
numSurfaces = 8;
- parent->ci_frame_num = 0;
+ parent->ci_frame_num = 0;
}
-
+
self->surface_num = numSurfaces + parent->ci_frame_num;
-
+
surfaces = g_malloc(sizeof(VASurfaceID)*numSurfaces);
-
+
if (surfaces == NULL)
{
- LOG_E(
- "Failed allocate surface\n");
+ LOG_E(
+ "Failed allocate surface\n");
ret = MIX_RESULT_NO_MEMORY;
- goto cleanup;
+ goto cleanup;
}
-
+
LOG_V( "vaCreateSurfaces\n");
-
- va_status = vaCreateSurfaces(va_display, parent->picture_width,
+
+ va_status = vaCreateSurfaces(va_display, parent->picture_width,
parent->picture_height, parent->va_format,
numSurfaces, surfaces);
-
- if (va_status != VA_STATUS_SUCCESS)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed vaCreateSurfaces\n");
+ LOG_E(
+ "Failed vaCreateSurfaces\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
if (parent->share_buf_mode) {
-
- LOG_V(
- "We are in share buffer mode!\n");
- self->ci_shared_surfaces =
+
+ LOG_V(
+ "We are in share buffer mode!\n");
+ self->ci_shared_surfaces =
g_malloc(sizeof(VASurfaceID) * parent->ci_frame_num);
-
+
if (self->ci_shared_surfaces == NULL)
{
- LOG_E(
- "Failed allocate shared surface\n");
-
+ LOG_E(
+ "Failed allocate shared surface\n");
+
ret = MIX_RESULT_NO_MEMORY;
- goto cleanup;
+ goto cleanup;
}
-
+
guint index;
for(index = 0; index < parent->ci_frame_num; index++) {
-
- LOG_I( "ci_frame_id = %lu\n",
- parent->ci_frame_id[index]);
-
- LOG_V(
- "vaCreateSurfaceFromCIFrame\n");
-
- va_status = vaCreateSurfaceFromCIFrame(va_display,
- (gulong) (parent->ci_frame_id[index]),
+
+ LOG_I( "ci_frame_id = %lu\n",
+ parent->ci_frame_id[index]);
+
+ LOG_V(
+ "vaCreateSurfaceFromCIFrame\n");
+
+ va_status = vaCreateSurfaceFromCIFrame(va_display,
+ (gulong) (parent->ci_frame_id[index]),
&self->ci_shared_surfaces[index]);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaCreateSurfaceFromCIFrame\n");
+ LOG_E(
+ "Failed to vaCreateSurfaceFromCIFrame\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
- }
+ goto cleanup;
+ }
}
-
- LOG_V(
+
+ LOG_V(
"vaCreateSurfaceFromCIFrame Done\n");
-
+
}// if (parent->share_buf_mode)
-
+
self->surfaces = g_malloc(sizeof(VASurfaceID) * self->surface_num);
-
+
if (self->surfaces == NULL)
{
- LOG_E(
- "Failed allocate private surface\n");
+ LOG_E(
+ "Failed allocate private surface\n");
ret = MIX_RESULT_NO_MEMORY;
- goto cleanup;
- }
-
- if (parent->share_buf_mode) {
- /*shared surfaces should be put in pool first,
+ goto cleanup;
+ }
+
+ if (parent->share_buf_mode) {
+ /*shared surfaces should be put in pool first,
because we will get it accoring to CI index*/
for(index = 0; index < parent->ci_frame_num; index++)
self->surfaces[index] = self->ci_shared_surfaces[index];
}
-
+
for(index = 0; index < numSurfaces; index++) {
- self->surfaces[index + parent->ci_frame_num] = surfaces[index];
+ self->surfaces[index + parent->ci_frame_num] = surfaces[index];
}
-
- LOG_V( "assign surface Done\n");
- LOG_I( "Created %d libva surfaces\n",
- numSurfaces + parent->ci_frame_num);
-
+
+ LOG_V( "assign surface Done\n");
+ LOG_I( "Created %d libva surfaces\n",
+ numSurfaces + parent->ci_frame_num);
+
#if 0 //current put this in gst
- images = g_malloc(sizeof(VAImage)*numSurfaces);
+ images = g_malloc(sizeof(VAImage)*numSurfaces);
if (images == NULL)
{
- g_mutex_unlock(parent->objectlock);
+ g_mutex_unlock(parent->objectlock);
return MIX_RESULT_FAIL;
- }
-
- for (index = 0; index < numSurfaces; index++) {
- //Derive an VAImage from an existing surface.
+ }
+
+ for (index = 0; index < numSurfaces; index++) {
+ //Derive an VAImage from an existing surface.
//The image buffer can then be mapped/unmapped for CPU access
va_status = vaDeriveImage(va_display, surfaces[index],
&images[index]);
}
-#endif
-
- LOG_V( "mix_surfacepool_new\n");
-
+#endif
+
+ LOG_V( "mix_surfacepool_new\n");
+
parent->surfacepool = mix_surfacepool_new();
if (surface_pool)
- *surface_pool = parent->surfacepool;
+ *surface_pool = parent->surfacepool;
//which is useful to check before encode
if (parent->surfacepool == NULL)
{
- LOG_E(
+ LOG_E(
"Failed to mix_surfacepool_new\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
- LOG_V(
- "mix_surfacepool_initialize\n");
-
+
+ LOG_V(
+ "mix_surfacepool_initialize\n");
+
ret = mix_surfacepool_initialize(parent->surfacepool,
self->surfaces, parent->ci_frame_num + numSurfaces, va_display);
-
+
switch (ret)
{
case MIX_RESULT_SUCCESS:
break;
case MIX_RESULT_ALREADY_INIT:
- LOG_E( "Error init failure\n");
+ LOG_E( "Error init failure\n");
ret = MIX_RESULT_ALREADY_INIT;
- goto cleanup;
+ goto cleanup;
default:
break;
}
-
-
+
+
//Initialize and save the VA context ID
- LOG_V( "vaCreateContext\n");
-
+ LOG_V( "vaCreateContext\n");
+
va_status = vaCreateContext(va_display, parent->va_config,
parent->picture_width, parent->picture_height,
0, self->surfaces, parent->ci_frame_num + numSurfaces,
&(parent->va_context));
-
- LOG_I(
- "Created libva context width %d, height %d\n",
+
+ LOG_I(
+ "Created libva context width %d, height %d\n",
parent->picture_width, parent->picture_height);
-
- if (va_status != VA_STATUS_SUCCESS)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaCreateContext\n");
- LOG_I( "va_status = %d\n",
- (guint)va_status);
+ LOG_E(
+ "Failed to vaCreateContext\n");
+ LOG_I( "va_status = %d\n",
+ (guint)va_status);
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
guint max_size = 0;
ret = mix_videofmtenc_h264_get_max_encoded_buf_size (parent, &max_size);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
- "Failed to mix_videofmtenc_h264_get_max_encoded_buf_size\n");
- goto cleanup;
-
+ LOG_E(
+ "Failed to mix_videofmtenc_h264_get_max_encoded_buf_size\n");
+ goto cleanup;
+
}
-
+
/*Create coded buffer for output*/
va_status = vaCreateBuffer (va_display, parent->va_context,
VAEncCodedBufferType,
self->coded_buf_size, //
1, NULL,
&(self->coded_buf[0]));
-
- if (va_status != VA_STATUS_SUCCESS)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaCreateBuffer: VAEncCodedBufferType\n");
+ LOG_E(
+ "Failed to vaCreateBuffer: VAEncCodedBufferType\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
/*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)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaCreateBuffer: VAEncCodedBufferType\n");
+ LOG_E(
+ "Failed to vaCreateBuffer: VAEncCodedBufferType\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
+ goto cleanup;
}
-
+
#ifdef SHOW_SRC
Display * display = XOpenDisplay (NULL);
- LOG_I( "display = 0x%08x\n",
- (guint) display);
+ LOG_I( "display = 0x%08x\n",
+ (guint) display);
win = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0,
parent->picture_width, parent->picture_height, 0, 0,
WhitePixel(display, 0));
XMapWindow(display, win);
XSelectInput(display, win, KeyPressMask | StructureNotifyMask);
-
+
XSync(display, False);
- LOG_I( "va_display = 0x%08x\n",
- (guint) va_display);
-
-#endif /* SHOW_SRC */
-
+ LOG_I( "va_display = 0x%08x\n",
+ (guint) va_display);
+
+#endif /* SHOW_SRC */
+
cleanup:
-
-
+
+
if (ret == MIX_RESULT_SUCCESS) {
- parent->initialized = TRUE;
+ parent->initialized = TRUE;
}
-
+
/*free profiles and entrypoints*/
- if (va_profiles)
+ if (va_profiles)
g_free(va_profiles);
-
+
if (va_entrypoints)
- g_free (va_entrypoints);
-
- if (surfaces)
+ g_free (va_entrypoints);
+
+ if (surfaces)
g_free (surfaces);
-
- g_mutex_unlock(parent->objectlock);
-
- LOG_V( "end\n");
-
+
+ g_mutex_unlock(parent->objectlock);
+
+ LOG_V( "end\n");
+
return ret;
}
MIX_RESULT mix_videofmtenc_h264_encode(MixVideoFormatEnc *mix, MixBuffer * bufin[],
gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
MixVideoEncodeParams * encode_params) {
-
+
MIX_RESULT ret = MIX_RESULT_SUCCESS;
MixVideoFormatEnc *parent = NULL;
-
- LOG_V( "Begin\n");
-
+
+ LOG_V( "Begin\n");
+
/*currenly only support one input and output buffer*/
if (bufincnt != 1 || iovoutcnt != 1) {
- LOG_E(
- "buffer count not equel to 1\n");
- LOG_E(
- "maybe some exception occurs\n");
+ LOG_E(
+ "buffer count not equel to 1\n");
+ LOG_E(
+ "maybe some exception occurs\n");
}
-
+
if (mix == NULL ||bufin[0] == NULL || iovout[0] == NULL) {
- LOG_E(
- "!mix || !bufin[0] ||!iovout[0]\n");
+ LOG_E(
+ "!mix || !bufin[0] ||!iovout[0]\n");
return MIX_RESULT_NULL_PTR;
}
-
+
#if 0
if (parent_class->encode) {
return parent_class->encode(mix, bufin, bufincnt, iovout,
iovoutcnt, encode_params);
}
#endif
-
+
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
- return MIX_RESULT_INVALID_PARAM;
-
+ return MIX_RESULT_INVALID_PARAM;
+
parent = MIX_VIDEOFORMATENC(&(mix->parent));
MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264 (mix);
-
- LOG_V( "Locking\n");
+
+ LOG_V( "Locking\n");
g_mutex_lock(parent->objectlock);
-
+
//TODO: also we could move some encode Preparation work to here
-
- LOG_V(
- "mix_videofmtenc_h264_process_encode\n");
-
- ret = mix_videofmtenc_h264_process_encode (self,
+
+ LOG_V(
+ "mix_videofmtenc_h264_process_encode\n");
+
+ ret = mix_videofmtenc_h264_process_encode (self,
bufin[0], iovout[0]);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
- "Failed mix_videofmtenc_h264_process_encode\n");
+ LOG_E(
+ "Failed mix_videofmtenc_h264_process_encode\n");
goto cleanup;
}
-
-cleanup:
-
- LOG_V( "UnLocking\n");
-
+
+cleanup:
+
+ LOG_V( "UnLocking\n");
+
g_mutex_unlock(parent->objectlock);
-
- LOG_V( "end\n");
-
+
+ LOG_V( "end\n");
+
return ret;
}
MIX_RESULT mix_videofmtenc_h264_flush(MixVideoFormatEnc *mix) {
-
+
//MIX_RESULT ret = MIX_RESULT_SUCCESS;
-
- LOG_V( "Begin\n");
+
+ LOG_V( "Begin\n");
if (mix == NULL) {
- LOG_E( "mix == NULL\n");
- return MIX_RESULT_NULL_PTR;
- }
-
-
+ LOG_E( "mix == NULL\n");
+ return MIX_RESULT_NULL_PTR;
+ }
+
+
/*not chain to parent flush func*/
#if 0
if (parent_class->flush) {
@@ -765,59 +766,60 @@
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
return MIX_RESULT_INVALID_PARAM;
-
+
MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
-
+
g_mutex_lock(mix->objectlock);
-#if 0
- /*unref the current source surface*/
+#if 0
+ /*unref the current source surface*/
if (self->cur_frame != NULL)
{
mix_videoframe_unref (self->cur_frame);
self->cur_frame = NULL;
}
-#endif
-
- /*unref the reconstructed surface*/
+#endif
+
+ /*unref the reconstructed surface*/
if (self->rec_frame != NULL)
{
mix_videoframe_unref (self->rec_frame);
self->rec_frame = NULL;
}
- /*unref the reference surface*/
+ /*unref the reference surface*/
if (self->ref_frame != NULL)
{
mix_videoframe_unref (self->ref_frame);
- self->ref_frame = NULL;
+ self->ref_frame = NULL;
}
+
#ifdef ANDROID
if(self->last_mix_buffer) {
mix_buffer_unref(self->last_mix_buffer);
self->last_mix_buffer = NULL;
}
-#endif
- /*reset the properities*/
+#endif
+ /*reset the properities*/
self->encoded_frames = 0;
self->pic_skipped = FALSE;
self->is_intra = TRUE;
-
+
g_mutex_unlock(mix->objectlock);
-
- LOG_V( "end\n");
-
+
+ LOG_V( "end\n");
+
return MIX_RESULT_SUCCESS;
}
MIX_RESULT mix_videofmtenc_h264_eos(MixVideoFormatEnc *mix) {
-
- LOG_V( "\n");
+
+ LOG_V( "\n");
if (mix == NULL) {
- LOG_E( "mix == NULL\n");
- return MIX_RESULT_NULL_PTR;
- }
+ LOG_E( "mix == NULL\n");
+ return MIX_RESULT_NULL_PTR;
+ }
if (parent_class->eos) {
return parent_class->eos(mix);
@@ -826,21 +828,21 @@
}
MIX_RESULT mix_videofmtenc_h264_deinitialize(MixVideoFormatEnc *mix) {
-
+
MixVideoFormatEnc *parent = NULL;
VAStatus va_status;
- MIX_RESULT ret = MIX_RESULT_SUCCESS;
-
-
- LOG_V( "Begin\n");
+ MIX_RESULT ret = MIX_RESULT_SUCCESS;
+
+
+ LOG_V( "Begin\n");
if (mix == NULL) {
- LOG_E( "mix == NULL\n");
- return MIX_RESULT_NULL_PTR;
- }
+ LOG_E( "mix == NULL\n");
+ return MIX_RESULT_NULL_PTR;
+ }
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
- return MIX_RESULT_INVALID_PARAM;
+ return MIX_RESULT_INVALID_PARAM;
if (parent_class->deinitialize) {
ret = parent_class->deinitialize(mix);
@@ -849,39 +851,45 @@
if (ret != MIX_RESULT_SUCCESS)
{
return ret;
- }
+ }
parent = MIX_VIDEOFORMATENC(&(mix->parent));
- MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
-
- LOG_V( "Release frames\n");
+ MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
+
+ LOG_V( "Release frames\n");
g_mutex_lock(parent->objectlock);
#if 0
- /*unref the current source surface*/
+ /*unref the current source surface*/
if (self->cur_frame != NULL)
{
mix_videoframe_unref (self->cur_frame);
self->cur_frame = NULL;
}
-#endif
-
- /*unref the reconstructed surface*/
+#endif
+
+ /*unref the reconstructed surface*/
if (self->rec_frame != NULL)
{
mix_videoframe_unref (self->rec_frame);
self->rec_frame = NULL;
}
- /*unref the reference surface*/
+ /*unref the reference surface*/
if (self->ref_frame != NULL)
{
mix_videoframe_unref (self->ref_frame);
- self->ref_frame = NULL;
- }
+ self->ref_frame = NULL;
+ }
- LOG_V( "Release surfaces\n");
+ if (self->lookup_frame != NULL)
+ {
+ mix_videoframe_unref (self->lookup_frame);
+ self->lookup_frame = NULL;
+ }
+
+ LOG_V( "Release surfaces\n");
if (self->ci_shared_surfaces)
{
@@ -891,62 +899,62 @@
if (self->surfaces)
{
- g_free (self->surfaces);
+ g_free (self->surfaces);
self->surfaces = NULL;
- }
+ }
- LOG_V( "vaDestroyContext\n");
-
+ LOG_V( "vaDestroyContext\n");
+
va_status = vaDestroyContext (parent->va_display, parent->va_context);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed vaDestroyContext\n");
+ LOG_E(
+ "Failed vaDestroyContext\n");
ret = MIX_RESULT_FAIL;
goto cleanup;
- }
+ }
- LOG_V( "vaDestroyConfig\n");
-
- va_status = vaDestroyConfig (parent->va_display, parent->va_config);
- if (va_status != VA_STATUS_SUCCESS)
+ LOG_V( "vaDestroyConfig\n");
+
+ va_status = vaDestroyConfig (parent->va_display, parent->va_config);
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed vaDestroyConfig\n");
+ LOG_E(
+ "Failed vaDestroyConfig\n");
ret = MIX_RESULT_FAIL;
goto cleanup;
- }
+ }
cleanup:
parent->initialized = FALSE;
- g_mutex_unlock(parent->objectlock);
+ g_mutex_unlock(parent->objectlock);
- LOG_V( "end\n");
-
+ LOG_V( "end\n");
+
return ret;
}
MIX_RESULT mix_videofmtenc_h264_send_seq_params (MixVideoFormatEnc_H264 *mix)
{
-
+
VAStatus va_status;
VAEncSequenceParameterBufferH264 h264_seq_param;
-
+
MixVideoFormatEnc *parent = NULL;
-
+
if (mix == NULL) {
- LOG_E("mix == NULL\n");
+ LOG_E("mix == NULL\n");
return MIX_RESULT_NULL_PTR;
}
-
- LOG_V( "Begin\n\n");
-
+
+ LOG_V( "Begin\n\n");
+
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
return MIX_RESULT_INVALID_PARAM;
- parent = MIX_VIDEOFORMATENC(&(mix->parent));
-
+ parent = MIX_VIDEOFORMATENC(&(mix->parent));
+
/*set up the sequence params for HW*/
h264_seq_param.level_idc = 30; //TODO, hard code now
h264_seq_param.intra_period = parent->intra_period;
@@ -954,64 +962,64 @@
h264_seq_param.picture_width_in_mbs = parent->picture_width / 16;
h264_seq_param.picture_height_in_mbs = parent->picture_height/ 16;
h264_seq_param.bits_per_second = parent->bitrate;
- h264_seq_param.frame_rate =
+ h264_seq_param.frame_rate =
(unsigned int) (parent->frame_rate_num + parent->frame_rate_denom /2 ) / parent->frame_rate_denom;
h264_seq_param.initial_qp = parent->initial_qp;
h264_seq_param.min_qp = parent->min_qp;
h264_seq_param.basic_unit_size = mix->basic_unit_size; //for rate control usage
h264_seq_param.intra_period = parent->intra_period;
//h264_seq_param.vui_flag = 248;
- //h264_seq_param.seq_parameter_set_id = 176;
+ //h264_seq_param.seq_parameter_set_id = 176;
- LOG_V(
- "===h264 sequence params===\n");
-
- LOG_I( "seq_parameter_set_id = %d\n",
- (guint)h264_seq_param.seq_parameter_set_id);
- LOG_I( "level_idc = %d\n",
- (guint)h264_seq_param.level_idc);
- LOG_I( "intra_period = %d\n",
- h264_seq_param.intra_period);
- LOG_I( "idr_interval = %d\n",
- h264_seq_param.intra_idr_period);
- LOG_I( "picture_width_in_mbs = %d\n",
- h264_seq_param.picture_width_in_mbs);
- LOG_I( "picture_height_in_mbs = %d\n",
- h264_seq_param.picture_height_in_mbs);
- LOG_I( "bitrate = %d\n",
- h264_seq_param.bits_per_second);
- LOG_I( "frame_rate = %d\n",
- h264_seq_param.frame_rate);
- LOG_I( "initial_qp = %d\n",
- h264_seq_param.initial_qp);
- LOG_I( "min_qp = %d\n",
- h264_seq_param.min_qp);
- LOG_I( "basic_unit_size = %d\n",
- h264_seq_param.basic_unit_size);
- LOG_I( "vui_flag = %d\n\n",
- h264_seq_param.vui_flag);
-
+ LOG_V(
+ "===h264 sequence params===\n");
+
+ LOG_I( "seq_parameter_set_id = %d\n",
+ (guint)h264_seq_param.seq_parameter_set_id);
+ LOG_I( "level_idc = %d\n",
+ (guint)h264_seq_param.level_idc);
+ LOG_I( "intra_period = %d\n",
+ h264_seq_param.intra_period);
+ LOG_I( "idr_interval = %d\n",
+ h264_seq_param.intra_idr_period);
+ LOG_I( "picture_width_in_mbs = %d\n",
+ h264_seq_param.picture_width_in_mbs);
+ LOG_I( "picture_height_in_mbs = %d\n",
+ h264_seq_param.picture_height_in_mbs);
+ LOG_I( "bitrate = %d\n",
+ h264_seq_param.bits_per_second);
+ LOG_I( "frame_rate = %d\n",
+ h264_seq_param.frame_rate);
+ LOG_I( "initial_qp = %d\n",
+ h264_seq_param.initial_qp);
+ LOG_I( "min_qp = %d\n",
+ h264_seq_param.min_qp);
+ LOG_I( "basic_unit_size = %d\n",
+ h264_seq_param.basic_unit_size);
+ LOG_I( "vui_flag = %d\n\n",
+ h264_seq_param.vui_flag);
+
va_status = vaCreateBuffer(parent->va_display, parent->va_context,
VAEncSequenceParameterBufferType,
sizeof(h264_seq_param),
1, &h264_seq_param,
&mix->seq_param_buf);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaCreateBuffer\n");
+ LOG_E(
+ "Failed to vaCreateBuffer\n");
return MIX_RESULT_FAIL;
}
-
- va_status = vaRenderPicture(parent->va_display, parent->va_context,
+
+ va_status = vaRenderPicture(parent->va_display, parent->va_context,
&mix->seq_param_buf, 1);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaRenderPicture\n");
+ LOG_E(
+ "Failed to vaRenderPicture\n");
return MIX_RESULT_FAIL;
- }
-
+ }
+
return MIX_RESULT_SUCCESS;
}
@@ -1020,254 +1028,266 @@
VAStatus va_status;
VAEncPictureParameterBufferH264 h264_pic_param;
MixVideoFormatEnc *parent = NULL;
-
+
if (mix == NULL) {
- LOG_E("mix == NULL\n");
+ LOG_E("mix == NULL\n");
return MIX_RESULT_NULL_PTR;
}
-
- LOG_V( "Begin\n\n");
+
+ LOG_V( "Begin\n\n");
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
return MIX_RESULT_INVALID_PARAM;
-
+
parent = MIX_VIDEOFORMATENC(&(mix->parent));
-
+
/*set picture params for HW*/
- h264_pic_param.reference_picture = mix->ref_frame->frame_id;
+ 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;
-
-
- LOG_V(
- "======h264 picture params======\n");
- LOG_I( "reference_picture = 0x%08x\n",
- 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.last_picture = 0;
+
+
+ LOG_V(
+ "======h264 picture params======\n");
+ LOG_I( "reference_picture = 0x%08x\n",
+ 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);
- LOG_I( "picture_width = %d\n",
- h264_pic_param.picture_width);
- LOG_I( "picture_height = %d\n\n",
- h264_pic_param.picture_height);
-
+ LOG_I( "picture_width = %d\n",
+ h264_pic_param.picture_width);
+ LOG_I( "picture_height = %d\n\n",
+ h264_pic_param.picture_height);
+
va_status = vaCreateBuffer(parent->va_display, parent->va_context,
VAEncPictureParameterBufferType,
sizeof(h264_pic_param),
1,&h264_pic_param,
- &mix->pic_param_buf);
-
- if (va_status != VA_STATUS_SUCCESS)
+ &mix->pic_param_buf);
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaCreateBuffer\n");
+ LOG_E(
+ "Failed to vaCreateBuffer\n");
return MIX_RESULT_FAIL;
}
-
-
+
+
va_status = vaRenderPicture(parent->va_display, parent->va_context,
- &mix->pic_param_buf, 1);
-
- if (va_status != VA_STATUS_SUCCESS)
+ &mix->pic_param_buf, 1);
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaRenderPicture\n");
+ LOG_E(
+ "Failed to vaRenderPicture\n");
return MIX_RESULT_FAIL;
- }
-
- LOG_V( "end\n");
- return MIX_RESULT_SUCCESS;
-
+ }
+
+ LOG_V( "end\n");
+ return MIX_RESULT_SUCCESS;
+
}
MIX_RESULT mix_videofmtenc_h264_send_slice_parameter (MixVideoFormatEnc_H264 *mix)
{
VAStatus va_status;
-
+
guint slice_num;
guint slice_height;
guint slice_index;
guint slice_height_in_mb;
-
+
if (mix == NULL) {
- LOG_E("mix == NULL\n");
+ LOG_E("mix == NULL\n");
return MIX_RESULT_NULL_PTR;
}
-
- LOG_V( "Begin\n\n");
-
-
- MixVideoFormatEnc *parent = NULL;
-
+
+ LOG_V( "Begin\n\n");
+
+
+ MixVideoFormatEnc *parent = NULL;
+
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
return MIX_RESULT_INVALID_PARAM;
-
- parent = MIX_VIDEOFORMATENC(&(mix->parent));
-
+
+ parent = MIX_VIDEOFORMATENC(&(mix->parent));
+
slice_num = mix->slice_num;
- slice_height = parent->picture_height / slice_num;
-
+ slice_height = parent->picture_height / slice_num;
+
slice_height += 15;
slice_height &= (~15);
slice_num = mix->slice_num = (parent->picture_height + 15) / slice_height;
-#if 1
- va_status = vaCreateBuffer (parent->va_display, parent->va_context,
+#if 0
+ if (!mix->is_intra){
+ slice_num = 9;
+
+ slice_height = parent->picture_height / slice_num;
+
+ slice_height += 15;
+ slice_height &= (~15);
+
+ }
+#endif
+
+#if 1
+ va_status = vaCreateBuffer (parent->va_display, parent->va_context,
VAEncSliceParameterBufferType,
sizeof(VAEncSliceParameterBuffer),
slice_num, NULL,
- &mix->slice_param_buf);
-
- if (va_status != VA_STATUS_SUCCESS)
+ &mix->slice_param_buf);
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaCreateBuffer\n");
+ LOG_E(
+ "Failed to vaCreateBuffer\n");
return MIX_RESULT_FAIL;
}
-
+
VAEncSliceParameterBuffer *slice_param, *current_slice;
va_status = vaMapBuffer(parent->va_display,
mix->slice_param_buf,
- (void **)&slice_param);
-
- if (va_status != VA_STATUS_SUCCESS)
+ (void **)&slice_param);
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaMapBuffer\n");
+ LOG_E(
+ "Failed to vaMapBuffer\n");
return MIX_RESULT_FAIL;
- }
-
+ }
+
current_slice = slice_param;
-
+
for (slice_index = 0; slice_index < slice_num; slice_index++) {
current_slice = slice_param + slice_index;
- slice_height_in_mb =
- min (slice_height, parent->picture_height
+ slice_height_in_mb =
+ min (slice_height, parent->picture_height
- slice_index * slice_height) / 16;
-
+
// starting MB row number for this slice
- current_slice->start_row_number = slice_index * slice_height / 16;
+ current_slice->start_row_number = slice_index * slice_height / 16;
// slice height measured in MB
- current_slice->slice_height = slice_height_in_mb;
- current_slice->slice_flags.bits.is_intra = mix->is_intra;
- current_slice->slice_flags.bits.disable_deblocking_filter_idc
+ current_slice->slice_height = slice_height_in_mb;
+ current_slice->slice_flags.bits.is_intra = mix->is_intra;
+ current_slice->slice_flags.bits.disable_deblocking_filter_idc
= mix->disable_deblocking_filter_idc;
-
- LOG_V(
- "======h264 slice params======\n");
-
- LOG_I( "slice_index = %d\n",
- (gint) slice_index);
- LOG_I( "start_row_number = %d\n",
- (gint) current_slice->start_row_number);
- LOG_I( "slice_height_in_mb = %d\n",
- (gint) current_slice->slice_height);
- LOG_I( "slice.is_intra = %d\n",
- (gint) current_slice->slice_flags.bits.is_intra);
- LOG_I(
- "disable_deblocking_filter_idc = %d\n\n",
- (gint) mix->disable_deblocking_filter_idc);
-
+
+ LOG_V(
+ "======h264 slice params======\n");
+
+ LOG_I( "slice_index = %d\n",
+ (gint) slice_index);
+ LOG_I( "start_row_number = %d\n",
+ (gint) current_slice->start_row_number);
+ LOG_I( "slice_height_in_mb = %d\n",
+ (gint) current_slice->slice_height);
+ LOG_I( "slice.is_intra = %d\n",
+ (gint) current_slice->slice_flags.bits.is_intra);
+ LOG_I(
+ "disable_deblocking_filter_idc = %d\n\n",
+ (gint) mix->disable_deblocking_filter_idc);
+
}
-
+
va_status = vaUnmapBuffer(parent->va_display, mix->slice_param_buf);
-
- if (va_status != VA_STATUS_SUCCESS)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaUnmapBuffer\n");
+ LOG_E(
+ "Failed to vaUnmapBuffer\n");
return MIX_RESULT_FAIL;
- }
-#endif
+ }
+#endif
#if 0
VAEncSliceParameterBuffer slice_param;
slice_index = 0;
slice_height_in_mb = slice_height / 16;
- slice_param.start_row_number = 0;
- slice_param.slice_height = slice_height / 16;
- slice_param.slice_flags.bits.is_intra = mix->is_intra;
+ slice_param.start_row_number = 0;
+ slice_param.slice_height = slice_height / 16;
+ slice_param.slice_flags.bits.is_intra = mix->is_intra;
slice_param.slice_flags.bits.disable_deblocking_filter_idc
= mix->disable_deblocking_filter_idc;
- va_status = vaCreateBuffer (parent->va_display, parent->va_context,
+ va_status = vaCreateBuffer (parent->va_display, parent->va_context,
VAEncSliceParameterBufferType,
sizeof(slice_param),
slice_num, &slice_param,
- &mix->slice_param_buf);
-
- if (va_status != VA_STATUS_SUCCESS)
+ &mix->slice_param_buf);
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaCreateBuffer\n");
+ LOG_E(
+ "Failed to vaCreateBuffer\n");
return MIX_RESULT_FAIL;
- }
+ }
#endif
-
+
va_status = vaRenderPicture(parent->va_display, parent->va_context,
- &mix->slice_param_buf, 1);
-
- if (va_status != VA_STATUS_SUCCESS)
+ &mix->slice_param_buf, 1);
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaRenderPicture\n");
+ LOG_E(
+ "Failed to vaRenderPicture\n");
return MIX_RESULT_FAIL;
- }
-
-
- LOG_V( "end\n");
-
+ }
+
+
+ LOG_V( "end\n");
+
return MIX_RESULT_SUCCESS;
}
MIX_RESULT mix_videofmtenc_h264_process_encode (MixVideoFormatEnc_H264 *mix,
MixBuffer * bufin, MixIOVec * iovout)
{
-
+
MIX_RESULT ret = MIX_RESULT_SUCCESS;
VAStatus va_status = VA_STATUS_SUCCESS;
- VADisplay va_display = NULL;
+ VADisplay va_display = NULL;
VAContextID va_context;
gulong surface = 0;
guint16 width, height;
-
+
MixVideoFrame * tmp_frame;
guint8 *buf;
-
+
if ((mix == NULL) || (bufin == NULL) || (iovout == NULL)) {
- LOG_E(
+ LOG_E(
"mix == NUL) || bufin == NULL || iovout == NULL\n");
return MIX_RESULT_NULL_PTR;
- }
+ }
- LOG_V( "Begin\n");
-
+ LOG_V( "Begin\n");
+
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
return MIX_RESULT_INVALID_PARAM;
-
+
MixVideoFormatEnc *parent = MIX_VIDEOFORMATENC(&(mix->parent));
-
+
va_display = parent->va_display;
va_context = parent->va_context;
width = parent->picture_width;
- height = parent->picture_height;
-
+ height = parent->picture_height;
- LOG_I( "encoded_frames = %d\n",
- mix->encoded_frames);
- LOG_I( "is_intra = %d\n",
- mix->is_intra);
- LOG_I( "ci_frame_id = 0x%08x\n",
+
+ LOG_I( "encoded_frames = %d\n",
+ mix->encoded_frames);
+ LOG_I( "is_intra = %d\n",
+ mix->is_intra);
+ LOG_I( "ci_frame_id = 0x%08x\n",
(guint) parent->ci_frame_id);
/* determine the picture type*/
@@ -1275,127 +1295,127 @@
mix->is_intra = TRUE;
} else {
mix->is_intra = FALSE;
- }
+ }
- LOG_I( "is_intra_picture = %d\n",
- mix->is_intra);
-
- LOG_V(
- "Get Surface from the pool\n");
-
- /*current we use one surface for source data,
+ LOG_I( "is_intra_picture = %d\n",
+ mix->is_intra);
+
+ LOG_V(
+ "Get Surface from the pool\n");
+
+ /*current we use one surface for source data,
* one for reference and one for reconstructed*/
/*TODO, could be refine here*/
if (!parent->share_buf_mode) {
- LOG_V(
- "We are NOT in share buffer mode\n");
-
+ LOG_V(
+ "We are NOT in share buffer mode\n");
+
if (mix->ref_frame == NULL)
{
ret = mix_surfacepool_get(parent->surfacepool, &mix->ref_frame);
if (ret != MIX_RESULT_SUCCESS) //#ifdef SLEEP_SURFACE not used
{
- LOG_E(
- "Failed to mix_surfacepool_get\n");
+ LOG_E(
+ "Failed to mix_surfacepool_get\n");
goto cleanup;
}
}
-
- if (mix->rec_frame == NULL)
+
+ if (mix->rec_frame == NULL)
{
ret = mix_surfacepool_get(parent->surfacepool, &mix->rec_frame);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
- "Failed to mix_surfacepool_get\n");
+ LOG_E(
+ "Failed to mix_surfacepool_get\n");
goto cleanup;
}
}
if (parent->need_display) {
- mix->cur_frame = NULL;
+ mix->cur_frame = NULL;
}
-
+
if (mix->cur_frame == NULL)
{
ret = mix_surfacepool_get(parent->surfacepool, &mix->cur_frame);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
- "Failed to mix_surfacepool_get\n");
+ LOG_E(
+ "Failed to mix_surfacepool_get\n");
goto cleanup;
- }
+ }
}
-
- LOG_V( "Get Surface Done\n");
-
+ LOG_V( "Get Surface Done\n");
+
+
VAImage src_image;
guint8 *pvbuf;
guint8 *dst_y;
- guint8 *dst_uv;
+ guint8 *dst_uv;
int i,j;
-
- LOG_V(
- "map source data to surface\n");
-
+
+ LOG_V(
+ "map source data to surface\n");
+
ret = mix_videoframe_get_frame_id(mix->cur_frame, &surface);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
- "Failed to mix_videoframe_get_frame_id\n");
+ LOG_E(
+ "Failed to mix_videoframe_get_frame_id\n");
goto cleanup;
}
-
-
- LOG_I(
+
+
+ LOG_I(
"surface id = 0x%08x\n", (guint) surface);
-
- va_status = vaDeriveImage(va_display, surface, &src_image);
+
+ va_status = vaDeriveImage(va_display, surface, &src_image);
//need to destroy
-
- if (va_status != VA_STATUS_SUCCESS)
+
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaDeriveImage\n");
+ LOG_E(
+ "Failed to vaDeriveImage\n");
ret = MIX_RESULT_FAIL;
goto cleanup;
}
-
- VAImage *image = &src_image;
-
- LOG_V( "vaDeriveImage Done\n");
-
+ VAImage *image = &src_image;
+
+ LOG_V( "vaDeriveImage Done\n");
+
+
va_status = vaMapBuffer (va_display, image->buf, (void **)&pvbuf);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
LOG_E( "Failed to vaMapBuffer\n");
ret = MIX_RESULT_FAIL;
goto cleanup;
- }
-
- LOG_V(
- "vaImage information\n");
- LOG_I(
+ }
+
+ LOG_V(
+ "vaImage information\n");
+ LOG_I(
"image->pitches[0] = %d\n", image->pitches[0]);
- LOG_I(
- "image->pitches[1] = %d\n", image->pitches[1]);
- LOG_I(
+ LOG_I(
+ "image->pitches[1] = %d\n", image->pitches[1]);
+ LOG_I(
"image->offsets[0] = %d\n", image->offsets[0]);
- LOG_I(
- "image->offsets[1] = %d\n", image->offsets[1]);
- LOG_I(
- "image->num_planes = %d\n", image->num_planes);
- LOG_I(
- "image->width = %d\n", image->width);
- LOG_I(
- "image->height = %d\n", image->height);
-
- LOG_I(
- "input buf size = %d\n", bufin->size);
-
+ LOG_I(
+ "image->offsets[1] = %d\n", image->offsets[1]);
+ LOG_I(
+ "image->num_planes = %d\n", image->num_planes);
+ LOG_I(
+ "image->width = %d\n", image->width);
+ LOG_I(
+ "image->height = %d\n", image->height);
+
+ LOG_I(
+ "input buf size = %d\n", bufin->size);
+
guint8 *inbuf = bufin->data;
#ifndef ANDROID
@@ -1407,18 +1427,18 @@
#ifdef USE_SRC_FMT_YUV420
/*need to convert YUV420 to NV12*/
dst_y = pvbuf +image->offsets[0];
-
+
for (i = 0; i < height; i ++) {
memcpy (dst_y, inbuf + i * width, width);
dst_y += image->pitches[0];
}
-
+
dst_uv = pvbuf + image->offsets[1];
-
+
for (i = 0; i < height / 2; i ++) {
for (j = 0; j < width; j+=2) {
dst_uv [j] = inbuf [width * height + i * width / 2 + j / 2];
- dst_uv [j + 1] =
+ dst_uv [j + 1] =
inbuf [width * height * 5 / 4 + i * width / 2 + j / 2];
}
dst_uv += image->pitches[1];
@@ -1454,70 +1474,80 @@
#endif
#endif //USE_SRC_FMT_YUV420
- va_status = vaUnmapBuffer(va_display, image->buf);
- if (va_status != VA_STATUS_SUCCESS)
+ va_status = vaUnmapBuffer(va_display, image->buf);
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaUnmapBuffer\n");
- ret = MIX_RESULT_FAIL;
+ LOG_E(
+ "Failed to vaUnmapBuffer\n");
+ ret = MIX_RESULT_FAIL;
goto cleanup;
- }
-
+ }
+
va_status = vaDestroyImage(va_display, src_image.image_id);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed to vaDestroyImage\n");
- ret = MIX_RESULT_FAIL;
+ LOG_E(
+ "Failed to vaDestroyImage\n");
+ ret = MIX_RESULT_FAIL;
goto cleanup;
- }
-
- LOG_V(
- "Map source data to surface done\n");
-
+ }
+
+ LOG_V(
+ "Map source data to surface done\n");
+
}
-
+
else {//if (!parent->share_buf_mode)
-
- MixVideoFrame * frame = mix_videoframe_new();
-
- if (mix->ref_frame == NULL)
+
+ //MixVideoFrame * frame = mix_videoframe_new();
+ if (mix->lookup_frame == NULL)
{
- ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 1);
- if (ret != MIX_RESULT_SUCCESS)
+ mix->lookup_frame = mix_videoframe_new ();
+ if (mix->lookup_frame == NULL)
{
- LOG_E(
- "mix_videoframe_set_ci_frame_idx failed\n");
- goto cleanup;
- }
-
- ret = mix_surfacepool_get_frame_with_ci_frameidx
- (parent->surfacepool, &mix->ref_frame, frame);
- if (ret != MIX_RESULT_SUCCESS)
- {
- LOG_E(
- "get reference surface from pool failed\n");
+ LOG_E("mix_videoframe_new() failed!\n");
+ ret = MIX_RESULT_NO_MEMORY;
goto cleanup;
}
}
-
- if (mix->rec_frame == NULL)
+
+ if (mix->ref_frame == NULL)
{
- ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 2);
- if (ret != MIX_RESULT_SUCCESS)
+ ret = mix_videoframe_set_ci_frame_idx (mix->lookup_frame, mix->surface_num - 1);
+ if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
- "mix_videoframe_set_ci_frame_idx failed\n");
+ LOG_E(
+ "mix_videoframe_set_ci_frame_idx failed\n");
goto cleanup;
- }
-
+ }
+
ret = mix_surfacepool_get_frame_with_ci_frameidx
- (parent->surfacepool, &mix->rec_frame, frame);
+ (parent->surfacepool, &mix->ref_frame, mix->lookup_frame);
+ if (ret != MIX_RESULT_SUCCESS)
+ {
+ LOG_E(
+ "get reference surface from pool failed\n");
+ goto cleanup;
+ }
+ }
+
+ if (mix->rec_frame == NULL)
+ {
+ ret = mix_videoframe_set_ci_frame_idx (mix->lookup_frame, mix->surface_num - 2);
+ if (ret != MIX_RESULT_SUCCESS)
+ {
+ LOG_E(
+ "mix_videoframe_set_ci_frame_idx failed\n");
+ goto cleanup;
+ }
+
+ ret = mix_surfacepool_get_frame_with_ci_frameidx
+ (parent->surfacepool, &mix->rec_frame, mix->lookup_frame);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
- "get recontructed surface from pool failed\n");
+ LOG_E(
+ "get recontructed surface from pool failed\n");
goto cleanup;
}
}
@@ -1525,9 +1555,9 @@
//mix_videoframe_unref (mix->cur_frame);
if (parent->need_display) {
- mix->cur_frame = NULL;
+ mix->cur_frame = NULL;
}
-
+
if (mix->cur_frame == NULL)
{
guint ci_idx;
@@ -1537,146 +1567,146 @@
memcpy (&ci_idx, bufin->data, sizeof(unsigned int));
#endif
- LOG_I(
- "surface_num = %d\n", mix->surface_num);
- LOG_I(
- "ci_frame_idx = %d\n", ci_idx);
-
+ LOG_I(
+ "surface_num = %d\n", mix->surface_num);
+ LOG_I(
+ "ci_frame_idx = %d\n", ci_idx);
+
if (ci_idx > mix->surface_num - 2) {
- LOG_E(
- "the CI frame idx is too bigger than CI frame number\n");
- ret = MIX_RESULT_FAIL;
+ LOG_E(
+ "the CI frame idx is too bigger than CI frame number\n");
+ ret = MIX_RESULT_FAIL;
goto cleanup;
}
-
-
- ret = mix_videoframe_set_ci_frame_idx (frame, ci_idx);
- if (ret != MIX_RESULT_SUCCESS)
- {
- LOG_E(
- "mix_videoframe_set_ci_frame_idx failed\n");
- goto cleanup;
- }
-
+
+ ret = mix_videoframe_set_ci_frame_idx (mix->lookup_frame, ci_idx);
+ if (ret != MIX_RESULT_SUCCESS)
+ {
+ LOG_E(
+ "mix_videoframe_set_ci_frame_idx failed\n");
+ goto cleanup;
+ }
+
+
ret = mix_surfacepool_get_frame_with_ci_frameidx
- (parent->surfacepool, &mix->cur_frame, frame);
+ (parent->surfacepool, &mix->cur_frame, mix->lookup_frame);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
+ LOG_E(
"get current working surface from pool failed\n");
goto cleanup;
- }
+ }
}
-
+
ret = mix_videoframe_get_frame_id(mix->cur_frame, &surface);
-
+
}
/**
* Start encoding process
**/
-
- LOG_V( "vaBeginPicture\n");
+
+ LOG_V( "vaBeginPicture\n");
LOG_I( "va_context = 0x%08x\n",(guint)va_context);
- LOG_I( "surface = 0x%08x\n",(guint)surface);
+ 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)
+ if (va_status != VA_STATUS_SUCCESS)
{
LOG_E( "Failed vaBeginPicture\n");
- ret = MIX_RESULT_FAIL;
+ ret = MIX_RESULT_FAIL;
goto cleanup;
- }
-
+ }
+
ret = mix_videofmtenc_h264_send_encode_command (mix);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E (
- "Failed mix_videofmtenc_h264_send_encode_command\n");
+ LOG_E (
+ "Failed mix_videofmtenc_h264_send_encode_command\n");
goto cleanup;
- }
-
-
+ }
+
+
if ((parent->va_rcmode == VA_RC_NONE) || mix->encoded_frames == 0) {
-
+
va_status = vaEndPicture (va_display, va_context);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E( "Failed vaEndPicture\n");
- ret = MIX_RESULT_FAIL;
+ LOG_E( "Failed vaEndPicture\n");
+ ret = MIX_RESULT_FAIL;
goto cleanup;
}
}
- LOG_V( "vaEndPicture\n");
-
+ LOG_V( "vaEndPicture\n");
+
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 ++;
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;
-
-
+ mix->ref_frame = tmp_frame;
+
+
}
-
-
- LOG_V( "vaSyncSurface\n");
-
+
+
+ LOG_V( "vaSyncSurface\n");
+
va_status = vaSyncSurface(va_display, mix->last_frame->frame_id);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E( "Failed vaSyncSurface\n");
+ LOG_E( "Failed vaSyncSurface\n");
//return MIX_RESULT_FAIL;
- }
+ }
- LOG_V(
- "Start to get encoded data\n");
+ LOG_V(
+ "Start to get encoded data\n");
/*get encoded data from the VA buffer*/
va_status = vaMapBuffer (va_display, mix->last_coded_buf, (void **)&buf);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E( "Failed vaMapBuffer\n");
- ret = MIX_RESULT_FAIL;
+ LOG_E( "Failed vaMapBuffer\n");
+ ret = MIX_RESULT_FAIL;
goto cleanup;
- }
+ }
-
+
VACodedBufferSegment *coded_seg = NULL;
int num_seg = 0;
guint total_size = 0;
- guint size = 0;
-
+ guint size = 0;
+
coded_seg = (VACodedBufferSegment *)buf;
num_seg = 1;
-
+
while (1) {
total_size += coded_seg->size;
-
- if (coded_seg->next == NULL)
- break;
-
+
+ if (coded_seg->next == NULL)
+ break;
+
coded_seg = coded_seg->next;
num_seg ++;
}
@@ -1685,190 +1715,190 @@
#if 0
// first 4 bytes is the size of the buffer
- memcpy (&(iovout->data_size), (void*)buf, 4);
+ memcpy (&(iovout->data_size), (void*)buf, 4);
//size = (guint*) buf;
guint size = iovout->data_size + 100;
-#endif
+#endif
iovout->data_size = total_size;
size = total_size + 100;
-
+
iovout->buffer_size = size;
- //We will support two buffer mode, one is application allocates the buffer and passes to encode,
+ //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
if (iovout->data == NULL) {
- LOG_E( "iovout->data == NULL\n");
+ LOG_E( "iovout->data == NULL\n");
ret = MIX_RESULT_NO_MEMORY;
- goto cleanup;
+ goto cleanup;
}
}
-
+
coded_seg = (VACodedBufferSegment *)buf;
total_size = 0;
-
+
if (mix->delimiter_type == MIX_DELIMITER_ANNEXB) {
-
+
while (1) {
-
+
memcpy (iovout->data + total_size, coded_seg->buf, coded_seg->size);
- total_size += coded_seg->size;
-
- if (coded_seg->next == NULL)
- break;
-
+ total_size += coded_seg->size;
+
+ if (coded_seg->next == NULL)
+ break;
+
coded_seg = coded_seg->next;
- }
+ }
//memcpy (iovout->data, buf + 16, iovout->data_size); //parload is started from 17th byte
- //size = iovout->data_size;
-
+ //size = iovout->data_size;
+
} else {
-
+
guint pos = 0;
- guint zero_byte_count = 0;
- guint prefix_length = 0;
- guint8 nal_unit_type = 0;
+ guint zero_byte_count = 0;
+ guint prefix_length = 0;
+ guint8 nal_unit_type = 0;
//guint8 * payload = buf + 16;
- guint8 * payload = coded_seg->buf;
-
- while ((payload[pos++] == 0x00)) {
+ guint8 * payload = coded_seg->buf;
+
+ while ((payload[pos++] == 0x00)) {
zero_byte_count ++;
if (pos >= coded_seg->size) //to make sure the buffer to be accessed is valid
break;
- }
+ }
nal_unit_type = (guint8)(payload[pos] & 0x1f);
- prefix_length = zero_byte_count + 1;
+ prefix_length = zero_byte_count + 1;
- LOG_I ("nal_unit_type = %d\n", nal_unit_type);
- LOG_I ("zero_byte_count = %d\n", zero_byte_count);
+ LOG_I ("nal_unit_type = %d\n", nal_unit_type);
+ LOG_I ("zero_byte_count = %d\n", zero_byte_count);
- size = iovout->data_size;
+ size = iovout->data_size;
if ((payload [pos - 1] & 0x01) && mix->slice_num == 1 && nal_unit_type == 1 && num_seg == 1) {
iovout->data[0] = ((size - prefix_length) >> 24) & 0xff;
iovout->data[1] = ((size - prefix_length) >> 16) & 0xff;
iovout->data[2] = ((size - prefix_length) >> 8) & 0xff;
- iovout->data[3] = (size - prefix_length) & 0xff;
+ iovout->data[3] = (size - prefix_length) & 0xff;
// use 4 bytes to indicate the NALU length
- //memcpy (iovout->data + 4, buf + 16 + prefix_length, size - prefix_length);
- memcpy (iovout->data + 4, coded_seg->buf + prefix_length, size - prefix_length);
- LOG_V ("We only have one start code, copy directly\n");
- }
- else {
+ //memcpy (iovout->data + 4, buf + 16 + prefix_length, size - prefix_length);
+ memcpy (iovout->data + 4, coded_seg->buf + prefix_length, size - prefix_length);
+ LOG_V ("We only have one start code, copy directly\n");
+ }
+ else {
- if (num_seg == 1) {
+ if (num_seg == 1) {
ret = mix_videofmtenc_h264_AnnexB_to_length_prefixed (coded_seg->buf, coded_seg->size, iovout->data, &size);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E (
- "Failed mix_videofmtenc_h264_AnnexB_to_length_prefixed\n");
+ LOG_E (
+ "Failed mix_videofmtenc_h264_AnnexB_to_length_prefixed\n");
goto cleanup;
}
-
+
} else {
-
+
guint8 * tem_buf = NULL;
tem_buf = g_malloc (size);
if (tem_buf == NULL) {
- LOG_E( "tem_buf == NULL\n");
+ LOG_E( "tem_buf == NULL\n");
ret = MIX_RESULT_NO_MEMORY;
- goto cleanup;
- }
-
+ goto cleanup;
+ }
+
while (1) {
-
+
memcpy (tem_buf + total_size, coded_seg->buf, coded_seg->size);
- total_size += coded_seg->size;
-
- if (coded_seg->next == NULL)
- break;
-
+ total_size += coded_seg->size;
+
+ if (coded_seg->next == NULL)
+ break;
+
coded_seg = coded_seg->next;
- }
-
+ }
+
ret = mix_videofmtenc_h264_AnnexB_to_length_prefixed (tem_buf, iovout->data_size, iovout->data, &size);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E (
- "Failed mix_videofmtenc_h264_AnnexB_to_length_prefixed\n");
+ LOG_E (
+ "Failed mix_videofmtenc_h264_AnnexB_to_length_prefixed\n");
goto cleanup;
- }
+ }
g_free (tem_buf);
}
}
}
-
- LOG_I(
- "out size is = %d\n", iovout->data_size);
+
+ LOG_I(
+ "out size is = %d\n", iovout->data_size);
va_status = vaUnmapBuffer (va_display, mix->last_coded_buf);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
LOG_E( "Failed vaUnmapBuffer\n");
- ret = MIX_RESULT_FAIL;
+ ret = MIX_RESULT_FAIL;
goto cleanup;
- }
+ }
- LOG_V( "get encoded data done\n");
+ LOG_V( "get encoded data done\n");
if (!((parent->va_rcmode == VA_RC_NONE) || mix->encoded_frames == 1)) {
-
+
va_status = vaEndPicture (va_display, va_context);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E( "Failed vaEndPicture\n");
- ret = MIX_RESULT_FAIL;
+ LOG_E( "Failed vaEndPicture\n");
+ ret = MIX_RESULT_FAIL;
goto cleanup;
}
- }
-
+ }
+
if (mix->encoded_frames == 1) {
va_status = vaBeginPicture(va_display, va_context, surface);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
LOG_E( "Failed vaBeginPicture\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
- }
-
+ goto cleanup;
+ }
+
ret = mix_videofmtenc_h264_send_encode_command (mix);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E (
- "Failed mix_videofmtenc_h264_send_encode_command\n");
+ LOG_E (
+ "Failed mix_videofmtenc_h264_send_encode_command\n");
goto cleanup;
- }
-
+ }
+
va_status = vaEndPicture (va_display, va_context);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E( "Failed vaEndPicture\n");
+ LOG_E( "Failed vaEndPicture\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
- }
-
- }
-
+ goto cleanup;
+ }
+
+ }
+
VASurfaceStatus status;
-
+
/*query the status of current surface*/
va_status = vaQuerySurfaceStatus(va_display, surface, &status);
- if (va_status != VA_STATUS_SUCCESS)
+ if (va_status != VA_STATUS_SUCCESS)
{
- LOG_E(
- "Failed vaQuerySurfaceStatus\n");
+ LOG_E(
+ "Failed vaQuerySurfaceStatus\n");
ret = MIX_RESULT_FAIL;
- goto cleanup;
- }
- mix->pic_skipped = status & VASurfaceSkipped;
+ goto cleanup;
+ }
+ mix->pic_skipped = status & VASurfaceSkipped;
if (parent->need_display) {
ret = mix_videoframe_set_sync_flag(mix->cur_frame, TRUE);
@@ -1876,40 +1906,40 @@
LOG_E("Failed to set sync_flag\n");
goto cleanup;
}
-
- ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_frame);
+
+ ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_frame);
if (ret != MIX_RESULT_SUCCESS)
- {
- LOG_E(
- "Failed mix_framemanager_enqueue\n");
+ {
+ LOG_E(
+ "Failed mix_framemanager_enqueue\n");
goto cleanup;
- }
+ }
}
-
+
/*update the reference surface and reconstructed surface */
if (!mix->pic_skipped) {
tmp_frame = mix->rec_frame;
mix->rec_frame= mix->ref_frame;
mix->ref_frame = tmp_frame;
- }
-
+ }
+
#if 0
if (mix->ref_frame != NULL)
mix_videoframe_unref (mix->ref_frame);
mix->ref_frame = mix->rec_frame;
-
+
mix_videoframe_unref (mix->cur_frame);
-#endif
-
+#endif
+
mix->encoded_frames ++;
mix->last_coded_buf = mix->coded_buf[mix->coded_buf_index];
- mix->coded_buf_index ++;
+ mix->coded_buf_index ++;
mix->coded_buf_index %=2;
mix->last_frame = mix->cur_frame;
#ifdef ANDROID
- if(mix->last_mix_buffer) {
+ if(mix->last_mix_buffer) {
LOG_V("calls to mix_buffer_unref \n");
LOG_V("refcount = %d\n", MIX_PARAMS(mix->last_mix_buffer)->refcount);
mix_buffer_unref(mix->last_mix_buffer);
@@ -1932,9 +1962,9 @@
iovout->data = NULL;
}
}
-
- LOG_V( "end\n");
-
+
+ LOG_V( "end\n");
+
return ret;
}
@@ -1943,110 +1973,110 @@
{
MixVideoFormatEnc *parent = NULL;
-
+
if (mix == NULL || max_size == NULL)
{
- LOG_E(
+ LOG_E(
"mix == NULL || max_size == NULL\n");
return MIX_RESULT_NULL_PTR;
}
parent = MIX_VIDEOFORMATENC(mix);
- MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
-
- LOG_V( "Begin\n");
+ MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
+
+ LOG_V( "Begin\n");
if (MIX_IS_VIDEOFORMATENC_H264(self)) {
if (self->coded_buf_size > 0) {
*max_size = self->coded_buf_size;
LOG_V ("Already calculate the max encoded size, get the value directly");
- return MIX_RESULT_SUCCESS;
+ return MIX_RESULT_SUCCESS;
}
-
+
/*base on the rate control mode to calculate the defaule encoded buffer size*/
if (self->va_rcmode == VA_RC_NONE) {
- self->coded_buf_size =
- (parent->picture_width* parent->picture_height * 400) / (16 * 16);
+ self->coded_buf_size =
+ (parent->picture_width* parent->picture_height * 400) / (16 * 16);
// set to value according to QP
}
- else {
- self->coded_buf_size = parent->bitrate/ 4;
+ else {
+ self->coded_buf_size = parent->bitrate/ 4;
}
-
- self->coded_buf_size =
- max (self->coded_buf_size ,
+
+ self->coded_buf_size =
+ max (self->coded_buf_size ,
(parent->picture_width* parent->picture_height * 400) / (16 * 16));
-
+
/*in case got a very large user input bit rate value*/
- self->coded_buf_size =
- min(self->coded_buf_size,
+ self->coded_buf_size =
+ min(self->coded_buf_size,
(parent->picture_width * parent->picture_height * 1.5 * 8));
self->coded_buf_size = (self->coded_buf_size + 15) &(~15);
}
else
{
- LOG_E(
- "not H264 video encode Object\n");
- return MIX_RESULT_INVALID_PARAM;
+ LOG_E(
+ "not H264 video encode Object\n");
+ return MIX_RESULT_INVALID_PARAM;
}
*max_size = self->coded_buf_size;
-
- return MIX_RESULT_SUCCESS;
+
+ return MIX_RESULT_SUCCESS;
}
MIX_RESULT mix_videofmtenc_h264_AnnexB_to_length_prefixed (
guint8 * bufin, guint bufin_len, guint8* bufout, guint * bufout_len)
{
-
+
guint pos = 0;
guint last_pos = 0;
-
- guint zero_byte_count = 0;
+
+ guint zero_byte_count = 0;
guint nal_size = 0;
- guint prefix_length = 0;
- guint size_copied = 0;
- guint leading_zero_count = 0;
-
+ guint prefix_length = 0;
+ guint size_copied = 0;
+ guint leading_zero_count = 0;
+
if (bufin == NULL || bufout == NULL || bufout_len == NULL) {
-
+
LOG_E(
"bufin == NULL || bufout == NULL || bufout_len = NULL\n");
return MIX_RESULT_NULL_PTR;
}
-
+
if (bufin_len <= 0 || *bufout_len <= 0) {
LOG_E(
"bufin_len <= 0 || *bufout_len <= 0\n");
- return MIX_RESULT_FAIL;
+ return MIX_RESULT_FAIL;
}
-
- LOG_V ("Begin\n");
-
- while ((bufin[pos++] == 0x00)) {
+
+ LOG_V ("Begin\n");
+
+ while ((bufin[pos++] == 0x00)) {
zero_byte_count ++;
if (pos >= bufin_len) //to make sure the buffer to be accessed is valid
break;
- }
-
+ }
+
if (bufin[pos - 1] != 0x01 || zero_byte_count < 2)
{
LOG_E("The stream is not AnnexB format \n");
return MIX_RESULT_FAIL; ; //not AnnexB, we won't process it
- }
-
- zero_byte_count = 0;
- last_pos = pos;
-
+ }
+
+ zero_byte_count = 0;
+ last_pos = pos;
+
while (pos < bufin_len) {
-
+
while (bufin[pos++] == 0) {
zero_byte_count ++;
if (pos >= bufin_len) //to make sure the buffer to be accessed is valid
- break;
+ break;
}
-
+
if (bufin[pos - 1] == 0x01 && zero_byte_count >= 2) {
if (zero_byte_count == 2) {
prefix_length = 3;
@@ -2055,129 +2085,129 @@
prefix_length = 4;
leading_zero_count = zero_byte_count - 3;
}
-
- LOG_I("leading_zero_count = %d\n", leading_zero_count);
-
- nal_size = pos - last_pos - prefix_length - leading_zero_count;
+
+ LOG_I("leading_zero_count = %d\n", leading_zero_count);
+
+ nal_size = pos - last_pos - prefix_length - leading_zero_count;
if (nal_size < 0) {
- LOG_E ("something wrong in the stream\n");
- return MIX_RESULT_FAIL; //not AnnexB, we won't process it
+ LOG_E ("something wrong in the stream\n");
+ return MIX_RESULT_FAIL; //not AnnexB, we won't process it
}
-
+
if (*bufout_len < (size_copied + nal_size + 4)) {
- LOG_E ("The length of destination buffer is too small\n");
- return MIX_RESULT_FAIL;
+ LOG_E ("The length of destination buffer is too small\n");
+ return MIX_RESULT_FAIL;
}
-
- LOG_I ("nal_size = %d\n", nal_size);
-
- /*We use 4 bytes length prefix*/
+
+ LOG_I ("nal_size = %d\n", nal_size);
+
+ /*We use 4 bytes length prefix*/
bufout [size_copied] = nal_size >> 24 & 0xff;
bufout [size_copied + 1] = nal_size >> 16 & 0xff;
bufout [size_copied + 2] = nal_size >> 8 & 0xff;
- bufout [size_copied + 3] = nal_size & 0xff;
-
- size_copied += 4; //4 bytes length prefix
+ bufout [size_copied + 3] = nal_size & 0xff;
+
+ size_copied += 4; //4 bytes length prefix
memcpy (bufout + size_copied, bufin + last_pos, nal_size);
- size_copied += nal_size;
-
- LOG_I ("size_copied = %d\n", size_copied);
-
- zero_byte_count = 0;
+ size_copied += nal_size;
+
+ LOG_I ("size_copied = %d\n", size_copied);
+
+ zero_byte_count = 0;
leading_zero_count = 0;
- last_pos = pos;
+ last_pos = pos;
}
-
+
else if (pos == bufin_len) {
-
- LOG_V ("Last NALU in this frame\n");
-
- nal_size = pos - last_pos;
-
+
+ LOG_V ("Last NALU in this frame\n");
+
+ nal_size = pos - last_pos;
+
if (*bufout_len < (size_copied + nal_size + 4)) {
- LOG_E ("The length of destination buffer is too small\n");
- return MIX_RESULT_FAIL;
+ LOG_E ("The length of destination buffer is too small\n");
+ return MIX_RESULT_FAIL;
}
-
- /*We use 4 bytes length prefix*/
+
+ /*We use 4 bytes length prefix*/
bufout [size_copied] = nal_size >> 24 & 0xff;
bufout [size_copied + 1] = nal_size >> 16 & 0xff;
bufout [size_copied + 2] = nal_size >> 8 & 0xff;
- bufout [size_copied + 3] = nal_size & 0xff;
-
- size_copied += 4; //4 bytes length prefix
+ bufout [size_copied + 3] = nal_size & 0xff;
+
+ size_copied += 4; //4 bytes length prefix
memcpy (bufout + size_copied, bufin + last_pos, nal_size);
- size_copied += nal_size;
-
- LOG_I ("size_copied = %d\n", size_copied);
+ size_copied += nal_size;
+
+ LOG_I ("size_copied = %d\n", size_copied);
}
-
+
else {
zero_byte_count = 0;
leading_zero_count = 0;
}
-
+
}
-
+
if (size_copied != *bufout_len) {
*bufout_len = size_copied;
}
-
- LOG_V ("End\n");
-
- return MIX_RESULT_SUCCESS;
-
+
+ LOG_V ("End\n");
+
+ return MIX_RESULT_SUCCESS;
+
}
MIX_RESULT mix_videofmtenc_h264_send_encode_command (MixVideoFormatEnc_H264 *mix)
{
MIX_RESULT ret = MIX_RESULT_SUCCESS;
- LOG_V( "Begin\n");
+ LOG_V( "Begin\n");
MixVideoFormatEnc *parent = MIX_VIDEOFORMATENC(&(mix->parent));
-
+
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
- return MIX_RESULT_INVALID_PARAM;
-
+ return MIX_RESULT_INVALID_PARAM;
+
if (mix->encoded_frames == 0 || parent->new_header_required) {
ret = mix_videofmtenc_h264_send_seq_params (mix);
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
+ LOG_E(
"Failed mix_videofmtenc_h264_send_seq_params\n");
return MIX_RESULT_FAIL;
}
parent->new_header_required = FALSE; //Set to require new header filed to FALSE
}
-
- ret = mix_videofmtenc_h264_send_picture_parameter (mix);
-
+
+ ret = mix_videofmtenc_h264_send_picture_parameter (mix);
+
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_E(
- "Failed mix_videofmtenc_h264_send_picture_parameter\n");
+ 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");
+ {
+ LOG_E(
+ "Failed mix_videofmtenc_h264_send_slice_parameter\n");
return MIX_RESULT_FAIL;
- }
-
+ }
- LOG_V( "End\n");
+
+ LOG_V( "End\n");
return MIX_RESULT_SUCCESS;
}
-MIX_RESULT mix_videofmtenc_h264_set_dynamic_enc_config (MixVideoFormatEnc * mix,
- MixVideoConfigParamsEnc * config_params_enc,
+MIX_RESULT mix_videofmtenc_h264_set_dynamic_enc_config (MixVideoFormatEnc * mix,
+ MixVideoConfigParamsEnc * config_params_enc,
MixEncParamsType params_type) {
@@ -2185,23 +2215,23 @@
MixVideoFormatEnc *parent = NULL;
MixVideoConfigParamsEncH264 * config_params_enc_h264;
- LOG_V( "Begin\n");
+ LOG_V( "Begin\n");
if (!MIX_IS_VIDEOFORMATENC_H264(mix))
- return MIX_RESULT_INVALID_PARAM;
+ return MIX_RESULT_INVALID_PARAM;
MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
parent = MIX_VIDEOFORMATENC(&(mix->parent));
if (MIX_IS_VIDEOCONFIGPARAMSENC_H264 (config_params_enc)) {
- config_params_enc_h264 =
+ config_params_enc_h264 =
MIX_VIDEOCONFIGPARAMSENC_H264 (config_params_enc);
} else {
- LOG_V(
+ LOG_V(
"mix_videofmtenc_h264_initialize: no h264 config params found\n");
return MIX_RESULT_FAIL;
- }
+ }
/*
* For case params_type == MIX_ENC_PARAMS_SLICE_SIZE
@@ -2211,42 +2241,42 @@
*/
if (params_type == MIX_ENC_PARAMS_SLICE_SIZE) {
- g_mutex_lock(parent->objectlock);
-
+ g_mutex_lock(parent->objectlock);
+
ret = mix_videoconfigparamsenc_h264_get_slice_num (config_params_enc_h264,
&self->slice_num);
if (ret != MIX_RESULT_SUCCESS) {
- LOG_E(
- "Failed to mix_videoconfigparamsenc_h264_get_slice_num\n");
+ LOG_E(
+ "Failed to mix_videoconfigparamsenc_h264_get_slice_num\n");
- g_mutex_unlock(parent->objectlock);
+ g_mutex_unlock(parent->objectlock);
return ret;
- }
+ }
- g_mutex_unlock(parent->objectlock);
-
+ g_mutex_unlock(parent->objectlock);
+
} else if (params_type == MIX_ENC_PARAMS_IDR_INTERVAL) {
- g_mutex_lock(parent->objectlock);
-
+ g_mutex_lock(parent->objectlock);
+
ret = mix_videoconfigparamsenc_h264_get_IDR_interval(config_params_enc_h264,
&self->idr_interval);
if (ret != MIX_RESULT_SUCCESS) {
- LOG_E(
- "Failed to mix_videoconfigparamsenc_h264_get_IDR_interval\n");
+ LOG_E(
+ "Failed to mix_videoconfigparamsenc_h264_get_IDR_interval\n");
- g_mutex_unlock(parent->objectlock);
+ g_mutex_unlock(parent->objectlock);
return ret;
- }
+ }
parent->new_header_required = TRUE;
- g_mutex_unlock(parent->objectlock);
-
+ g_mutex_unlock(parent->objectlock);
+
} else{
/* Chainup parent method. */
@@ -2257,16 +2287,16 @@
if (ret != MIX_RESULT_SUCCESS)
{
- LOG_V(
+ LOG_V(
"chainup parent method (set_dynamic_config) failed \n");
return ret;
- }
+ }
}
- LOG_V( "End\n");
+ 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 a8f813a..2e7b12d 100644
--- a/mix_video/src/mixvideoformatenc_h264.h
+++ b/mix_video/src/mixvideoformatenc_h264.h
@@ -49,7 +49,8 @@
MixVideoFrame *ref_frame; //reference frame
MixVideoFrame *rec_frame; //reconstructed frame;
MixVideoFrame *last_frame; //last frame;
-#ifdef ANDROID
+ MixVideoFrame *lookup_frame;
+#ifdef ANDROID
MixBuffer *last_mix_buffer;
#endif