Add defensive code for spurious wakeup in _mmcamcorder_sound_solo_play_wait()
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_util.c
index b3ab5a5..3614ffe 100644 (file)
@@ -165,37 +165,45 @@ static void __gdbus_stream_eos_cb(GDBusConnection *connection,
        const gchar *signal_name, GVariant *param, gpointer user_data)
 {
        int played_idx = 0;
-       _MMCamcorderGDbusCbInfo *gdbus_info = NULL;
-       mmf_camcorder_t *hcamcorder = NULL;
-
-       MMCAM_LOG_WARNING("entered");
+       gboolean stopped_by_user = FALSE;
+       gboolean do_free = FALSE;
+       _MMCamcorderGDbusCbInfo *info = NULL;
 
        if (!param || !user_data) {
                MMCAM_LOG_ERROR("invalid parameter %p %p", param, user_data);
                return;
        }
 
-       gdbus_info = (_MMCamcorderGDbusCbInfo *)user_data;
-       hcamcorder = (mmf_camcorder_t *)gdbus_info->mm_handle;
+       info = (_MMCamcorderGDbusCbInfo *)user_data;
 
-       g_variant_get(param, "(i)", &played_idx);
+       MMCAM_LOG_WARNING("entered[gdbus_info:%p]", info);
 
-       g_mutex_lock(&gdbus_info->sync_mutex);
+       g_variant_get(param, "(ib)", &played_idx, &stopped_by_user);
 
-       MMCAM_LOG_WARNING("gdbus_info->param %d, played_idx : %d, handle : %p",
-               gdbus_info->param, played_idx, hcamcorder);
+       g_mutex_lock(&info->sync_mutex);
 
-       if (gdbus_info->param == played_idx) {
-               g_dbus_connection_signal_unsubscribe(connection, gdbus_info->subscribe_id);
+       MMCAM_LOG_WARNING("gdbus_info->param %d, played_idx %d, stopped_by_user %d",
+               info->param, played_idx, stopped_by_user);
 
-               gdbus_info->is_playing = FALSE;
-               gdbus_info->subscribe_id = 0;
-               gdbus_info->param = 0;
+       if (info->param == played_idx) {
+               g_dbus_connection_signal_unsubscribe(connection, info->subscribe_id);
+
+               info->is_playing = FALSE;
+               info->subscribe_id = 0;
+               info->param = 0;
 
-               g_cond_signal(&gdbus_info->sync_cond);
+               g_cond_signal(&info->sync_cond);
        }
 
-       g_mutex_unlock(&gdbus_info->sync_mutex);
+       if (info->free_in_cb)
+               do_free = TRUE;
+
+       g_mutex_unlock(&info->sync_mutex);
+
+       if (do_free) {
+               MMCAM_LOG_WARNING("free gdbus_info[%p]", info);
+               _mmcamcorder_gdbus_info_free(info);
+       }
 
        MMCAM_LOG_WARNING("done");
 
@@ -875,6 +883,44 @@ int _mmcamcorder_get_file_system_type(const gchar *path, int *file_system_type)
 }
 
 
+int _mmcamcorder_get_camera_id(int device_type, int *camera_id)
+{
+       int ret = MM_ERROR_NONE;
+       MMCamPreset info = {.videodev_type = device_type};
+       MMHandleType handle = NULL;
+       mmf_camcorder_t *hcamcorder = NULL;
+       type_int_array *input_index = NULL;
+
+       mmf_return_val_if_fail(camera_id, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
+
+       ret = _mmcamcorder_create(&handle, &info);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("_mmcamcorder_create failed[0x%x]", ret);
+               return ret;
+       }
+
+       hcamcorder = MMF_CAMCORDER(handle);
+
+       _mmcamcorder_conf_get_value_int_array(hcamcorder->conf_ctrl,
+               CONFIGURE_CATEGORY_CTRL_CAMERA,
+               "InputIndex", &input_index);
+       if (!input_index) {
+               MMCAM_LOG_ERROR("Get input index failed");
+               ret = MM_ERROR_CAMCORDER_INTERNAL;
+               goto _GET_CAMERA_ID_OUT;
+       }
+
+       *camera_id = input_index->default_value;
+
+       MMCAM_LOG_INFO("device type[%d] -> camera id[%d]", device_type, *camera_id);
+
+_GET_CAMERA_ID_OUT:
+       _mmcamcorder_destroy(handle);
+
+       return ret;
+}
+
+
 int _mmcamcorder_get_device_led_brightness(GDBusConnection *conn, int *brightness)
 {
        int get_value = 0;
@@ -904,6 +950,60 @@ int _mmcamcorder_get_device_led_brightness(GDBusConnection *conn, int *brightnes
 }
 
 
+_MMCamcorderGDbusCbInfo *_mmcamcorder_gdbus_info_new(void)
+{
+       _MMCamcorderGDbusCbInfo *new_info = g_new0(_MMCamcorderGDbusCbInfo, 1);
+
+       g_mutex_init(&new_info->sync_mutex);
+       g_cond_init(&new_info->sync_cond);
+
+       MMCAM_LOG_INFO("new gdbus_info[%p]", new_info);
+
+       return new_info;
+}
+
+
+void _mmcamcorder_gdbus_info_free(_MMCamcorderGDbusCbInfo *info)
+{
+       if (!info) {
+               MMCAM_LOG_WARNING("NULL info");
+               return;
+       }
+
+       MMCAM_LOG_INFO("free gdbus_info[%p]", info);
+
+       g_mutex_clear(&info->sync_mutex);
+       g_cond_clear(&info->sync_cond);
+
+       g_free(info);
+}
+
+
+void _mmcamcorder_gdbus_info_check_free(_MMCamcorderGDbusCbInfo *info)
+{
+       gboolean do_free = FALSE;
+
+       if (!info) {
+               MMCAM_LOG_WARNING("NULL info");
+               return;
+       }
+
+       g_mutex_lock(&info->sync_mutex);
+
+       if (info->subscribe_id > 0) {
+               MMCAM_LOG_WARNING("gdbus_info[%p] will be freed in sound EOS cb", info);
+               info->free_in_cb = TRUE;
+       } else {
+               do_free = TRUE;
+       }
+
+       g_mutex_unlock(&info->sync_mutex);
+
+       if (do_free)
+               _mmcamcorder_gdbus_info_free(info);
+}
+
+
 int _mmcamcorder_send_sound_play_message(GDBusConnection *conn, _MMCamcorderGDbusCbInfo *gdbus_info,
        const char *sample_name, const char *stream_role, const char *volume_gain, int sync_play)
 {
@@ -1527,7 +1627,7 @@ void _mmcamcorder_remove_message_all(MMHandleType handle)
 }
 
 
-int _mmcamcorder_get_pixel_format(GstCaps *caps)
+int _mmcamcorder_get_pixel_format(GstCaps *caps, gboolean is_preview)
 {
        gchar *caps_string = NULL;
        const char *media_type;
@@ -1548,7 +1648,7 @@ int _mmcamcorder_get_pixel_format(GstCaps *caps)
        }
 
        if (!strcmp(media_type, "image/jpeg"))
-               return MM_PIXEL_FORMAT_ENCODED;
+               return (is_preview ? MM_PIXEL_FORMAT_ENCODED_MJPEG : MM_PIXEL_FORMAT_ENCODED);
        else if (!strcmp(media_type, "video/x-h264"))
                return MM_PIXEL_FORMAT_ENCODED_H264;
        else if (!strcmp(media_type, "video/x-jpeg"))
@@ -1889,6 +1989,94 @@ gboolean _mmcamcorder_link_elements(GList *element_list)
        return TRUE;
 }
 
+GstCaps *_mmcamcorder_get_video_caps(MMHandleType handle, MMPixelFormatType format, int width, int height, int fps, int rotate)
+{
+       int codec_type = MM_IMAGE_CODEC_JPEG;
+       guint32 fourcc = 0;
+       char fourcc_string[sizeof(guint32) + 1];
+#ifdef _MMCAMCORDER_PRODUCT_TV
+       int maxwidth = 0;
+       int maxheight = 0;
+       int display_surface_type = MM_DISPLAY_SURFACE_NULL;
+#endif /* _MMCAMCORDER_PRODUCT_TV */
+       gchar *caps_string = NULL;
+       GstCaps *caps = NULL;;
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+
+       switch (format) {
+       case MM_PIXEL_FORMAT_ENCODED_H264:
+#ifdef _MMCAMCORDER_PRODUCT_TV
+               mm_camcorder_get_attributes(handle, NULL,
+                       MMCAM_DISPLAY_SURFACE, &display_surface_type,
+                       NULL);
+               if (display_surface_type != MM_DISPLAY_SURFACE_NULL &&
+                       __mmcamcorder_find_max_resolution(handle, &maxwidth, &maxheight) == false) {
+                       MMCAM_LOG_ERROR("can not find max resolution limitation");
+                       return false;
+               } else if (display_surface_type == MM_DISPLAY_SURFACE_NULL) {
+                       maxwidth = width;
+                       maxheight = height;
+               }
+#endif /* _MMCAMCORDER_PRODUCT_TV */
+               caps = gst_caps_new_simple("video/x-h264",
+                       "stream-format", G_TYPE_STRING, "byte-stream",
+#ifdef _MMCAMCORDER_PRODUCT_TV
+                       "maxwidth", G_TYPE_INT, maxwidth,
+                       "maxheight", G_TYPE_INT, maxheight,
+                       "alignment", G_TYPE_STRING, "au",
+#endif /* _MMCAMCORDER_PRODUCT_TV */
+                       NULL);
+               break;
+       case MM_PIXEL_FORMAT_ENCODED_MJPEG:
+#ifdef _MMCAMCORDER_PRODUCT_TV
+               caps = gst_caps_new_empty_simple("video/x-jpeg");
+#else
+               caps = gst_caps_new_empty_simple("image/jpeg");
+#endif
+               break;
+       case MM_PIXEL_FORMAT_ENCODED_VP8:
+               caps = gst_caps_new_empty_simple("video/x-vp8");
+               break;
+       case MM_PIXEL_FORMAT_ENCODED_VP9:
+               caps = gst_caps_new_empty_simple("video/x-vp9");
+               break;
+       default:
+               mm_camcorder_get_attributes(handle, NULL,
+                       MMCAM_IMAGE_ENCODER, &codec_type,
+                       NULL);
+
+               fourcc = (guint32)_mmcamcorder_get_fourcc(format, codec_type, hcamcorder->use_zero_copy_format);
+               snprintf(fourcc_string, sizeof(fourcc_string), "%"GST_FOURCC_FORMAT, GST_FOURCC_ARGS(fourcc));
+               caps = gst_caps_new_simple("video/x-raw",
+                       "format", G_TYPE_STRING, fourcc_string,
+                       NULL);
+               break;
+       }
+
+       gst_caps_set_simple(caps,
+               "width", G_TYPE_INT, width,
+               "height", G_TYPE_INT, height,
+               NULL);
+
+       if (fps > 0) {
+               gst_caps_set_simple(caps,
+                       "framerate", GST_TYPE_FRACTION, fps, 1,
+                       NULL);
+       }
+
+       if (rotate >= 0) {
+               gst_caps_set_simple(caps,
+                       "rotate", G_TYPE_INT, rotate,
+                       NULL);
+       }
+
+       caps_string = gst_caps_to_string(caps);
+       MMCAM_LOG_INFO("caps[%s]", caps_string);
+       g_free(caps_string);
+
+       return caps;
+}
+
 gboolean _mmcamcorder_resize_frame(unsigned char *src_data, unsigned int src_width, unsigned int src_height, unsigned int src_length, int src_format,
        unsigned char **dst_data, unsigned int *dst_width, unsigned int *dst_height, size_t *dst_length)
 {
@@ -2469,7 +2657,8 @@ int _mmcamcorder_get_audiosrc_blocksize(int samplerate, int format, int channel,
 
 gboolean _mmcamcorder_is_encoded_preview_pixel_format(int pixel_format)
 {
-       return (pixel_format == MM_PIXEL_FORMAT_ENCODED_H264 ||
+       return (pixel_format == MM_PIXEL_FORMAT_ENCODED ||
+               pixel_format == MM_PIXEL_FORMAT_ENCODED_H264 ||
                pixel_format == MM_PIXEL_FORMAT_ENCODED_MJPEG ||
                pixel_format == MM_PIXEL_FORMAT_ENCODED_VP8 ||
                pixel_format == MM_PIXEL_FORMAT_ENCODED_VP9);
@@ -2519,3 +2708,33 @@ void _mmcamcorder_measure_fps(void *data)
 
        MMCAM_LOG_INFO("current fps[%d], average[%d]", kpi->current_fps, kpi->average_fps);
 }
+
+void _mmcamcorder_set_property_array_int(GstElement *element, const char *property_name, int *array, unsigned int array_length)
+{
+       unsigned int i = 0;
+       GValue value = G_VALUE_INIT;
+       GValue tmp = G_VALUE_INIT;
+
+       mmf_return_if_fail(element);
+       mmf_return_if_fail(property_name);
+       mmf_return_if_fail(array);
+
+       g_value_init(&value, GST_TYPE_ARRAY);
+       g_value_init(&tmp, G_TYPE_INT);
+
+       MMCAM_LOG_INFO("set element[%s], property[%s], array_length[%d]",
+               GST_ELEMENT_NAME(element), property_name, array_length);
+
+       gst_value_array_init(&value, array_length);
+
+       for (i = 0 ; i < array_length ; i++) {
+               MMCAM_LOG_INFO("array[%u] %d", i, array[i]);
+               g_value_set_int(&tmp, array[i]);
+               gst_value_array_append_value(&value, &tmp);
+       }
+
+       g_object_set_property(G_OBJECT(element), property_name, &value);
+
+       g_value_unset(&tmp);
+       g_value_unset(&value);
+}