[Release version 0.10.42] Fix capture failure on ARTIK-10
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_gstcommon.c
index 955e7da..f7fa967 100644 (file)
@@ -35,7 +35,6 @@
 
 #include "mm_camcorder_internal.h"
 #include "mm_camcorder_gstcommon.h"
-#include "mm_camcorder_client.h"
 
 /*-----------------------------------------------------------------------
 |    GLOBAL VARIABLE DEFINITIONS for internal                          |
@@ -329,12 +328,17 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle)
                if (err != MM_ERROR_NONE) {
                        _mmcam_dbg_warn("Get socket path failed 0x%x", err);
                        SAFE_FREE(err_name);
-                       return err;
+                       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, 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);
@@ -396,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;
@@ -420,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);
@@ -471,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);
@@ -657,26 +670,31 @@ 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");
-               }
-               if (!pad) {
-                       _mmcam_dbg_err("get videosrc_que src pad failed");
-                       err = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
-                       goto pipeline_creation_error;
+                       /* Image */
+                       MMCAMCORDER_G_OBJECT_GET(sc->element[_MMCAMCORDER_VIDEOSRC_FILT].gst, "caps", &video_caps);
                }
 
-               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;
 
@@ -689,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);
@@ -712,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 */
@@ -769,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);
                }
@@ -824,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 &&
@@ -1214,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);
                }
@@ -1252,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.");
                }
@@ -1279,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);
@@ -1348,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);
@@ -1366,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;
@@ -1379,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 {
@@ -1755,7 +1765,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);
@@ -2013,7 +2023,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;
 
@@ -2027,7 +2037,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) {
@@ -2035,10 +2045,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 {
@@ -2052,7 +2061,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;
 
@@ -2066,7 +2075,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) {
@@ -2074,10 +2083,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 {
@@ -2288,11 +2296,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) {
@@ -2549,3 +2560,35 @@ bool _mmcamcorder_set_encoded_preview_gop_interval(MMHandleType handle, int inte
 
        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;
+}
+