Add new field to frame meta for lux index
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_util.c
index 3babfdd..788bf0f 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,46 +1627,101 @@ 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;
-       GstVideoInfo vinfo;
-       MMPixelFormatType type = MM_PIXEL_FORMAT_INVALID;
+       const char *format;
 
        mmf_return_val_if_fail(caps != NULL, MM_PIXEL_FORMAT_INVALID);
 
-       media_type = gst_structure_get_name(gst_caps_get_structure(caps, 0));
-       if (media_type == NULL) {
-               MMCAM_LOG_ERROR("failed to get media_type");
-               return MM_PIXEL_FORMAT_INVALID;
+       if (_mmcamcorder_get_log_level() >= MM_CAMCORDER_LOG_LEVEL_DEBUG) {
+               caps_string = gst_caps_to_string(caps);
+               MMCAM_LOG_DEBUG("caps[%s]", caps_string);
+               g_free(caps_string);
        }
 
-       if (!gst_video_info_from_caps(&vinfo, caps)) {
-               MMCAM_LOG_ERROR("get video info failed[media type:%s]", media_type);
+       media_type = gst_structure_get_name(gst_caps_get_structure(caps, 0));
+       if (!media_type) {
+               MMCAM_LOG_ERROR("failed to get media_type");
                return MM_PIXEL_FORMAT_INVALID;
        }
 
-       if (GST_VIDEO_INFO_IS_YUV(&vinfo))
-               type = _mmcamcorder_get_pixtype(gst_video_format_to_fourcc(GST_VIDEO_INFO_FORMAT(&vinfo)));
-       else if (GST_VIDEO_INFO_IS_RGB(&vinfo))
-               type = MM_PIXEL_FORMAT_RGB888;
-       else if (!strcmp(media_type, "image/jpeg"))
-               type = MM_PIXEL_FORMAT_ENCODED;
+       if (!strcmp(media_type, "image/jpeg"))
+               return (is_preview ? MM_PIXEL_FORMAT_ENCODED_MJPEG : MM_PIXEL_FORMAT_ENCODED);
        else if (!strcmp(media_type, "video/x-h264"))
-               type = MM_PIXEL_FORMAT_ENCODED_H264;
+               return MM_PIXEL_FORMAT_ENCODED_H264;
        else if (!strcmp(media_type, "video/x-jpeg"))
-               type = MM_PIXEL_FORMAT_ENCODED_MJPEG;
+               return MM_PIXEL_FORMAT_ENCODED_MJPEG;
        else if (!strcmp(media_type, "video/x-vp8"))
-               type = MM_PIXEL_FORMAT_ENCODED_VP8;
+               return MM_PIXEL_FORMAT_ENCODED_VP8;
        else if (!strcmp(media_type, "video/x-vp9"))
-               type = MM_PIXEL_FORMAT_ENCODED_VP9;
+               return MM_PIXEL_FORMAT_ENCODED_VP9;
 
-       if (type == MM_PIXEL_FORMAT_INVALID)
-               MMCAM_LOG_ERROR("Not supported format[%s,GST:%d]", media_type, GST_VIDEO_INFO_FORMAT(&vinfo));
-       else
-               MMCAM_LOG_DEBUG("Type[%d]", type);
+       format = gst_structure_get_string(gst_caps_get_structure(caps, 0), "format");
+       if (!format) {
+               caps_string = gst_caps_to_string(caps);
+               MMCAM_LOG_ERROR("unsupported caps[%s]", caps_string);
+               g_free(caps_string);
 
-       return type;
+               return MM_PIXEL_FORMAT_INVALID;
+       }
+
+       return _mmcamcorder_get_pixtype(GST_STR_FOURCC(format));
+}
+
+
+MMPixelFormatType _mmcamcorder_get_pixel_format2(GstCameraControlImageFormat img_fmt)
+{
+       const MMPixelFormatType pixel_format_table[] = {
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_NV12] = MM_PIXEL_FORMAT_NV12,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_NV21] = MM_PIXEL_FORMAT_NV21,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_I420] = MM_PIXEL_FORMAT_I420,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_YV12] = MM_PIXEL_FORMAT_YV12,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_YUYV] = MM_PIXEL_FORMAT_YUYV,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_UYVY] = MM_PIXEL_FORMAT_UYVY,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_BGRA] = MM_PIXEL_FORMAT_RGBA,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_ARGB] = MM_PIXEL_FORMAT_ARGB,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_JPEG] = MM_PIXEL_FORMAT_ENCODED,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_H264] = MM_PIXEL_FORMAT_ENCODED_H264,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_MJPEG] = MM_PIXEL_FORMAT_ENCODED_MJPEG,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_VP8] = MM_PIXEL_FORMAT_ENCODED_VP8,
+               [GST_CAMERA_CONTROL_IMAGE_FORMAT_VP9] = MM_PIXEL_FORMAT_ENCODED_VP9,
+       };
+
+       if (img_fmt < GST_CAMERA_CONTROL_IMAGE_FORMAT_NV12 || img_fmt > GST_CAMERA_CONTROL_IMAGE_FORMAT_VP9) {
+               MMCAM_LOG_ERROR("invalid format[%d], return default[NV12]", img_fmt);
+               return MM_PIXEL_FORMAT_NV12;
+       }
+
+       return pixel_format_table[img_fmt];
+}
+
+
+GstCameraControlImageFormat _mmcamcorder_get_camera_control_image_format(int pixel_format)
+{
+       const GstCameraControlImageFormat img_fmt_table[] = {
+               [MM_PIXEL_FORMAT_NV12] = GST_CAMERA_CONTROL_IMAGE_FORMAT_NV12,
+               [MM_PIXEL_FORMAT_NV21] = GST_CAMERA_CONTROL_IMAGE_FORMAT_NV21,
+               [MM_PIXEL_FORMAT_I420] = GST_CAMERA_CONTROL_IMAGE_FORMAT_I420,
+               [MM_PIXEL_FORMAT_YV12] = GST_CAMERA_CONTROL_IMAGE_FORMAT_YV12,
+               [MM_PIXEL_FORMAT_YUYV] = GST_CAMERA_CONTROL_IMAGE_FORMAT_YUYV,
+               [MM_PIXEL_FORMAT_UYVY] = GST_CAMERA_CONTROL_IMAGE_FORMAT_UYVY,
+               [MM_PIXEL_FORMAT_RGBA] = GST_CAMERA_CONTROL_IMAGE_FORMAT_BGRA,
+               [MM_PIXEL_FORMAT_ARGB] = GST_CAMERA_CONTROL_IMAGE_FORMAT_ARGB,
+               [MM_PIXEL_FORMAT_ENCODED] = GST_CAMERA_CONTROL_IMAGE_FORMAT_JPEG,
+               [MM_PIXEL_FORMAT_ENCODED_H264] = GST_CAMERA_CONTROL_IMAGE_FORMAT_H264,
+               [MM_PIXEL_FORMAT_ENCODED_MJPEG] = GST_CAMERA_CONTROL_IMAGE_FORMAT_MJPEG,
+               [MM_PIXEL_FORMAT_ENCODED_VP8] = GST_CAMERA_CONTROL_IMAGE_FORMAT_VP8,
+               [MM_PIXEL_FORMAT_ENCODED_VP9] = GST_CAMERA_CONTROL_IMAGE_FORMAT_VP9
+       };
+
+       if (pixel_format < MM_PIXEL_FORMAT_NV12 || pixel_format > MM_PIXEL_FORMAT_ENCODED_VP9) {
+               MMCAM_LOG_ERROR("invalid format[%d], return default[NV12]", pixel_format);
+               return GST_CAMERA_CONTROL_IMAGE_FORMAT_NV12;
+       }
+
+       return img_fmt_table[pixel_format];
 }
 
 
@@ -1834,6 +1989,95 @@ 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: /* fall through */
+       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)
 {
@@ -2414,7 +2658,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);
@@ -2455,8 +2700,9 @@ void _mmcamcorder_measure_fps(void *data)
 
        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);
+       diff_sec = current_video_time.tv_sec - kpi->init_video_time.tv_sec;
+       if (diff_sec != 0)
+               kpi->average_fps = (int)kpi->video_framecount / diff_sec;
 
        kpi->last_framecount = frame_count;
        kpi->last_video_time.tv_sec = current_video_time.tv_sec;
@@ -2464,3 +2710,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);
+}