X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmm_camcorder_gstcommon.c;h=964703d3b300c2e67b4fd77660ba7af6998c2059;hb=afd2a25711f505dd1e8c9271f0172a0db560989a;hp=8f47dca32ca2cfaca57959f137bbd893bed23c69;hpb=e29f5836c8bc050472b78a23dc0cc66af07e89bb;p=platform%2Fcore%2Fmultimedia%2Flibmm-camcorder.git diff --git a/src/mm_camcorder_gstcommon.c b/src/mm_camcorder_gstcommon.c index 8f47dca..964703d 100644 --- a/src/mm_camcorder_gstcommon.c +++ b/src/mm_camcorder_gstcommon.c @@ -35,7 +35,6 @@ #include "mm_camcorder_internal.h" #include "mm_camcorder_gstcommon.h" -#include "mm_camcorder_client.h" /*----------------------------------------------------------------------- | GLOBAL VARIABLE DEFINITIONS for internal | @@ -45,7 +44,7 @@ gboolean audiocodec_fileformat_compatibility_table[MM_AUDIO_CODEC_NUM][MM_FILE_F { /* 3GP ASF AVI MATROSKA MP4 OGG NUT QT REAL AMR AAC MP3 AIFF AU WAV MID MMF DIVX FLV VOB IMELODY WMA WMV JPG FLAC M2TS*/ /*AMR*/ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*G723.1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -/*MP3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +/*MP3*/ { 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1}, /*OGG*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*AAC*/ { 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /*WMA*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -178,6 +177,7 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) int capture_jpg_quality = 100; int video_stabilization = 0; int anti_shake = 0; + int display_surface_type = MM_DISPLAY_SURFACE_NULL; const char *videosrc_name = NULL; const char *videosink_name = NULL; char *err_name = NULL; @@ -233,7 +233,8 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) MMCAM_CAMERA_HDR_CAPTURE, &sc->info_image->hdr_capture_mode, MMCAM_IMAGE_ENCODER, &codectype, MMCAM_IMAGE_ENCODER_QUALITY, &capture_jpg_quality, - MMCAM_DISPLAY_SHM_SOCKET_PATH, &socket_path, &socket_path_len, + MMCAM_DISPLAY_SOCKET_PATH, &socket_path, &socket_path_len, + MMCAM_DISPLAY_SURFACE, &display_surface_type, NULL); if (err != MM_ERROR_NONE) { _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err); @@ -290,6 +291,22 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) /* make demux and decoder for H264 stream from videosrc */ if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { + int preview_bitrate = 0; + int gop_interval = 0; + + /* set encoded preview bitrate and iframe interval */ + mm_camcorder_get_attributes(handle, NULL, + MMCAM_ENCODED_PREVIEW_BITRATE, &preview_bitrate, + MMCAM_ENCODED_PREVIEW_GOP_INTERVAL, &gop_interval, + NULL); + + if (!_mmcamcorder_set_encoded_preview_bitrate(handle, preview_bitrate)) + _mmcam_dbg_warn("_mmcamcorder_set_encoded_preview_bitrate failed"); + + if (!_mmcamcorder_set_encoded_preview_gop_interval(handle, gop_interval)) + _mmcam_dbg_warn("_mmcamcorder_set_encoded_preview_gop_interval failed"); + + /* create decoder element */ _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSRC_DECODE, _MMCAMCORDER_VIDEO_DECODER_NAME, "videosrc_decode", element_list, err); } @@ -301,20 +318,31 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSINK_QUE, "queue", "videosink_queue", element_list, err); _mmcam_dbg_log("videosink_name: %s", videosink_name); - if (strcmp(videosink_name, "fakesink") == 0) { - _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSINK_SINK, videosink_name, "videosink_sink", element_list, err); - _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, sc->VideosinkElement); + + if (display_surface_type == MM_DISPLAY_SURFACE_REMOTE) { + _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSINK_SINK, videosink_name, "ipc_sink", element_list, err); + + err = mm_camcorder_get_attributes(handle, &err_name, + MMCAM_DISPLAY_SOCKET_PATH, &socket_path, &socket_path_len, + NULL); + if (err != MM_ERROR_NONE) { + _mmcam_dbg_warn("Get socket path failed 0x%x", err); + SAFE_FREE(err_name); + goto pipeline_creation_error; + } + + g_object_set(G_OBJECT(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst), "socket-path", socket_path, NULL); } else { - _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSINK_SINK, "shmsink", "ipc_sink", element_list, err); - _mmcam_dbg_log("socket_path : %s", socket_path); - g_object_set(G_OBJECT(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst), - "socket-path", socket_path, - "wait-for-connection", FALSE, - "perms", 0777, - "sync", TRUE, - NULL); + _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSINK_SINK, videosink_name, "videosink_sink", element_list, err); + if (_mmcamcorder_videosink_window_set(handle, sc->VideosinkElement) != MM_ERROR_NONE) { + _mmcam_dbg_err("_mmcamcorder_videosink_window_set error"); + err = MM_ERROR_CAMCORDER_INVALID_ARGUMENT; + goto pipeline_creation_error; + } } + _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, sc->VideosinkElement); + /* Set caps by rotation */ _mmcamcorder_set_videosrc_rotation(handle, camera_rotate); @@ -372,6 +400,9 @@ int _mmcamcorder_create_audiosrc_bin(MMHandleType handle) char *err_name = NULL; const char *audiosrc_name = NULL; char *cat_name = NULL; + char *stream_type = NULL; + char stream_type_len = 0; + int stream_index = 0; GstCaps *caps = NULL; GstPad *pad = NULL; @@ -396,14 +427,16 @@ int _mmcamcorder_create_audiosrc_bin(MMHandleType handle) } err = mm_camcorder_get_attributes(handle, &err_name, - MMCAM_AUDIO_DEVICE, &a_dev, - MMCAM_AUDIO_ENCODER, &a_enc, - MMCAM_AUDIO_ENCODER_BITRATE, &val, - MMCAM_AUDIO_SAMPLERATE, &rate, - MMCAM_AUDIO_FORMAT, &format, - MMCAM_AUDIO_CHANNEL, &channel, - MMCAM_AUDIO_VOLUME, &volume, - NULL); + MMCAM_AUDIO_DEVICE, &a_dev, + MMCAM_AUDIO_ENCODER, &a_enc, + MMCAM_AUDIO_ENCODER_BITRATE, &val, + MMCAM_AUDIO_SAMPLERATE, &rate, + MMCAM_AUDIO_FORMAT, &format, + MMCAM_AUDIO_CHANNEL, &channel, + MMCAM_AUDIO_VOLUME, &volume, + MMCAM_SOUND_STREAM_TYPE, &stream_type, &stream_type_len, + MMCAM_SOUND_STREAM_INDEX, &stream_index, + NULL); if (err != MM_ERROR_NONE) { _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err); SAFE_FREE(err_name); @@ -447,6 +480,10 @@ int _mmcamcorder_create_audiosrc_bin(MMHandleType handle) _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_AUDIOSRC_SRC, audiosrc_name, "audiosrc_src", element_list, err); + /* set sound stream info */ + _mmcamcorder_set_sound_stream_info(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst, stream_type, stream_index); + + /* set audiosrc properties in ini configuration */ _mmcamcorder_conf_set_value_element_property(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst, AudiosrcElement); _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_AUDIOSRC_FILT, "capsfilter", "audiosrc_capsfilter", element_list, err); @@ -633,25 +670,30 @@ int _mmcamcorder_create_encodesink_bin(MMHandleType handle, MMCamcorderEncodebin MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_ENCSINK_SRC].gst, "max-bytes", 0); /* unlimited */ /* set capsfilter */ - if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { - _mmcam_dbg_log("get pad from videosrc_filter"); - pad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "src"); + if (profile == MM_CAMCORDER_ENCBIN_PROFILE_VIDEO) { + if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { + _mmcam_dbg_log("get pad from videosrc_filter"); + pad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "src"); + } else { + _mmcam_dbg_log("get pad from videosrc_que"); + pad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "src"); + } + if (!pad) { + _mmcam_dbg_err("get videosrc_que src pad failed"); + err = MM_ERROR_CAMCORDER_RESOURCE_CREATION; + goto pipeline_creation_error; + } + + caps_from_pad = gst_pad_get_allowed_caps(pad); + video_caps = gst_caps_copy(caps_from_pad); + gst_caps_unref(caps_from_pad); + caps_from_pad = NULL; + gst_object_unref(pad); + pad = NULL; } else { - _mmcam_dbg_log("get pad from videosrc_que"); - pad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "src"); + /* Image */ + MMCAMCORDER_G_OBJECT_GET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", &video_caps); } - if (!pad) { - _mmcam_dbg_err("get videosrc_que src pad failed"); - err = MM_ERROR_CAMCORDER_RESOURCE_CREATION; - goto pipeline_creation_error; - } - - caps_from_pad = gst_pad_get_allowed_caps(pad); - video_caps = gst_caps_copy(caps_from_pad); - gst_caps_unref(caps_from_pad); - caps_from_pad = NULL; - gst_object_unref(pad); - pad = NULL; if (video_caps) { char *caps_str = NULL; @@ -665,7 +707,7 @@ int _mmcamcorder_create_encodesink_bin(MMHandleType handle, MMCamcorderEncodebin caps_str = gst_caps_to_string(video_caps); _mmcam_dbg_log("encodebin caps [%s]", caps_str); - free(caps_str); + g_free(caps_str); caps_str = NULL; MMCAMCORDER_G_OBJECT_SET_POINTER(sc->encode_element[_MMCAMCORDER_ENCSINK_FILT].gst, "caps", video_caps); @@ -688,13 +730,24 @@ int _mmcamcorder_create_encodesink_bin(MMHandleType handle, MMCamcorderEncodebin _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_ENCBIN, "encodebin", "encodesink_encbin", element_list, err); /* check element availability */ - mm_camcorder_get_attributes(handle, &err_name, + err = mm_camcorder_get_attributes(handle, &err_name, MMCAM_AUDIO_ENCODER, &audio_enc, MMCAM_AUDIO_CHANNEL, &channel, MMCAM_VIDEO_ENCODER_BITRATE, &v_bitrate, MMCAM_AUDIO_ENCODER_BITRATE, &a_bitrate, NULL); + if (err != MM_ERROR_NONE) { + if (err_name) { + _mmcam_dbg_err("failed to get attributes [%s][0x%x]", err_name, err); + SAFE_FREE(err_name); + } else { + _mmcam_dbg_err("failed to get attributes [0x%x]", err); + } + + return err; + } + _mmcam_dbg_log("Profile[%d]", profile); /* Set information */ @@ -745,7 +798,7 @@ int _mmcamcorder_create_encodesink_bin(MMHandleType handle, MMCamcorderEncodebin } if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { - gst_element_venc_name = strdup("capsfilter"); + gst_element_venc_name = "capsfilter"; } else { _mmcamcorder_conf_get_value_element_name(VideoencElement, &gst_element_venc_name); } @@ -800,11 +853,6 @@ int _mmcamcorder_create_encodesink_bin(MMHandleType handle, MMCamcorderEncodebin if (use_venc_queue) { _MMCAMCORDER_ENCODEBIN_ELMGET(sc, _MMCAMCORDER_ENCSINK_VENC_QUE, "use-venc-queue", err); } - - if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { - free(gst_element_venc_name); - gst_element_venc_name = NULL; - } } if (sc->audio_disable == FALSE && @@ -1011,11 +1059,6 @@ int _mmcamcorder_create_encodesink_bin(MMHandleType handle, MMCamcorderEncodebin element_list = NULL; } - if (video_caps) { - gst_caps_unref(video_caps); - video_caps = NULL; - } - _mmcam_dbg_log("done"); return MM_ERROR_NONE; @@ -1038,11 +1081,6 @@ pipeline_creation_error : element_list = NULL; } - if (video_caps) { - gst_caps_unref(video_caps); - video_caps = NULL; - } - return err; } @@ -1200,8 +1238,7 @@ int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* Videosi if (err != MM_ERROR_NONE) { if (err_name) { _mmcam_dbg_err("failed to get attributes [%s][0x%x]", err_name, err); - free(err_name); - err_name = NULL; + SAFE_FREE(err_name); } else { _mmcam_dbg_err("failed to get attributes [0x%x]", err); } @@ -1238,21 +1275,10 @@ int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* Videosi } else if (!strcmp(videosink_name, "waylandsink")) { MMCamWaylandInfo *wl_info = (MMCamWaylandInfo *)overlay; if (wl_info) { - GstContext *context = NULL; - - context = gst_wayland_display_handle_context_new((struct wl_display *)wl_info->display); - if (context) { - gst_element_set_context(vsink, context); - } else { - _mmcam_dbg_warn("gst_wayland_display_handle_context_new failed"); - } - - gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), (guintptr)wl_info->surface); + _mmcam_dbg_log("wayland global surface id : %d", wl_info->global_surface_id); + gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(vsink), (guintptr)wl_info->global_surface_id); gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(vsink), - wl_info->window_x, - wl_info->window_y, - wl_info->window_width, - wl_info->window_height); + wl_info->window_x, wl_info->window_y, wl_info->window_width, wl_info->window_height); } else { _mmcam_dbg_warn("Handle is NULL. skip setting."); } @@ -1265,7 +1291,7 @@ int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* Videosi videosink_name, display_geometry_method, origin_size, visible, rotation, flip); /* Set attribute */ - if (!strcmp(videosink_name, "xvimagesink") || + if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "waylandsink") || !strcmp(videosink_name, "evaspixmapsink")) { /* set rotation */ MMCAMCORDER_G_OBJECT_SET(vsink, "rotate", rotation); @@ -1334,7 +1360,7 @@ gboolean _mmcamcorder_get_device_info(MMHandleType handle) mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle); _MMCamcorderSubContext *sc = NULL; GstCameraControl *control = NULL; - GstCameraControlExifInfo exif_info; + GstCameraControlExifInfo exif_info = {0,}; mmf_return_val_if_fail(hcamcorder, FALSE); sc = MMF_CAMCORDER_SUBCONTEXT(handle); @@ -1352,7 +1378,8 @@ gboolean _mmcamcorder_get_device_info(MMHandleType handle) control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst); if (control != NULL) { gst_camera_control_get_exif_info(control, &exif_info); //get video input device information - focal_len = ((double)exif_info.focal_len_numerator) / ((double) exif_info.focal_len_denominator); + if (exif_info.focal_len_denominator != 0) + focal_len = ((double)exif_info.focal_len_numerator) / ((double) exif_info.focal_len_denominator); } else { _mmcam_dbg_err("Fail to get camera control interface!"); focal_len = 0.0; @@ -1365,10 +1392,7 @@ gboolean _mmcamcorder_get_device_info(MMHandleType handle) NULL); if (err != MM_ERROR_NONE) { _mmcam_dbg_err("Set attributes error(%s:%x)!", err_name, err); - if (err_name) { - free(err_name); - err_name = NULL; - } + SAFE_FREE(err_name); return FALSE; } } else { @@ -1487,16 +1511,19 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP structure = gst_caps_get_structure( caps, 0 ); gst_structure_get_int(structure, "width", &(stream.width)); gst_structure_get_int(structure, "height", &(stream.height)); - string_format = gst_structure_get_string(structure, "format"); - if (string_format == NULL) { - gst_caps_unref(caps); - caps = NULL; - _mmcam_dbg_warn("get string error!!"); - return GST_PAD_PROBE_OK; + if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { + stream.format = MM_PIXEL_FORMAT_ENCODED_H264; + } else { + string_format = gst_structure_get_string(structure, "format"); + if (string_format == NULL) { + gst_caps_unref(caps); + caps = NULL; + _mmcam_dbg_warn("get string error!!"); + return GST_PAD_PROBE_OK; + } + fourcc = _mmcamcorder_convert_fourcc_string_to_value(string_format); + stream.format = _mmcamcorder_get_pixtype(fourcc); } - - fourcc = _mmcamcorder_convert_fourcc_string_to_value(string_format); - stream.format = _mmcamcorder_get_pixtype(fourcc); gst_caps_unref(caps); caps = NULL; @@ -1567,6 +1594,10 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP stream.data.yuv420sp.length_y = stream.width * stream.height; stream.data.yuv420sp.uv = stream.data.yuv420sp.y + stream.data.yuv420sp.length_y; stream.data.yuv420sp.length_uv = stream.data.yuv420sp.length_y >> 1; + stream.stride[0] = stream.width; + stream.elevation[0] = stream.height; + stream.stride[1] = stream.width; + stream.elevation[1] = stream.height >> 1; /* _mmcam_dbg_log("format[%d][num_planes:%d] [Y]p:0x%x,size:%d [UV]p:0x%x,size:%d", stream.format, stream.num_planes, @@ -1582,6 +1613,12 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP stream.data.yuv420p.length_u = stream.data.yuv420p.length_y >> 2; stream.data.yuv420p.v = stream.data.yuv420p.u + stream.data.yuv420p.length_u; stream.data.yuv420p.length_v = stream.data.yuv420p.length_u; + stream.stride[0] = stream.width; + stream.elevation[0] = stream.height; + stream.stride[1] = stream.width >> 1; + stream.elevation[1] = stream.height >> 1; + stream.stride[2] = stream.width >> 1; + stream.elevation[2] = stream.height >> 1; /* _mmcam_dbg_log("I420[num_planes:%d] [Y]p:0x%x,size:%d [U]p:0x%x,size:%d [V]p:0x%x,size:%d", stream.num_planes, @@ -1604,10 +1641,21 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP stream.data_type = MM_CAM_STREAM_DATA_YUV422; stream.data.yuv422.yuv = mapinfo.data; stream.data.yuv422.length_yuv = stream.length_total; + stream.stride[0] = stream.width << 1; + stream.elevation[0] = stream.height; + } else if (stream.format == MM_PIXEL_FORMAT_ENCODED_H264) { + stream.data_type = MM_CAM_STREAM_DATA_ENCODED; + stream.data.encoded.data = mapinfo.data; + stream.data.encoded.length_data = stream.length_total; + _mmcam_dbg_log("H264[num_planes:%d] [0]p:0x%x,size:%d", + fourcc, fourcc>>8, fourcc>>16, fourcc>>24, stream.num_planes, + stream.data.encoded.data, stream.data.encoded.length_data); } else { stream.data_type = MM_CAM_STREAM_DATA_YUV420; stream.data.yuv420.yuv = mapinfo.data; stream.data.yuv420.length_yuv = stream.length_total; + stream.stride[0] = (stream.width * 3) >> 1; + stream.elevation[0] = stream.height; } stream.num_planes = 1; @@ -1710,11 +1758,11 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_push_buffer_to_record(Gst if(sc->info_video->is_firstframe) { /* for image capture with encodebin(ex:emulator) */ if (sc->bencbin_capture && sc->info_image->capturing) { - pthread_mutex_lock(&(hcamcorder->task_thread_lock)); + g_mutex_lock(&hcamcorder->task_thread_lock); _mmcam_dbg_log("send signal for sound play"); hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_SOUND_SOLO_PLAY_START; - pthread_cond_signal(&(hcamcorder->task_thread_cond)); - pthread_mutex_unlock(&(hcamcorder->task_thread_lock)); + g_cond_signal(&hcamcorder->task_thread_cond); + g_mutex_unlock(&hcamcorder->task_thread_lock); } sc->info_video->is_firstframe = FALSE; sc->info_video->base_video_ts = GST_BUFFER_PTS(buffer); @@ -1731,7 +1779,7 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_push_buffer_to_record(Gst char *caps_string = gst_caps_to_string(caps); if (caps_string) { _mmcam_dbg_log("%s", caps_string); - free(caps_string); + g_free(caps_string); caps_string = NULL; } gst_caps_unref(caps); @@ -1930,8 +1978,8 @@ int _mmcamcorder_check_audiocodec_fileformat_compatibility(MMHandleType handle) } /* Check compatibility between audio codec and file format */ - if (audio_codec >= MM_AUDIO_CODEC_INVALID && audio_codec < MM_AUDIO_CODEC_NUM && - file_format >= MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) { + if (audio_codec > MM_AUDIO_CODEC_INVALID && audio_codec < MM_AUDIO_CODEC_NUM && + file_format > MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) { if (audiocodec_fileformat_compatibility_table[audio_codec][file_format] == 0) { _mmcam_dbg_err("Audio codec[%d] and file format[%d] compatibility FAILED.", audio_codec, file_format); @@ -1969,8 +2017,8 @@ int _mmcamcorder_check_videocodec_fileformat_compatibility(MMHandleType handle) } /* Check compatibility between audio codec and file format */ - if (video_codec >= MM_VIDEO_CODEC_INVALID && video_codec < MM_VIDEO_CODEC_NUM && - file_format >= MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) { + if (video_codec > MM_VIDEO_CODEC_INVALID && video_codec < MM_VIDEO_CODEC_NUM && + file_format > MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) { if (videocodec_fileformat_compatibility_table[video_codec][file_format] == 0) { _mmcam_dbg_err("Video codec[%d] and file format[%d] compatibility FAILED.", video_codec, file_format); @@ -1989,7 +2037,7 @@ int _mmcamcorder_check_videocodec_fileformat_compatibility(MMHandleType handle) } -bool _mmcamcorder_set_display_rotation(MMHandleType handle, int display_rotate) +bool _mmcamcorder_set_display_rotation(MMHandleType handle, int display_rotate, int videosink_index) { const char* videosink_name = NULL; @@ -2003,7 +2051,7 @@ bool _mmcamcorder_set_display_rotation(MMHandleType handle, int display_rotate) mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED); mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED); - if (sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst) { + if (sc->element[videosink_index].gst) { /* Get videosink name */ _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name); if (videosink_name == NULL) { @@ -2011,10 +2059,9 @@ bool _mmcamcorder_set_display_rotation(MMHandleType handle, int display_rotate) return FALSE; } - if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "evasimagesink") || - !strcmp(videosink_name, "evaspixmapsink")) { - MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, - "rotate", display_rotate); + if (!strcmp(videosink_name, "waylandsink") || !strcmp(videosink_name, "xvimagesink") || + !strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "evaspixmapsink")) { + MMCAMCORDER_G_OBJECT_SET(sc->element[videosink_index].gst, "rotate", display_rotate); _mmcam_dbg_log("Set display-rotate [%d] done.", display_rotate); return TRUE; } else { @@ -2028,7 +2075,7 @@ bool _mmcamcorder_set_display_rotation(MMHandleType handle, int display_rotate) } -bool _mmcamcorder_set_display_flip(MMHandleType handle, int display_flip) +bool _mmcamcorder_set_display_flip(MMHandleType handle, int display_flip, int videosink_index) { const char* videosink_name = NULL; @@ -2042,7 +2089,7 @@ bool _mmcamcorder_set_display_flip(MMHandleType handle, int display_flip) mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED); mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED); - if (sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst) { + if (sc->element[videosink_index].gst) { /* Get videosink name */ _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name); if (videosink_name == NULL) { @@ -2050,10 +2097,9 @@ bool _mmcamcorder_set_display_flip(MMHandleType handle, int display_flip) return FALSE; } - if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "evasimagesink") || - !strcmp(videosink_name, "evaspixmapsink")) { - MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, - "flip", display_flip); + if (!strcmp(videosink_name, "waylandsink") || !strcmp(videosink_name, "xvimagesink") || + !strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "evaspixmapsink")) { + MMCAMCORDER_G_OBJECT_SET(sc->element[videosink_index].gst, "flip", display_flip); _mmcam_dbg_log("Set display flip [%d] done.", display_flip); return TRUE; } else { @@ -2203,12 +2249,16 @@ bool _mmcamcorder_set_videosrc_caps(MMHandleType handle, unsigned int fourcc, in structure = gst_caps_get_structure(caps, 0); if (structure) { + const gchar *format_string = NULL; int caps_width = 0; int caps_height = 0; int caps_fps = 0; int caps_rotate = 0; - caps_fourcc = _mmcamcorder_convert_fourcc_string_to_value(gst_structure_get_string(structure, "format")); + format_string = gst_structure_get_string(structure, "format"); + if (format_string) { + caps_fourcc = _mmcamcorder_convert_fourcc_string_to_value(format_string); + } gst_structure_get_int(structure, "width", &caps_width); gst_structure_get_int(structure, "height", &caps_height); gst_structure_get_int(structure, "fps", &caps_fps); @@ -2260,11 +2310,14 @@ bool _mmcamcorder_set_videosrc_caps(MMHandleType handle, unsigned int fourcc, in NULL); } - _mmcam_dbg_log("vidoesrc new caps set. %"GST_PTR_FORMAT, caps); - - MMCAMCORDER_G_OBJECT_SET_POINTER(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps); - gst_caps_unref(caps); - caps = NULL; + if (caps) { + _mmcam_dbg_log("vidoesrc new caps set. %"GST_PTR_FORMAT, caps); + MMCAMCORDER_G_OBJECT_SET_POINTER(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", caps); + gst_caps_unref(caps); + caps = NULL; + } else { + _mmcam_dbg_err("There are no caps"); + } } if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) { @@ -2444,3 +2497,112 @@ bool _mmcamcorder_set_camera_resolution(MMHandleType handle, int width, int heig return _mmcamcorder_set_videosrc_caps(handle, sc->fourcc, width, height, fps, sc->videosrc_rotate); } + + +bool _mmcamcorder_set_encoded_preview_bitrate(MMHandleType handle, int bitrate) +{ + _MMCamcorderSubContext *sc = NULL; + GstCameraControl *CameraControl = NULL; + GstCameraControlChannel *CameraControlChannel = NULL; + const GList *controls = NULL; + const GList *item = NULL; + + if ((void *)handle == NULL) { + _mmcam_dbg_warn("handle is NULL"); + return FALSE; + } + + sc = MMF_CAMCORDER_SUBCONTEXT(handle); + if (!sc) { + _mmcam_dbg_warn("subcontext is NULL"); + return FALSE; + } + + if (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst == NULL) { + _mmcam_dbg_warn("videosrc plugin is NULL"); + return FALSE; + } + + _mmcam_dbg_log("set encoded preview bitrate : %d bps", bitrate); + + CameraControl = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst); + controls = gst_camera_control_list_channels(CameraControl); + _mmcam_dbg_log("controls : 0x%x", controls); + if (controls != NULL) { + _mmcam_dbg_log("controls : 0x%x", controls); + for (item = controls ; item && item->data ; item = item->next) { + CameraControlChannel = item->data; + _mmcam_dbg_log("label : %d", CameraControlChannel->label); + if (!strcmp(CameraControlChannel->label, "bitrate")) { + _mmcam_dbg_log("set encoded preview bitrate %d", bitrate); + return gst_camera_control_set_value(CameraControl, CameraControlChannel, bitrate); + } + } + + if (item == NULL) { + _mmcam_dbg_warn("failed to find \"bitrate\" control channel"); + } + } + + return FALSE; +} + + +bool _mmcamcorder_set_encoded_preview_gop_interval(MMHandleType handle, int interval) +{ + _MMCamcorderSubContext *sc = NULL; + + if ((void *)handle == NULL) { + _mmcam_dbg_warn("handle is NULL"); + return FALSE; + } + + sc = MMF_CAMCORDER_SUBCONTEXT(handle); + if (!sc) { + _mmcam_dbg_warn("subcontext is NULL"); + return FALSE; + } + + if (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst == NULL) { + _mmcam_dbg_warn("videosrc plugin is NULL"); + return FALSE; + } + + _mmcam_dbg_log("set encoded preview GOP interval : %d ms", interval); + + MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "newgop-interval", interval); + + return TRUE; +} + + +bool _mmcamcorder_set_sound_stream_info(GstElement *element, char *stream_type, int stream_index) +{ + GstStructure *props = NULL; + char stream_props[64] = {'\0',}; + + if (element == NULL || stream_type == NULL || stream_index < 0) { + _mmcam_dbg_err("invalid argument %p %p %d", element, stream_type, stream_index); + return FALSE; + } + + snprintf(stream_props, sizeof(stream_props) - 1, + "props,media.role=%s, media.parent_id=%d", + stream_type, stream_index); + + _mmcam_dbg_log("stream type %s, index %d -> [%s]", stream_type, stream_index, stream_props); + + props = gst_structure_from_string(stream_props, NULL); + if (!props) { + _mmcam_dbg_err("failed to create GstStructure"); + return FALSE; + } + + MMCAMCORDER_G_OBJECT_SET_POINTER(element, "stream-properties", props); + + gst_structure_free(props); + props = NULL; + + return TRUE; +} +