X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmm_camcorder_gstcommon.c;h=a0da705c4b4f53ff194cda4ad7fbae0c78cfd904;hb=1044299a1d7b6c0b0ea979fe5d244af8dcca3741;hp=cd1db492dbcc20284108d6cf2de8f290acb1f016;hpb=57b38c21526cd590f392f6d37e2c1aa89add1ee5;p=platform%2Fcore%2Fmultimedia%2Flibmm-camcorder.git diff --git a/src/mm_camcorder_gstcommon.c b/src/mm_camcorder_gstcommon.c index cd1db49..a0da705 100644 --- a/src/mm_camcorder_gstcommon.c +++ b/src/mm_camcorder_gstcommon.c @@ -155,6 +155,10 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_push_buffer_to_record(Gst static int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate); static guint32 _mmcamcorder_convert_fourcc_string_to_value(const gchar* format_name); +#ifdef _MMCAMCORDER_PRODUCT_TV +static bool __mmcamcorder_find_max_resolution(MMHandleType handle, gint *max_width, gint *max_height); +#endif /* _MMCAMCORDER_PRODUCT_TV */ + /*======================================================================================= | FUNCTION DEFINITIONS | =======================================================================================*/ @@ -188,7 +192,10 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) char decoder_name[20] = {'\0',}; #endif /* _MMCAMCORDER_RM_SUPPORT */ GstElement *sink_element = NULL; + GstCameraControl *control = NULL; int sink_element_size = 0; + int *fds = NULL; + int fd_number = 0; GList *element_list = NULL; @@ -248,6 +255,21 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) return err; } + if (hcamcorder->support_user_buffer) { + err = mm_camcorder_get_attributes(handle, NULL, + MMCAM_USER_BUFFER_FD, &fds, &fd_number, + NULL); + if (err != MM_ERROR_NONE || fd_number < 1) { + _mmcam_dbg_err("get user buffer fd failed 0x%x, number %d", err, fd_number); + return err; + } + + /* + for (i = 0 ; i < fd_number ; i++) + _mmcam_dbg_log("fds[%d] %d", i, fds[i]); + */ + } + /* Get fourcc from picture format */ sc->fourcc = _mmcamcorder_get_fourcc(sc->info_image->preview_format, codectype, hcamcorder->use_zero_copy_format); @@ -294,8 +316,17 @@ int _mmcamcorder_create_preview_elements(MMHandleType handle) /* Set video device index */ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "camera-id", input_index->default_value); + /* set user buffer fd to videosrc element */ + if (hcamcorder->support_user_buffer) { + control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst); + if (!gst_camera_control_set_user_buffer_fd(control, fds, fd_number)) { + _mmcam_dbg_err("set user buffer fd failed"); + goto pipeline_creation_error; + } + } + /* make demux and decoder for H264 stream from videosrc */ - if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { + if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264 && display_surface_type != MM_DISPLAY_SURFACE_NULL) { int preview_bitrate = 0; int gop_interval = 0; const char *videodecoder_name = NULL; @@ -1350,7 +1381,8 @@ int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* Videosi #ifdef _MMCAMCORDER_RM_SUPPORT int display_scaler = 0; #endif /* _MMCAMCORDER_RM_SUPPORT */ - int *overlay = NULL; + int *dp_handle = NULL; + MMCamWindowInfo *window_info = NULL; gulong xid; char *err_name = NULL; const char *videosink_name = NULL; @@ -1380,7 +1412,7 @@ int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* Videosi MMCAM_DISPLAY_ROTATION, &rotation, MMCAM_DISPLAY_FLIP, &flip, MMCAM_DISPLAY_VISIBLE, &visible, - MMCAM_DISPLAY_HANDLE, (void**)&overlay, &size, + MMCAM_DISPLAY_HANDLE, (void **)&dp_handle, &size, MMCAM_DISPLAY_MODE, &display_mode, MMCAM_DISPLAY_GEOMETRY_METHOD, &display_geometry_method, MMCAM_DISPLAY_SCALE, &zoom_attr, @@ -1404,13 +1436,12 @@ int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* Videosi return MM_ERROR_CAMCORDER_INTERNAL; } - _mmcam_dbg_log("(overlay=%p, size=%d)", overlay, size); + _mmcam_dbg_log("(dp_handle=%p, size=%d)", dp_handle, size); /* Set display handle */ - if (!strcmp(videosink_name, "xvimagesink") || - !strcmp(videosink_name, "ximagesink")) { - if (overlay) { - xid = *overlay; + if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "ximagesink")) { + if (dp_handle) { + xid = *dp_handle; _mmcam_dbg_log("xid = %lu )", xid); gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), xid); } else { @@ -1424,22 +1455,46 @@ int _mmcamcorder_videosink_window_set(MMHandleType handle, type_element* Videosi MMCAMCORDER_G_OBJECT_SET(vsink, "device-scaler", display_scaler); #endif /* _MMCAMCORDER_RM_SUPPORT */ } else if (!strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "evaspixmapsink")) { - _mmcam_dbg_log("videosink : %s, handle : %p", videosink_name, overlay); + _mmcam_dbg_log("videosink : %s, handle : %p", videosink_name, dp_handle); - if (overlay) { - MMCAMCORDER_G_OBJECT_SET_POINTER(vsink, "evas-object", overlay); + if (dp_handle) { + MMCAMCORDER_G_OBJECT_SET_POINTER(vsink, "evas-object", dp_handle); MMCAMCORDER_G_OBJECT_SET(vsink, "origin-size", !do_scaling); } else { _mmcam_dbg_err("display handle(eavs object) is NULL"); return MM_ERROR_CAMCORDER_INVALID_ARGUMENT; } - } else if (!strcmp(videosink_name, "tizenwlsink") || !strcmp(videosink_name, "directvideosink")) { - if (overlay) { - _mmcam_dbg_log("wayland global surface id : %d", *(int *)(overlay)); - gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(vsink), (guintptr)*(int *)(overlay)); + } else if (!strcmp(videosink_name, "tizenwlsink")) { + if (dp_handle) { + window_info = (MMCamWindowInfo *)dp_handle; + _mmcam_dbg_log("wayland global surface id : %d", window_info->surface_id); + gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(vsink), window_info->surface_id); } else { _mmcam_dbg_warn("Handle is NULL. skip setting."); } + } else if (!strcmp(videosink_name, "directvideosink")) { + if (dp_handle) { + window_info = (MMCamWindowInfo *)dp_handle; + _mmcam_dbg_log("wayland global surface id : %d, x,y,w,h (%d,%d,%d,%d)", + window_info->surface_id, + window_info->rect.x, + window_info->rect.y, + window_info->rect.width, + window_info->rect.height); + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), (guintptr)window_info->surface_id); + gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(vsink), + window_info->rect.x, + window_info->rect.y, + window_info->rect.width, + window_info->rect.height); + } else { + _mmcam_dbg_warn("dp_handle is null"); + } +#ifdef _MMCAMCORDER_RM_SUPPORT + if (hcamcorder->request_resources.category_id[0] == RM_CATEGORY_VIDEO_DECODER_SUB) + display_scaler = 1; + MMCAMCORDER_G_OBJECT_SET(vsink, "device-scaler", display_scaler); +#endif /* _MMCAMCORDER_RM_SUPPORT */ } else { _mmcam_dbg_warn("Who are you?? (Videosink: %s)", videosink_name); } @@ -1669,10 +1724,12 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP GstMemory *memory = NULL; GstMapInfo mapinfo; - state = _mmcamcorder_get_state((MMHandleType)hcamcorder); - if (state < MM_CAMCORDER_STATE_PREPARE) { - _mmcam_dbg_warn("Not ready for stream callback"); - return GST_PAD_PROBE_OK; + if (sc->info_image->preview_format != MM_PIXEL_FORMAT_ENCODED_H264) { + state = _mmcamcorder_get_state((MMHandleType)hcamcorder); + if (state < MM_CAMCORDER_STATE_PREPARE) { + _mmcam_dbg_warn("Not ready for stream callback"); + return GST_PAD_PROBE_OK; + } } caps = gst_pad_get_current_caps(pad); @@ -1718,7 +1775,10 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP } /* set size and timestamp */ - memory = gst_buffer_peek_memory(buffer, 0); + if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) + memory = gst_buffer_get_all_memory(buffer); + else + memory = gst_buffer_peek_memory(buffer, 0); if (!memory) { _mmcam_dbg_err("GstMemory get failed from buffer %p", buffer); return GST_PAD_PROBE_OK; @@ -1904,6 +1964,8 @@ static GstPadProbeReturn __mmcamcorder_video_dataprobe_preview(GstPad *pad, GstP /* unmap memory */ if (mapinfo.data) gst_memory_unmap(memory, &mapinfo); + if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) + gst_memory_unref(memory); } return GST_PAD_PROBE_OK; @@ -2164,7 +2226,7 @@ GstPadProbeReturn __mmcamcorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo const GstSegment *segment; gst_event_parse_segment(event, &segment); if (segment->format == GST_FORMAT_BYTES) { - _mmcam_dbg_log("change current offset %llu -> %llu", + _mmcam_dbg_log("change current offset %llu -> %"G_GUINT64_FORMAT, sc->muxed_stream_offset, segment->start); sc->muxed_stream_offset = (unsigned long long)segment->start; @@ -2493,13 +2555,6 @@ bool _mmcamcorder_set_videosrc_caps(MMHandleType handle, unsigned int fourcc, in gboolean do_set_caps = FALSE; GstCaps *caps = NULL; -#ifdef _MMCAMCORDER_PRODUCT_TV - GstPad *sinkpad; - GstCaps *decsink_caps = NULL; - GstStructure *decsink_struct = NULL; - int maxwidth = 0; - int maxheight = 0; -#endif /*_MMCAMCORDER_PRODUCT_TV */ mmf_camcorder_t *hcamcorder = NULL; _MMCamcorderSubContext *sc = NULL; @@ -2662,34 +2717,21 @@ bool _mmcamcorder_set_videosrc_caps(MMHandleType handle, unsigned int fourcc, in if (do_set_caps) { if (sc->info_image->preview_format == MM_PIXEL_FORMAT_ENCODED_H264) { #ifdef _MMCAMCORDER_PRODUCT_TV - sinkpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_DECODE].gst, "sink"); - if (!sinkpad) { - _mmcam_dbg_err("There are no decoder caps"); - return FALSE; - } - - decsink_caps = gst_pad_get_pad_template_caps(sinkpad); - if (!decsink_caps) { - gst_object_unref(sinkpad); - _mmcam_dbg_err("There is no decoder sink caps"); - return FALSE; - } + gint maxwidth = 0; + gint maxheight = 0; + int display_surface_type = MM_DISPLAY_SURFACE_NULL; + mm_camcorder_get_attributes(handle, NULL, + MMCAM_DISPLAY_SURFACE, &display_surface_type, + NULL); - decsink_struct = gst_caps_get_structure(decsink_caps, 0); - if (!decsink_struct) { - _mmcam_dbg_err("There are no structure from caps"); - gst_object_unref(decsink_caps); - gst_object_unref(sinkpad); - return FALSE; + if (display_surface_type != MM_DISPLAY_SURFACE_NULL && __mmcamcorder_find_max_resolution(handle, &maxwidth, &maxheight) == false) { + _mmcam_dbg_err("can not find max resolution limitation"); + return false; + } else if (display_surface_type == MM_DISPLAY_SURFACE_NULL) { + maxwidth = set_width; + maxheight = set_height; } - - if (gst_structure_has_field(decsink_struct, "maxwidth")) - gst_structure_get_int(decsink_struct, "maxwidth", &maxwidth); - - if (gst_structure_has_field(decsink_struct, "maxheight")) - gst_structure_get_int(decsink_struct, "maxheight", &maxheight); #endif /* _MMCAMCORDER_PRODUCT_TV */ - caps = gst_caps_new_simple("video/x-h264", "width", G_TYPE_INT, set_width, "height", G_TYPE_INT, set_height, @@ -2701,11 +2743,6 @@ bool _mmcamcorder_set_videosrc_caps(MMHandleType handle, unsigned int fourcc, in "alignment", G_TYPE_STRING, "au", #endif /* _MMCAMCORDER_PRODUCT_TV */ NULL); - -#ifdef _MMCAMCORDER_PRODUCT_TV - gst_object_unref(decsink_caps); - gst_object_unref(sinkpad); -#endif /* _MMCAMCORDER_PRODUCT_TV */ } else { char fourcc_string[sizeof(fourcc)+1]; strncpy(fourcc_string, (char*)&fourcc, sizeof(fourcc)); @@ -3146,3 +3183,65 @@ bool _mmcamcorder_recreate_decoder_for_encoded_preview(MMHandleType handle) return TRUE; } + +#ifdef _MMCAMCORDER_PRODUCT_TV +static bool __mmcamcorder_find_max_resolution(MMHandleType handle, gint *max_width, gint *max_height) +{ + _MMCamcorderSubContext *sc = NULL; + mmf_camcorder_t *hcamcorder = NULL; + int index = 0; + const gchar *mime = NULL; + GstPad *sinkpad; + GstCaps *decsink_caps = NULL; + GstStructure *decsink_struct = NULL; + + mmf_return_val_if_fail(handle, false); + mmf_return_val_if_fail(max_width, false); + mmf_return_val_if_fail(max_height, false); + + hcamcorder = MMF_CAMCORDER(handle); + mmf_return_val_if_fail(hcamcorder, false); + + sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder); + + sinkpad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_VIDEOSRC_DECODE].gst, "sink"); + if (!sinkpad) { + _mmcam_dbg_err("There are no decoder caps"); + return false; + } + + decsink_caps = gst_pad_get_pad_template_caps(sinkpad); + if (!decsink_caps) { + gst_object_unref(sinkpad); + _mmcam_dbg_err("There is no decoder sink caps"); + return false; + } + + for (index = 0; index < gst_caps_get_size(decsink_caps); index++) { + decsink_struct = gst_caps_get_structure(decsink_caps, index); + if (!decsink_struct) { + _mmcam_dbg_err("There are no structure from caps"); + gst_object_unref(decsink_caps); + gst_object_unref(sinkpad); + return false; + } + mime = gst_structure_get_name(decsink_struct); + if (!strcmp(mime, "video/x-h264")) { + _mmcam_dbg_log("h264 caps structure found"); + if (gst_structure_has_field(decsink_struct, "maxwidth")) + *max_width = gst_value_get_int_range_max(gst_structure_get_value(decsink_struct, "maxwidth")); + if (gst_structure_has_field(decsink_struct, "maxheight")) + *max_height = gst_value_get_int_range_max(gst_structure_get_value(decsink_struct, "maxheight")); + break; + } + } + _mmcam_dbg_log("maxwidth = %d , maxheight = %d", (int)*max_width, (int)*max_height); + gst_object_unref(decsink_caps); + gst_object_unref(sinkpad); + + if (*max_width <= 0 || *max_height <= 0) + return false; + + return true; +} +#endif /* _MMCAMCORDER_PRODUCT_TV */