Name: libmm-camcorder
Summary: Camera and recorder library
-Version: 0.10.231
+Version: 0.10.232
Release: 0
Group: Multimedia/Libraries
License: Apache-2.0
*/
#define MMCAM_AUDIOSRC_ELEMENT_NAME "audiosrc-element-name"
+/**
+ * Extra preview enable
+ */
+#define MMCAM_EXTRA_PREVIEW_ENABLE "extra-preview-enable"
+
/*=======================================================================================
void *internal_buffer; /**< Internal buffer pointer */
int stride[BUFFER_MAX_PLANE_NUM]; /**< Stride of each plane */
int elevation[BUFFER_MAX_PLANE_NUM]; /**< Elevation of each plane */
+ int extra_stream_id; /**< ID of extra preview stream */
} MMCamcorderVideoStreamDataType;
MM_CAM_STROBE_BRIGHTNESS,
MM_CAM_VIDEOSRC_ELEMENT_NAME,
MM_CAM_AUDIOSRC_ELEMENT_NAME,
+ MM_CAM_EXTRA_PREVIEW_ENABLE,
MM_CAM_ATTRIBUTE_NUM
} MMCamcorderAttrsID;
bool _mmcamcorder_commit_sound_stream_info(MMHandleType handle, int attr_idx, const MMAttrsValue *value);
bool _mmcamcorder_commit_tag(MMHandleType handle, int attr_idx, const MMAttrsValue *value);
bool _mmcamcorder_commit_audio_replay_gain(MMHandleType handle, int attr_idx, const MMAttrsValue *value);
+bool _mmcamcorder_commit_extra_preview(MMHandleType handle, int attr_idx, const MMAttrsValue *value);
/**
bool _mmcamcorder_set_encoded_preview_gop_interval(MMHandleType handle, int gop_interval);
bool _mmcamcorder_set_sound_stream_info(GstElement *element, char *stream_type, int stream_index);
void _mmcamcorder_set_encoder_bitrate(MMCamcorderEncoderType type, int codec, int bitrate, GstElement *element);
-gboolean _mmcamcorder_invoke_video_stream_cb(MMHandleType handle, GstBuffer *buffer, gboolean is_preview);
+gboolean _mmcamcorder_invoke_video_stream_cb(MMHandleType handle, GstSample *sample, gboolean is_preview, int stream_id);
GstPadProbeReturn __mmcamcorder_muxed_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
GstPadProbeReturn __mmcamcorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
#ifdef __cplusplus
int use_videoconvert; /**< Whether use videoconvert element for display */
int support_media_packet_preview_cb; /**< Whether support zero copy format for camera input */
int support_user_buffer; /**< Whether support user allocated buffer for zero copy */
+ int support_extra_preview; /**< Whether support extra preview stream */
int shutter_sound_policy; /**< shutter sound policy */
int brightness_default; /**< default value of brightness */
int brightness_step_denominator; /**< denominator of brightness bias step */
#ifdef _MMCAMCORDER_CAMERA_CONF_MGR_SUPPORT
camera_conf_device_info_s conf_device_info;
#endif /*_MMCAMCORDER_CAMERA_CONF_MGR_SUPPORT */
+
+ /* Profiling */
+ int measure_preview_fps; /**< Flag for measuring fps of preview frames */
+
int reserved[4]; /**< reserved */
} mmf_camcorder_t;
int _mmcamcorder_connect_capture_signal(MMHandleType handle);
/**
+ * This function connects extra preview stream signal.
+ *
+ * @param[in] handle Handle of camcorder context.
+ * @return This function returns MM_ERROR_NONE on success, or the other values on error.
+ * @remarks
+ */
+int _mmcamcorder_connect_extra_preview_stream(MMHandleType handle);
+
+/**
* This function destroy image pipeline.
*
* @param[in] handle Handle of camcorder context.
_MMCAMCORDER_HANDLER_VIDEOREC = (1 << 1),
_MMCAMCORDER_HANDLER_STILLSHOT = (1 << 2),
_MMCAMCORDER_HANDLER_AUDIOREC = (1 << 3),
+ _MMCAMCORDER_HANDLER_EXTRA_PREVIEW = (1 << 4),
} _MMCamcorderHandlerCategory;
/*=======================================================================================
#define G_DBUS_TIMEOUT 3000
#define FAT32_FILE_SYSTEM_MAX_SIZE (4294967295UL) /* 4 GigaByte - 1 byte */
#define _MMCAMCORDER_HANDLER_CATEGORY_ALL \
- (_MMCAMCORDER_HANDLER_PREVIEW | _MMCAMCORDER_HANDLER_VIDEOREC |_MMCAMCORDER_HANDLER_STILLSHOT | _MMCAMCORDER_HANDLER_AUDIOREC)
+ (_MMCAMCORDER_HANDLER_PREVIEW |\
+ _MMCAMCORDER_HANDLER_VIDEOREC |\
+ _MMCAMCORDER_HANDLER_STILLSHOT |\
+ _MMCAMCORDER_HANDLER_AUDIOREC |\
+ _MMCAMCORDER_HANDLER_EXTRA_PREVIEW)
/*=======================================================================================
void _mmcamcorder_set_log_level(int level);
int _mmcamcorder_get_log_level(void);
+/* profiling */
+void _mmcamcorder_measure_fps(void *data);
+
#ifdef __cplusplus
}
* This function pushes video buffer to encoding pipeline
*
* @param[in] handle Handle of camcorder context.
- * @param[in] buffer Buffer to push.
+ * @param[in] sample Sample including buffer to push.
* @return This function returns TRUE on success, or FALSE on failure.
* @remarks
*/
-gboolean _mmcamcorder_video_push_buffer(void *handle, GstBuffer *buffer);
+gboolean _mmcamcorder_video_push_buffer(void *handle, GstSample *sample);
#ifdef __cplusplus
{0},
{0},
NULL,
+ },
+ {
+ MM_CAM_EXTRA_PREVIEW_ENABLE,
+ "extra-preview-enable",
+ MM_ATTRS_TYPE_INT,
+ MM_ATTRS_FLAG_RW,
+ {(void*)FALSE},
+ MM_ATTRS_VALID_TYPE_INT_RANGE,
+ {.int_min = 0},
+ {.int_max = 1},
+ _mmcamcorder_commit_extra_preview,
}
};
}
+bool _mmcamcorder_commit_extra_preview(MMHandleType handle, int attr_idx, const MMAttrsValue *value)
+{
+ int current_state = MM_CAMCORDER_STATE_NONE;
+ mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+ _MMCamcorderSubContext *sc = NULL;
+
+ mmf_return_val_if_fail(hcamcorder && value, FALSE);
+
+ if (hcamcorder->type != MM_CAMCORDER_MODE_VIDEO_CAPTURE) {
+ MMCAM_LOG_ERROR("invalid mode %d", hcamcorder->type);
+ return FALSE;
+ }
+
+ MMCAM_LOG_INFO("Enable extra preview(%d)", value->value.i_val);
+
+ current_state = _mmcamcorder_get_state(handle);
+ if (current_state < MM_CAMCORDER_STATE_READY) {
+ MMCAM_LOG_INFO("will be set when preview is started");
+ return TRUE;
+ }
+
+ sc = MMF_CAMCORDER_SUBCONTEXT(handle);
+ mmf_return_val_if_fail(sc, FALSE);
+
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "extra-preview", value->value.i_val);
+
+ return TRUE;
+}
+
+
bool _mmcamcorder_set_attribute_to_camsensor(MMHandleType handle)
{
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
{ "DeviceCount", CONFIGURE_VALUE_INT, {.value_int = MM_VIDEO_DEVICE_NUM} },
{ "SupportMediaPacketPreviewCb", CONFIGURE_VALUE_INT, {.value_int = 0} },
{ "SupportUserBuffer", CONFIGURE_VALUE_INT, {.value_int = 0} },
+ { "MeasurePreviewFPS", CONFIGURE_VALUE_INT, {.value_int = 0} },
+ { "SupportExtraPreview", CONFIGURE_VALUE_INT, {.value_int = 0} },
};
/* [AudioInput] matching table */
}
-gboolean _mmcamcorder_invoke_video_stream_cb(MMHandleType handle, GstBuffer *buffer, gboolean is_preview)
+gboolean _mmcamcorder_invoke_video_stream_cb(MMHandleType handle, GstSample *sample, gboolean is_preview, int stream_id)
{
int i = 0;
int num_bos = 0;
tbm_surface_h t_surface = NULL;
tbm_surface_info_s ts_info;
+ GstBuffer *buffer = NULL;
GstMemory *memory = NULL;
GstMapInfo map_info;
GstCaps *caps = NULL;
- GstPad *pad = NULL;
GstStructure *structure = NULL;
mmf_return_val_if_fail(hcamcorder, FALSE);
+
+ buffer = gst_sample_get_buffer(sample);
mmf_return_val_if_fail(buffer, FALSE);
mmf_return_val_if_fail(gst_buffer_n_memory(buffer), FALSE);
memset(&map_info, 0x0, sizeof(GstMapInfo));
memset(&stream, 0x0, sizeof(MMCamcorderVideoStreamDataType));
- stream.format = sc->info_image->preview_format;
- if (is_preview) {
- /* preview buffer - get resolution from caps */
- pad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "src");
- mmf_return_val_if_fail(pad, FALSE);
-
- caps = gst_pad_get_allowed_caps(pad);
- if (!caps) {
- MMCAM_LOG_ERROR("failed to get caps from pad %p", pad);
- gst_object_unref(pad);
- return FALSE;
- }
-
- structure = gst_caps_get_structure(caps, 0);
- if (!structure) {
- MMCAM_LOG_ERROR("failed to get structure from caps %p", caps);
- gst_caps_unref(caps);
- gst_object_unref(pad);
- return FALSE;
- }
+ caps = gst_sample_get_caps(sample);
+ mmf_return_val_if_fail(caps, FALSE);
- gst_structure_get_int(structure, "width", &stream.width);
- gst_structure_get_int(structure, "height", &stream.height);
+ structure = gst_caps_get_structure(caps, 0);
+ mmf_return_val_if_fail(structure, FALSE);
- gst_caps_unref(caps);
- caps = NULL;
- gst_object_unref(pad);
- pad = NULL;
- } else {
- /* video recording buffer */
- stream.width = sc->info_video->video_width;
- stream.height = sc->info_video->video_height;
- }
+ /* set format and resolution */
+ gst_structure_get_int(structure, "width", &stream.width);
+ gst_structure_get_int(structure, "height", &stream.height);
+ stream.format = _mmcamcorder_get_pixel_format(caps);
- /* set size and timestamp */
if (_mmcamcorder_is_encoded_preview_pixel_format(stream.format)) {
memory = gst_buffer_get_all_memory(buffer);
stream.internal_buffer = buffer;
goto _INVOKE_VIDEO_STREAM_CB_DONE;
}
- MMCAM_LOG_DEBUG("VideoStreamData : resolution[%dx%d], format[%d]",
- stream.width, stream.height, stream.format);
+ MMCAM_LOG_DEBUG("VideoStreamData : format[%d], resolution[%dx%d], stream_id[%d]",
+ stream.format, stream.width, stream.height, stream_id);
stream.timestamp = (unsigned int)(GST_BUFFER_PTS(buffer) / 1000000); /* nano sec -> milli sec */
+ stream.extra_stream_id = stream_id;
/* invoke application callback */
if (is_preview) {
int sink_element_size = 0;
int *fds = NULL;
int fd_number = 0;
+ int extra_preview_enable = 0;
GList *element_list = NULL;
MMCAM_IMAGE_ENCODER_QUALITY, &capture_jpg_quality,
MMCAM_DISPLAY_SOCKET_PATH, &socket_path, &socket_path_len,
MMCAM_DISPLAY_SURFACE, &display_surface_type,
+ MMCAM_EXTRA_PREVIEW_ENABLE, &extra_preview_enable,
NULL);
if (err != MM_ERROR_NONE) {
MMCAM_LOG_WARNING("Get attrs fail. (%s:%x)", err_name, err);
_MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSRC_FILT, "capsfilter", "videosrc_filter", element_list, err);
- /* set camera properties */
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "high-speed-fps", 0);
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-width", capture_width);
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-height", capture_height);
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-jpg-quality", capture_jpg_quality);
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "hdr-capture", sc->info_image->hdr_capture_mode);
-
/**
* This is for "tizencamerasrc" element only.
* The camera HAL library will be loaded when "hal-name" property is set.
*/
MMCAMCORDER_G_OBJECT_SET_POINTER(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "hal-name", hcamcorder->network_hal_name);
+ /* set camera properties */
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "high-speed-fps", 0);
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-width", capture_width);
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-height", capture_height);
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-jpg-quality", capture_jpg_quality);
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "hdr-capture", sc->info_image->hdr_capture_mode);
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "extra-preview", extra_preview_enable);
+
_MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSRC_QUE, "queue", "videosrc_queue", element_list, err);
/* set camera flip */
static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
{
+ gboolean ret = TRUE;
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
_MMCamcorderSubContext *sc = NULL;
- _MMCamcorderKPIMeasure *kpi = NULL;
GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
+ GstSample *sample = NULL;
+ GstCaps *caps = NULL;
mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP);
mmf_return_val_if_fail(gst_buffer_n_memory(buffer), GST_PAD_PROBE_DROP);
return GST_PAD_PROBE_DROP;
}
- if (hcamcorder->state >= MM_CAMCORDER_STATE_PREPARE) {
- int diff_sec;
- int frame_count = 0;
- struct timeval current_video_time;
-
- kpi = &(sc->kpi);
- if (kpi->init_video_time.tv_sec == kpi->last_video_time.tv_sec &&
- kpi->init_video_time.tv_usec == kpi->last_video_time.tv_usec &&
- kpi->init_video_time.tv_usec == 0) {
- /*
- MMCAM_LOG_INFO("START to measure FPS");
- */
- gettimeofday(&(kpi->init_video_time), NULL);
- }
-
- frame_count = ++(kpi->video_framecount);
-
- gettimeofday(¤t_video_time, NULL);
- diff_sec = current_video_time.tv_sec - kpi->last_video_time.tv_sec;
- if (diff_sec != 0) {
- kpi->current_fps = (frame_count - kpi->last_framecount) / diff_sec;
- if ((current_video_time.tv_sec - kpi->init_video_time.tv_sec) != 0) {
- int framecount = kpi->video_framecount;
- int elased_sec = current_video_time.tv_sec - kpi->init_video_time.tv_sec;
- kpi->average_fps = framecount / elased_sec;
- }
-
- kpi->last_framecount = frame_count;
- kpi->last_video_time.tv_sec = current_video_time.tv_sec;
- kpi->last_video_time.tv_usec = current_video_time.tv_usec;
- /*
- MMCAM_LOG_INFO("current fps(%d), average(%d)", kpi->current_fps, kpi->average_fps);
- */
- }
- }
+ if (hcamcorder->measure_preview_fps && hcamcorder->state >= MM_CAMCORDER_STATE_PREPARE)
+ _mmcamcorder_measure_fps(&sc->kpi);
/* The first H.264 frame should not be skipped for vstream cb. */
if (hcamcorder->state < MM_CAMCORDER_STATE_PREPARE &&
return GST_PAD_PROBE_OK;
}
- if (_mmcamcorder_invoke_video_stream_cb((MMHandleType)hcamcorder, buffer, TRUE))
+ /* make sample with buffer and caps */
+ caps = gst_pad_get_allowed_caps(pad);
+ mmf_return_val_if_fail(caps, GST_PAD_PROBE_OK);
+
+ sample = gst_sample_new(buffer, caps, NULL, NULL);
+ gst_caps_unref(caps);
+ mmf_return_val_if_fail(sample, GST_PAD_PROBE_OK);
+
+ ret = _mmcamcorder_invoke_video_stream_cb((MMHandleType)hcamcorder, sample, TRUE, -1);
+
+ gst_sample_unref(sample);
+
+ if (ret)
return GST_PAD_PROBE_OK;
else
return GST_PAD_PROBE_DROP;
static GstPadProbeReturn __mmcamcorder_video_dataprobe_record(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
{
- if (_mmcamcorder_video_push_buffer(u_data, GST_PAD_PROBE_INFO_BUFFER(info)))
- return GST_PAD_PROBE_OK;
+ gboolean ret = TRUE;
+ GstSample *sample = NULL;
+ GstCaps *caps = NULL;
+
+ caps = gst_pad_get_allowed_caps(pad);
+ mmf_return_val_if_fail(caps, GST_PAD_PROBE_OK);
+
+ sample = gst_sample_new(GST_PAD_PROBE_INFO_BUFFER(info), caps, NULL, NULL);
+ gst_caps_unref(caps);
+ mmf_return_val_if_fail(sample, GST_PAD_PROBE_OK);
+
+ ret = _mmcamcorder_video_push_buffer(u_data, sample);
+
+ gst_sample_unref(sample);
- return GST_PAD_PROBE_DROP;
+ return (ret ? GST_PAD_PROBE_OK : GST_PAD_PROBE_DROP);
}
&hcamcorder->support_media_packet_preview_cb);
_mmcamcorder_conf_get_value_int((MMHandleType)hcamcorder, hcamcorder->conf_main,
+ CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
+ "SupportExtraPreview",
+ &hcamcorder->support_extra_preview);
+
+ _mmcamcorder_conf_get_value_int((MMHandleType)hcamcorder, hcamcorder->conf_main,
CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
"UseVideoconvert",
&hcamcorder->use_videoconvert);
+ _mmcamcorder_conf_get_value_int((MMHandleType)hcamcorder, hcamcorder->conf_main,
+ CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
+ "MeasurePreviewFPS",
+ &hcamcorder->measure_preview_fps);
+
ret = mm_camcorder_get_attributes((MMHandleType)hcamcorder, NULL,
MMCAM_CAMERA_WIDTH, &resolution_width,
MMCAM_CAMERA_HEIGHT, &resolution_height,
return MM_ERROR_CAMCORDER_INTERNAL;
}
- MMCAM_LOG_INFO("ZeroCopy %d, UserBuffer %d, Videoconvert %d, MPPreviewCb %d",
+ MMCAM_LOG_INFO("ZC %d, UB %d, VC %d, MPPC %d, EP %d, MPFPS %d",
hcamcorder->use_zero_copy_format, hcamcorder->support_user_buffer,
- hcamcorder->use_videoconvert, hcamcorder->support_media_packet_preview_cb);
+ hcamcorder->use_videoconvert, hcamcorder->support_media_packet_preview_cb,
+ hcamcorder->support_extra_preview, hcamcorder->measure_preview_fps);
MMCAM_LOG_INFO("res : %d X %d, Default FPS by resolution : %d",
resolution_width, resolution_height, fps_info.int_array.def);
break;
case MM_CAMCORDER_MODE_VIDEO_CAPTURE:
+ /* fall through */
default:
ret = _mmcamcorder_create_preview_pipeline(handle);
if (ret != MM_ERROR_NONE)
return ret;
- /* connect capture signal */
if (!sc->bencbin_capture) {
ret = _mmcamcorder_connect_capture_signal(handle);
if (ret != MM_ERROR_NONE)
return ret;
}
+
+ if (hcamcorder->support_extra_preview &&
+ _mmcamcorder_connect_extra_preview_stream(handle) != MM_ERROR_NONE)
+ MMCAM_LOG_WARNING("connect extra preview stream signal failed");
break;
}
int _mmcamcorder_image_cmd_preview_start(MMHandleType handle);
int _mmcamcorder_image_cmd_preview_stop(MMHandleType handle);
static void __mmcamcorder_image_capture_cb(GstElement *element, GstSample *sample1, GstSample *sample2, GstSample *sample3, gpointer u_data);
+static void __mmcamcorder_extra_preview_stream_cb(GstElement *element, int stream_id, GstSample *sample, gpointer u_data);
/* sound status changed callback */
static void __sound_status_changed_cb(keynode_t* node, void *data);
sc = MMF_CAMCORDER_SUBCONTEXT(handle);
mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
- /* check video source element */
- if (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst) {
- MMCAM_LOG_WARNING("connect capture signal to _MMCAMCORDER_VIDEOSRC_SRC");
- MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst,
- _MMCAMCORDER_HANDLER_STILLSHOT, "still-capture",
- G_CALLBACK(__mmcamcorder_image_capture_cb),
- hcamcorder);
+ mmf_return_val_if_fail(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
- return MM_ERROR_NONE;
- } else {
- MMCAM_LOG_ERROR("videosrc element is not created yet");
- return MM_ERROR_CAMCORDER_NOT_INITIALIZED;
- }
+ MMCAM_LOG_INFO("connect capture signal to _MMCAMCORDER_VIDEOSRC_SRC");
+
+ MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst,
+ _MMCAMCORDER_HANDLER_STILLSHOT, "still-capture",
+ G_CALLBACK(__mmcamcorder_image_capture_cb),
+ hcamcorder);
+
+ return MM_ERROR_NONE;
+}
+
+
+int _mmcamcorder_connect_extra_preview_stream(MMHandleType handle)
+{
+ mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+ _MMCamcorderSubContext *sc = NULL;
+
+ mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+ sc = MMF_CAMCORDER_SUBCONTEXT(handle);
+ mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+ mmf_return_val_if_fail(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+ MMCAM_LOG_INFO("connect extra preview stream signal to _MMCAMCORDER_VIDEOSRC_SRC");
+
+ MMCAMCORDER_SIGNAL_CONNECT(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst,
+ _MMCAMCORDER_HANDLER_EXTRA_PREVIEW, "extra-preview-stream-cb",
+ G_CALLBACK(__mmcamcorder_extra_preview_stream_cb),
+ hcamcorder);
+
+ return MM_ERROR_NONE;
}
}
+static void __mmcamcorder_extra_preview_stream_cb(GstElement *element, int stream_id, GstSample *sample, gpointer u_data)
+{
+ if (!sample) {
+ MMCAM_LOG_ERROR("NULL sample for extra preview[id:%d]", stream_id);
+ return;
+ }
+
+ /* no need to check return value here */
+ _mmcamcorder_invoke_video_stream_cb((MMHandleType)u_data, sample, TRUE, stream_id);
+
+ gst_sample_unref(sample);
+}
+
+
gboolean __mmcamcorder_handoff_callback(GstElement *fakesink, GstBuffer *buffer, GstPad *pad, gpointer u_data)
{
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
{
return mmcam_log_level;
}
+
+void _mmcamcorder_measure_fps(void *data)
+{
+ int diff_sec;
+ int frame_count = 0;
+ struct timeval current_video_time;
+ _MMCamcorderKPIMeasure *kpi = (_MMCamcorderKPIMeasure *)data;
+
+ mmf_return_if_fail(kpi);
+
+ if (!timerisset(&kpi->init_video_time) && !timerisset(&kpi->last_video_time)) {
+ MMCAM_LOG_INFO("START to measure FPS");
+ gettimeofday(&(kpi->init_video_time), NULL);
+ }
+
+ frame_count = ++(kpi->video_framecount);
+
+ gettimeofday(¤t_video_time, NULL);
+
+ diff_sec = current_video_time.tv_sec - kpi->last_video_time.tv_sec;
+ if (diff_sec == 0)
+ return;
+
+ kpi->current_fps = (frame_count - kpi->last_framecount) / diff_sec;
+
+ if ((current_video_time.tv_sec - kpi->init_video_time.tv_sec) != 0)
+ kpi->average_fps = kpi->video_framecount / (current_video_time.tv_sec - kpi->init_video_time.tv_sec);
+
+ kpi->last_framecount = frame_count;
+ kpi->last_video_time.tv_sec = current_video_time.tv_sec;
+ kpi->last_video_time.tv_usec = current_video_time.tv_usec;
+
+ MMCAM_LOG_INFO("current fps[%d], average[%d]", kpi->current_fps, kpi->average_fps);
+}
| LOCAL FUNCTION PROTOTYPES: |
---------------------------------------------------------------------------------------*/
/* STATIC INTERNAL FUNCTION */
-static gboolean __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data);
+static void __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data);
static GstPadProbeReturn __mmcamcorder_audio_dataprobe_check(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
static GstPadProbeReturn __mmcamcorder_video_dataprobe_encoded(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
static GstPadProbeReturn __mmcamcorder_audioque_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
/*---------------------------------------------------------------------------------------
| GLOBAL FUNCTION DEFINITIONS: |
---------------------------------------------------------------------------------------*/
-gboolean _mmcamcorder_video_push_buffer(void *handle, GstBuffer *buffer)
+gboolean _mmcamcorder_video_push_buffer(void *handle, GstSample *sample)
{
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
_MMCamcorderSubContext *sc = NULL;
_MMCamcorderVideoInfo *info_video = NULL;
_MMCamcorderGstElement *element = NULL;
GstClockTime current_ts = 0; /* nsec */
+ GstBuffer *buffer = NULL;
mmf_return_val_if_fail(hcamcorder, FALSE);
mmf_return_val_if_fail(MMF_CAMCORDER_SUBCONTEXT(hcamcorder), FALSE);
+ buffer = gst_sample_get_buffer(sample);
+
mmf_return_val_if_fail(buffer, FALSE);
mmf_return_val_if_fail(gst_buffer_n_memory(buffer), FALSE);
info_video->base_video_ts = current_ts;
}
} else {
- if (_mmcamcorder_invoke_video_stream_cb(handle, buffer, FALSE) == FALSE) {
+ if (_mmcamcorder_invoke_video_stream_cb(handle, sample, FALSE, -1) == FALSE) {
/* increase base video timestamp by frame duration,
it will remove delay of dropped buffer when play recorded file. */
info_video->base_video_ts += current_ts - info_video->last_video_ts;
}
-static gboolean __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data)
+static void __mmcamcorder_video_stream_cb(GstElement *element, GstSample *sample, gpointer u_data)
{
- return _mmcamcorder_video_push_buffer(u_data, gst_sample_get_buffer(sample));
+ mmf_return_if_fail(sample);
+
+ /* no need to check return value here */
+ _mmcamcorder_video_push_buffer(u_data, sample);
+
+ gst_sample_unref(sample);
}