X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmm_streamrecorder_recorder.c;h=27b54a47aacf9add0e5cfa245c1ae328893ca7c0;hb=a9cf01118960a830498eac6770e59ba1f16c80d0;hp=02cb2b181ba366a72db8e5b0da2d47cc2afc8801;hpb=ec26bef8c238b9a97feb8ecd831d8f16a9ee6882;p=platform%2Fcore%2Fmultimedia%2Flibmm-streamrecorder.git diff --git a/src/mm_streamrecorder_recorder.c b/src/mm_streamrecorder_recorder.c index 02cb2b1..27b54a4 100644 --- a/src/mm_streamrecorder_recorder.c +++ b/src/mm_streamrecorder_recorder.c @@ -67,7 +67,7 @@ int _mmstreamrecorder_create_pipeline(MMHandleType handle) _MMStreamRecorderSubContext *sc = NULL; GstElement *pipeline = NULL; - _mmstreamrec_dbg_log("handle : %x", handle); + _mmstreamrec_dbg_log("handle : %p", handle); mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); @@ -158,15 +158,23 @@ int _mmstreamrecorder_create_recorder_pipeline(MMHandleType handle) { int i = 0; int err = MM_ERROR_NONE; - int audio_enable = FALSE; + int rec_mode = 0; + int width = 0; + int height = 0; + int video_src_format = 0; + int frame_rate = 0; + int filename_size = 0; + gboolean audio_enable = FALSE; GstBus *bus = NULL; GstPad *srcpad = NULL; GstPad *sinkpad = NULL; - + GstCaps *caps = NULL; + GList *element_list = NULL; + GstStructure* pulse_property = NULL; unsigned int video_codec = MM_VIDEO_CODEC_INVALID; unsigned int file_format = MM_FILE_FORMAT_INVALID; char *err_name = NULL; - + char *filename = NULL; mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); _MMStreamRecorderSubContext *sc = NULL; @@ -177,88 +185,88 @@ int _mmstreamrecorder_create_recorder_pipeline(MMHandleType handle) _mmstreamrec_dbg_warn("start"); - err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_ENCODER, &video_codec, MMSTR_FILE_FORMAT, &file_format, NULL); + err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_ENCODER, &video_codec, MMSTR_FILE_FORMAT, &file_format, MMSTR_RECORDER_MODE, &rec_mode, NULL); if (err != MM_ERROR_NONE) { _mmstreamrec_dbg_warn("Get attrs fail. (%s:%x)", err_name, err); SAFE_FREE(err_name); return err; } - err = _mmstreamrecorder_check_videocodec_fileformat_compatibility(video_codec, file_format); - if (err != MM_ERROR_NONE) - return err; + if (rec_mode == MM_STREAMRECORDER_MODE_STREAM_BUFFER) { + _mmstreamrec_dbg_log("Recording Mode [%d]", MM_STREAMRECORDER_MODE_STREAM_BUFFER); + err = _mmstreamrecorder_check_videocodec_fileformat_compatibility(video_codec, file_format); + if (err != MM_ERROR_NONE) + return err; - /* Main pipeline */ - _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err); + /* Main pipeline */ + _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err); - /* get audio disable */ - mm_streamrecorder_get_attributes(handle, NULL, MMSTR_AUDIO_ENABLE, &audio_enable, NULL); - sc->audio_enable = audio_enable; + /* get audio disable */ + mm_streamrecorder_get_attributes(handle, NULL, MMSTR_AUDIO_ENABLE, &audio_enable, NULL); + sc->audio_enable = audio_enable; - _mmstreamrec_dbg_log("AUDIO DISABLE : %d", sc->audio_enable); + _mmstreamrec_dbg_log("AUDIO DISABLE : %d", sc->audio_enable); - if (sc->audio_enable == TRUE) { - /* create audiosrc bin */ - err = _mmstreamrecorder_create_audiosrc_bin((MMHandleType) hstreamrecorder); + if (sc->audio_enable == TRUE) { + /* create audiosrc bin */ + err = _mmstreamrecorder_create_audiosrc_bin((MMHandleType) hstreamrecorder); + if (err != MM_ERROR_NONE) + return err; + } + + err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO); if (err != MM_ERROR_NONE) return err; - } - - err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO); - if (err != MM_ERROR_NONE) - return err; - - if (sc->audio_enable == TRUE) { - gst_bin_add(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst); - } - /* add element and encodesink bin to encode main pipeline */ - gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, NULL); + if (sc->audio_enable == TRUE) + gst_bin_add(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst); - /* Link each element : appsrc - capsfilter - encodesink bin */ - srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src"); - sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "sink"); - _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error); + /* add element and encodesink bin to encode main pipeline */ + gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, NULL); - srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "src"); - sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "video_sink0"); - _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error); + /* Link each element : appsrc - capsfilter - encodesink bin */ + srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src"); + sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "sink"); + _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error); - if (sc->audio_enable == TRUE) { - srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src"); - sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0"); + srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "src"); + sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "video_sink0"); _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error); - } - if (sc->audio_enable == TRUE) { - sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "sink"); - MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audioque_dataprobe, hstreamrecorder); - gst_object_unref(sinkpad); - sinkpad = NULL; + if (sc->audio_enable == TRUE) { + srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src"); + sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0"); + _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error); + } - if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst) { - srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst, "src"); + if (sc->audio_enable == TRUE) { + sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "sink"); + MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_audioque_dataprobe, hstreamrecorder); + gst_object_unref(sinkpad); + sinkpad = NULL; + + if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst) { + srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC_QUE].gst, "src"); + MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder); + gst_object_unref(srcpad); + srcpad = NULL; + } + } + + if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst) { + srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst, "src"); MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder); gst_object_unref(srcpad); srcpad = NULL; } - } - - if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst) { - srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC_QUE].gst, "src"); - MMSTREAMRECORDER_ADD_EVENT_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_eventprobe_monitor, hstreamrecorder); - gst_object_unref(srcpad); - srcpad = NULL; - } - if (sc->audio_enable == FALSE) { - sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink"); - MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_audio_disable, hstreamrecorder); - gst_object_unref(sinkpad); - sinkpad = NULL; - } + if (sc->audio_enable == FALSE) { + sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink"); + MMSTREAMRECORDER_ADD_BUFFER_PROBE(sinkpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_audio_disable, hstreamrecorder); + gst_object_unref(sinkpad); + sinkpad = NULL; + } - if (!strcmp(/*gst_element_rsink_name */"filesink", "filesink")) { srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src"); MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_VIDEOREC, __mmstreamrecorder_video_dataprobe_record, hstreamrecorder); gst_object_unref(srcpad); @@ -270,6 +278,185 @@ int _mmstreamrecorder_create_recorder_pipeline(MMHandleType handle) gst_object_unref(srcpad); srcpad = NULL; } + } else if (rec_mode == MM_STREAMRECORDER_MODE_DEVICE_LOOPBACK) { + _mmstreamrec_dbg_log("Recording Mode [%d]", MM_STREAMRECORDER_MODE_DEVICE_LOOPBACK); + err = mm_streamrecorder_get_attributes(handle, NULL, MMSTR_VIDEO_RESOLUTION_WIDTH, &width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &height, MMSTR_AUDIO_ENABLE, &audio_enable, MMSTR_VIDEO_SOURCE_FORMAT, &video_src_format, MMSTR_VIDEO_FRAMERATE, &frame_rate, MMSTR_FILENAME, &filename, &filename_size, NULL); + _mmstreamrec_dbg_log("width [%d], height [%d], audio enable[%d], format [%d], framerate [%d] filename [%s]", width, height, audio_enable, video_src_format, frame_rate, filename); + + _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err); + + if (!hstreamrecorder->ini.hw_encoder_supported) { + _mmstreamrec_dbg_log("Screen is recorded with SW encoder."); + if (audio_enable) { + _mmstreamrec_dbg_log("Audio is enabled!"); + + /* Audio pipeline */ + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_SRC, "pulsesrc", "audio_source", element_list, err); + + pulse_property = gst_structure_new_from_string("props,media.role=loopback-mirroring"); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "stream-properties", pulse_property); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "do-timestamp", true); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "provide-clock", false); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_CONV, "audioconvert", "audio_converter", element_list, err); + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_ENC, "avenc_aac", "audio_encoder", element_list, err); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst, "compliance", -2); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_QUE, "queue", "audio_queue", element_list, err); + + gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), + sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, + sc->encode_element[_MMSTREAMRECORDER_AUDIO_CONV].gst, + sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst, + sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst, NULL); + } + + /* Video pipeline */ + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_SRC, "waylandsrc", "video_source", element_list, err); + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_CAPS, "capsfilter", "video_capsfilter", element_list, err); + + caps = gst_set_videosrcpad_caps_sw(MM_STREAMRECORDER_INPUT_FORMAT_BGRA, width, height, frame_rate, 1); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst, "caps", caps); + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_CONV, "videoconvert", "video_conveter", element_list, err); + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_ENC, "avenc_mpeg4", "video_encoder", element_list, err); + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_QUE, "queue", "video_queue", element_list, err); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_MUX, "avmux_mp4", "av_muxer", element_list, err); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_SINK, "filesink", "av_sink", element_list, err); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_SINK].gst, "location", filename); + + + gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), + sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst, + sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst, + sc->encode_element[_MMSTREAMRECORDER_VIDEO_CONV].gst, + sc->encode_element[_MMSTREAMRECORDER_VIDEO_ENC].gst, + sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst, NULL); + + gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), + sc->encode_element[_MMSTREAMRECORDER_MUX].gst, + sc->encode_element[_MMSTREAMRECORDER_SINK].gst, NULL); + if (audio_enable) { + if (!_MM_GST_ELEMENT_LINK_MANY(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_CONV].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst), NULL)) { + _mmstreamrec_dbg_log("AUDIO PIPELINE LINK MANY FAILED"); + } + + if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst))) { + _mmstreamrec_dbg_log("LINK BETWEEN AUDIO QUE AND MUX FAILED"); + } + } + + if (!_MM_GST_ELEMENT_LINK_MANY(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CONV].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_ENC].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst), NULL)) { + _mmstreamrec_dbg_log("VIDEO PIPELINE LINK MANY FAILED"); + } + + if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst))) { + _mmstreamrec_dbg_log("LINK BETWEEN VIDEO QUE AND MUX FAILED"); + } + + if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_SINK].gst))) { + _mmstreamrec_dbg_log("LINK BETWEEN MUX AND SINK FAILED"); + } + } else { + _mmstreamrec_dbg_log("Screen is recorded with HW encoder."); + if (audio_enable) { + _mmstreamrec_dbg_log("Audio is enabled!"); + + /* Audio pipeline */ + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_SRC, "pulsesrc", "audio_source", element_list, err); + + pulse_property = gst_structure_new_from_string("props,media.role=loopback-mirroring"); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "stream-properties", pulse_property); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "do-timestamp", true); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, "provide-clock", false); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_CONV, "audioconvert", "audio_converter", element_list, err); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_ENC, "avenc_aac", "audio_encoder", element_list, err); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst, "compliance", -2); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_AUDIO_QUE, "queue", "audio_queue", element_list, err); + + gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), + sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst, + sc->encode_element[_MMSTREAMRECORDER_AUDIO_CONV].gst, + sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst, + sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst, + sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst, NULL); + } + /* Video pipeline */ + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_SRC, "waylandsrc", "video_source", element_list, err); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_CAPS, "capsfilter", "video_capsfilter", element_list, err); + + caps = gst_set_videosrcpad_caps_hw(hstreamrecorder->ini.video_codec_element_hw, width, height, frame_rate, 1); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst, "caps", caps); + + if (!g_strcmp0(hstreamrecorder->ini.video_codec_element_hw, "sprd")){ + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_ENC, "sprdenc_h264", "video_encoder", element_list, err); + } else { + _mmstreamrec_dbg_warn("no matched hw codec element found."); + goto pipeline_creation_error; + } + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_VIDEO_QUE, "queue", "video_queue", element_list, err); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_MUX, "avmux_mp4", "av_muxer", element_list, err); + + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_SINK, "filesink", "av_sink", element_list, err); + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_SINK].gst, "location", filename); + + gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), + sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst, + sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst, + sc->encode_element[_MMSTREAMRECORDER_VIDEO_ENC].gst, + sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst, NULL); + + gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), + sc->encode_element[_MMSTREAMRECORDER_MUX].gst, + sc->encode_element[_MMSTREAMRECORDER_SINK].gst, NULL); + if (audio_enable) { + if (!_MM_GST_ELEMENT_LINK_MANY(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_SRC].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_CONV].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_ENC].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst), NULL)) { + _mmstreamrec_dbg_log("AUDIO PIPELINE LINK MANY FAILED"); + } + + if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_AUDIO_QUE].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst))) { + _mmstreamrec_dbg_log("LINK BETWEEN AUDIO QUE AND MUX FAILED"); + } + } + + if (!_MM_GST_ELEMENT_LINK_MANY(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_SRC].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_CAPS].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_ENC].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst), NULL)) { + _mmstreamrec_dbg_log("VIDEO PIPELINE LINK MANY FAILED"); + } + + if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_VIDEO_QUE].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst))) { + _mmstreamrec_dbg_log("LINK BETWEEN VIDEO QUE AND MUX FAILED"); + } + + if (!_MM_GST_ELEMENT_LINK(GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_MUX].gst), + GST_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_SINK].gst))) { + _mmstreamrec_dbg_log("LINK BETWEEN MUX AND SINK FAILED"); + } + } } bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst)); @@ -279,13 +466,12 @@ int _mmstreamrecorder_create_recorder_pipeline(MMHandleType handle) gst_object_unref(bus); bus = NULL; - return MM_ERROR_NONE; pipeline_creation_error: - for (i = _MMSTREAMRECORDER_AUDIOSRC_BIN; i <= _MMSTREAMRECORDER_ENCSINK_SINK; i++) { + for (i = _MMSTREAMRECORDER_AUDIOSRC_BIN; i <= _MMSTREAMRECORDER_ENCSINK_SINK; i++) _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, i); - } + _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE); return err; } @@ -376,7 +562,7 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde const char *str_aar = NULL; const char *str_acs = NULL; char *err_name = NULL; - + int ret = MM_ERROR_NONE; GstCaps *caps = NULL; GstPad *pad = NULL; GList *element_list = NULL; @@ -408,7 +594,12 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde finfo = sc->info_file; /* check element availability */ - mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_AUDIO_ENCODER, &audio_enc, MMSTR_AUDIO_CHANNEL, &channel, MMSTR_VIDEO_BITRATE, &v_bitrate, MMSTR_VIDEO_ENCODER, &video_enc, MMSTR_AUDIO_BITRATE, &a_bitrate, MMSTR_VIDEO_RESOLUTION_WIDTH, &video_width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &video_height, MMSTR_VIDEO_FRAMERATE, &video_fps, MMSTR_FILE_FORMAT, &file_format, MMSTR_AUDIO_SAMPLERATE, &audio_samplerate, MMSTR_AUDIO_SOURCE_FORMAT, &audio_src_format, MMSTR_VIDEO_SOURCE_FORMAT, &video_src_format, MMSTR_RECORDER_MODE, &rec_mode, NULL); + ret = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_AUDIO_ENCODER, &audio_enc, MMSTR_AUDIO_CHANNEL, &channel, MMSTR_VIDEO_BITRATE, &v_bitrate, MMSTR_VIDEO_ENCODER, &video_enc, MMSTR_AUDIO_BITRATE, &a_bitrate, MMSTR_VIDEO_RESOLUTION_WIDTH, &video_width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &video_height, MMSTR_VIDEO_FRAMERATE, &video_fps, MMSTR_FILE_FORMAT, &file_format, MMSTR_AUDIO_SAMPLERATE, &audio_samplerate, MMSTR_AUDIO_SOURCE_FORMAT, &audio_src_format, MMSTR_VIDEO_SOURCE_FORMAT, &video_src_format, MMSTR_RECORDER_MODE, &rec_mode, NULL); + if (ret != MM_ERROR_NONE) { + _mmstreamrec_dbg_err("Get attrs fail. (%s:%x)", err_name, ret); + SAFE_FREE(err_name); + return err; + } _mmstreamrec_dbg_err("audio encoder - %d , video encoder : %d", audio_enc, video_enc); _mmstreamrec_dbg_err("audio channel - %d , video v_bitrate : %d", channel, v_bitrate); @@ -432,14 +623,14 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC, hstreamrecorder->ini.name_of_encsink_src, "encodesink_src", element_list, err); _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT, "capsfilter", "encodesink_filter", element_list, err); - caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1); + caps = gst_set_videosrcpad_caps_sw(video_src_format, video_width, video_height, video_fps, 1); MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "caps", caps); if (caps) { gst_caps_unref(caps); caps = NULL; } - caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1); + caps = gst_set_videosrcpad_caps_sw(video_src_format, video_width, video_height, video_fps, 1); MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_FILT].gst, "caps", caps); if (caps) { gst_caps_unref(caps); @@ -452,14 +643,14 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde g_list_free(element_list); element_list = NULL; } - if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) { + if (rec_mode == MM_STREAMRECORDER_MODE_STREAM_BUFFER) { /* set appsrc as live source */ MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "is-live", hstreamrecorder->ini.encsink_src_islive); } } - _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN, "encodebin", "encodesink_encbin", element_list, err); + _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN, "tizenencodebin", "encodesink_encbin", element_list, err); _mmstreamrec_dbg_log("Profile[%d]", profile); @@ -478,9 +669,9 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde /* TODO : check the last value ( set ) */ MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "profile", hstreamrecorder->ini.encsink_bin_profile); - if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) { + if (rec_mode == MM_STREAMRECORDER_MODE_STREAM_BUFFER) MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-convert", hstreamrecorder->ini.encsink_bin_auto_audio_convert); - } + MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-audio-resample", hstreamrecorder->ini.encsink_bin_auto_audio_resample); MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace); MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "use-video-toggle", hstreamrecorder->ini.encsink_bin_use_video_toggle); @@ -502,8 +693,6 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde break; } _MMSTREAMRECORDER_ENCODEBIN_ELMGET(sc, _MMSTREAMRECORDER_ENCSINK_VENC, "video-encode", err); - /* _mmstreamrec_dbg_err(" hyuntae log = %p sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst = %p" ,sc, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst); */ - /* set color converter size */ MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vconv-name", hstreamrecorder->ini.name_of_encsink_bin_video_converter); @@ -511,14 +700,17 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "auto-colorspace", hstreamrecorder->ini.encsink_bin_auto_colorspace); - if (video_src_format == MM_STREAMRECORDER_INPUT_FORMAT_NV12) { + if (video_src_format == MM_STREAMRECORDER_INPUT_FORMAT_NV12 || + video_src_format == MM_STREAMRECORDER_INPUT_FORMAT_NV21) video_src_format = MM_STREAMRECORDER_INPUT_FORMAT_I420; - } - caps = gst_set_videosrcpad_caps(video_src_format, video_width, video_height, video_fps, 1); + + caps = gst_set_videosrcpad_caps_sw(video_src_format, video_width, video_height, video_fps, 1); MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "vcaps", caps); - if (video_src_format != MM_STREAMRECORDER_INPUT_FORMAT_NV12) { + + if (video_src_format != MM_STREAMRECORDER_INPUT_FORMAT_NV12 || + video_src_format != MM_STREAMRECORDER_INPUT_FORMAT_NV21) MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VCONV].gst, "dst-buffer-num", hstreamrecorder->ini.convert_output_buffer_num); - } + /* state tuning */ err = gst_pad_set_caps(gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "sink"), caps); err = MM_ERROR_NONE; @@ -562,8 +754,8 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "acaps", caps); { gchar *type = gst_caps_to_string(caps); - _mmstreamrec_dbg_warn("Set srcpad caps: %s", type); + g_free(type); } gst_caps_unref(caps); caps = NULL; @@ -649,7 +841,7 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde else info->max_time = ((guint64) imax_time) * 1000; /* to millisecond */ - finfo->filename = strdup(temp_filename); + finfo->filename = g_strdup(temp_filename); if (!finfo->filename) { _mmstreamrec_dbg_err("strdup was failed"); return err; @@ -661,11 +853,10 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) { /* video encoder attribute setting */ - if (v_bitrate > 0) { + if (v_bitrate > 0) MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "bitrate", v_bitrate); - } else { + else _mmstreamrec_dbg_warn("video bitrate is too small[%d], so skip setting. Use DEFAULT value.", v_bitrate); - } } if (sc->audio_enable == TRUE) { @@ -702,7 +893,7 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde _mmstreamrec_dbg_log("Element add complete"); if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_VIDEO) { - pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video"); + pad = gst_element_request_pad_simple(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "video"); if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("video_sink0", pad)) < 0) { gst_object_unref(pad); pad = NULL; @@ -714,7 +905,7 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde pad = NULL; if (sc->audio_enable == TRUE) { - pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio"); + pad = gst_element_request_pad_simple(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio"); if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) { gst_object_unref(pad); pad = NULL; @@ -726,7 +917,7 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde pad = NULL; } } else if (profile == MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO) { - pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio"); + pad = gst_element_request_pad_simple(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio"); if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("audio_sink0", pad)) < 0) { gst_object_unref(pad); pad = NULL; @@ -738,7 +929,7 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde pad = NULL; } else { /* for stillshot */ - pad = gst_element_get_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "image"); + pad = gst_element_request_pad_simple(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "image"); if (gst_element_add_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, gst_ghost_pad_new("image_sink0", pad)) < 0) { gst_object_unref(pad); pad = NULL; @@ -768,7 +959,7 @@ int _mmstreamrecorder_create_encodesink_bin(MMHandleType handle, MMStreamRecorde return MM_ERROR_NONE; - pipeline_creation_error: +pipeline_creation_error: _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_ENCBIN); _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SRC); _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_FILT); @@ -903,15 +1094,14 @@ int _mmstreamrecorder_create_audiosrc_bin(MMHandleType handle) } if (caps) { - if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) { + if (rec_mode == MM_STREAMRECORDER_MODE_STREAM_BUFFER) MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "caps", caps); - } + MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_FILT].gst), "caps", caps); { gchar *type = gst_caps_to_string(caps); - _mmstreamrec_dbg_err("_MMSTREAMRECORDER_AUDIOSRC_FILT %s", type); - + g_free(type); } gst_caps_unref(caps); caps = NULL; @@ -921,7 +1111,7 @@ int _mmstreamrecorder_create_audiosrc_bin(MMHandleType handle) goto pipeline_creation_error; } - if (rec_mode == MM_STREAMRECORDER_MODE_SCREENRECORD) { + if (rec_mode == MM_STREAMRECORDER_MODE_DEVICE_LOOPBACK) { #if 1 /* mic mode */ MMSTREAMRECORDER_G_OBJECT_SET((sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst), "do-timestamp", TRUE); #else /* speaker mode with alsasrc */ @@ -1021,6 +1211,9 @@ int _mmstreamrecorder_video_command(MMHandleType handle, int command) GstElement *pipeline = NULL; GstPad *pad = NULL; guint count = 0; + gboolean audio_enable = FALSE; + int rec_mode = 0; + char *err_name = NULL; mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); @@ -1028,11 +1221,19 @@ int _mmstreamrecorder_video_command(MMHandleType handle, int command) mmf_return_val_if_fail(sc && sc->encode_element, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); mmf_return_val_if_fail(sc->info_video, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - if (sc->audio_enable == TRUE) { + if (sc->audio_enable == TRUE) mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - } + mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); + ret = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_RECORDER_MODE, &rec_mode, MMSTR_AUDIO_ENABLE, &audio_enable, NULL); + + if (ret != MM_ERROR_NONE) { + _mmstreamrec_dbg_err("Get attrs fail. (%s:%x)", err_name, ret); + SAFE_FREE(err_name); + return ret; + } + info = sc->info_video; if (sc->audio_enable == TRUE) info_audio = sc->info_audio; @@ -1061,7 +1262,7 @@ int _mmstreamrecorder_video_command(MMHandleType handle, int command) sc->ferror_count = 0; sc->error_occurs = FALSE; sc->bget_eos = FALSE; - + ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_PAUSED); ret = _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_PLAYING); if (ret != MM_ERROR_NONE) { /* Remove recorder pipeline and recording file which size maybe zero */ @@ -1152,88 +1353,96 @@ int _mmstreamrecorder_video_command(MMHandleType handle, int command) case _MM_STREAMRECORDER_CMD_COMMIT: /* video recording command */ { - - if (info->b_commiting) { - _mmstreamrec_dbg_err("now on commiting previous file!!(command : %d)", command); - return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING; - } else { - _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start"); - info->b_commiting = TRUE; - } - - for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) { - if (sc->audio_enable == FALSE) { - /* check only video frame */ - if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) { - break; - } else if (count == hstreamrecorder->ini.retrial_count) { - _mmstreamrec_dbg_err("Commit fail, frame count is %" G_GUINT64_FORMAT "", info->video_frame_count); - info->b_commiting = FALSE; - return MM_ERROR_STREAMRECORDER_INVALID_CONDITION; - } else { - _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial [%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count); + if(rec_mode == MM_STREAMRECORDER_MODE_DEVICE_LOOPBACK) { + if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst != NULL) {\ + if (audio_enable) { + ret = gst_element_send_event(gst_bin_get_by_name(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), "audio_source"), gst_event_new_eos()); } + ret = gst_element_send_event(gst_bin_get_by_name(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), "video_source"), gst_event_new_eos()); + } + } else { - usleep(hstreamrecorder->ini.video_frame_wait_time); + if (info->b_commiting) { + _mmstreamrec_dbg_err("now on commiting previous file!!(command : %d)", command); + return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING; } else { - /* check both of video and audio frame */ - if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) { - break; - } else if (count == hstreamrecorder->ini.retrial_count) { - _mmstreamrec_dbg_err("Commit fail, VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count); + _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start"); + info->b_commiting = TRUE; + } - info->b_commiting = FALSE; - return MM_ERROR_STREAMRECORDER_INVALID_CONDITION; + for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) { + if (sc->audio_enable == FALSE) { + /* check only video frame */ + if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame) { + break; + } else if (count == hstreamrecorder->ini.retrial_count) { + _mmstreamrec_dbg_err("Commit fail, frame count is %" G_GUINT64_FORMAT "", info->video_frame_count); + info->b_commiting = FALSE; + return MM_ERROR_STREAMRECORDER_INVALID_CONDITION; + } else { + _mmstreamrec_dbg_warn("Waiting for enough video frame, retrial [%d], frame %" G_GUINT64_FORMAT "", count, info->video_frame_count); + } + + usleep(hstreamrecorder->ini.video_frame_wait_time); } else { - _mmstreamrec_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", count, info->video_frame_count, info_audio->audio_frame_count); + /* check both of video and audio frame */ + if (info->video_frame_count >= hstreamrecorder->ini.minimum_frame && info_audio->audio_frame_count) { + break; + } else if (count == hstreamrecorder->ini.retrial_count) { + _mmstreamrec_dbg_err("Commit fail, VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", info->video_frame_count, info_audio->audio_frame_count); + + info->b_commiting = FALSE; + return MM_ERROR_STREAMRECORDER_INVALID_CONDITION; + } else { + _mmstreamrec_dbg_warn("Waiting for enough frames, retrial [%d], VIDEO[%" G_GUINT64_FORMAT "], AUDIO [%" G_GUINT64_FORMAT "]", count, info->video_frame_count, info_audio->audio_frame_count); + } + + usleep(hstreamrecorder->ini.video_frame_wait_time); } - - usleep(hstreamrecorder->ini.video_frame_wait_time); } - } - if (sc->error_occurs) { - GstPad *video = NULL; - GstPad *audio = NULL; + if (sc->error_occurs) { + GstPad *video = NULL; + GstPad *audio = NULL; - _mmstreamrec_dbg_err("Committing Error case"); + _mmstreamrec_dbg_err("Committing Error case"); #if 0 - video = gst_element_get_static_pad(sc->element[_MMSTREAMRECORDER_VIDEOSINK_SINK].gst, "sink"); - ret = gst_pad_send_event(video, gst_event_new_eos()); - _mmstreamrec_dbg_err("Sending EOS video sink : %d", ret); - gst_object_unref(video); + video = gst_element_get_static_pad(sc->element[_MMSTREAMRECORDER_VIDEOSINK_SINK].gst, "sink"); + ret = gst_pad_send_event(video, gst_event_new_eos()); + _mmstreamrec_dbg_err("Sending EOS video sink : %d", ret); + gst_object_unref(video); #endif - video = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src"); - gst_pad_push_event(video, gst_event_new_flush_start()); - gst_pad_push_event(video, gst_event_new_flush_stop(TRUE)); - ret = gst_pad_push_event(video, gst_event_new_eos()); - _mmstreamrec_dbg_err("Sending EOS video encoder src pad : %d", ret); - gst_object_unref(video); - - if (sc->audio_enable == TRUE) { - audio = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src"); - gst_pad_push_event(audio, gst_event_new_flush_start()); - gst_pad_push_event(audio, gst_event_new_flush_stop(TRUE)); - ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos()); - _mmstreamrec_dbg_err("Sending EOS audio encoder src pad : %d", ret); - gst_object_unref(audio); - } - } else { - if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst != NULL) { + video = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_VENC].gst, "src"); + gst_pad_push_event(video, gst_event_new_flush_start()); + gst_pad_push_event(video, gst_event_new_flush_stop(TRUE)); + ret = gst_pad_push_event(video, gst_event_new_eos()); + _mmstreamrec_dbg_err("Sending EOS video encoder src pad : %d", ret); + gst_object_unref(video); + + if (sc->audio_enable == TRUE) { + audio = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src"); + gst_pad_push_event(audio, gst_event_new_flush_start()); + gst_pad_push_event(audio, gst_event_new_flush_stop(TRUE)); + ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos()); + _mmstreamrec_dbg_err("Sending EOS audio encoder src pad : %d", ret); + gst_object_unref(audio); + } + } else { + if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst != NULL) { ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, gst_event_new_eos()); _mmstreamrec_dbg_warn("send eos to appsrc result : %d", ret); - } + } - if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst != NULL) { - pad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src"); - ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos()); - gst_object_unref(pad); - pad = NULL; + if (sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst != NULL) { + pad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, "src"); + ret = gst_element_send_event(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst, gst_event_new_eos()); + gst_object_unref(pad); + pad = NULL; - _mmstreamrec_dbg_warn("send eos to audiosrc result : %d", ret); + _mmstreamrec_dbg_warn("send eos to audiosrc result : %d", ret); + } } } - /* Wait EOS */ _mmstreamrec_dbg_log("Start to wait EOS"); ret = _mmstreamrecorder_get_eos_message(handle); @@ -1295,11 +1504,11 @@ int _mmstreamrecorder_video_handle_eos(MMHandleType handle) /* Send recording report to application */ msg.id = MM_MESSAGE_STREAMRECORDER_VIDEO_CAPTURED; - report = (MMStreamRecordingReport *) malloc(sizeof(MMStreamRecordingReport)); + report = (MMStreamRecordingReport *) g_malloc(sizeof(MMStreamRecordingReport)); if (!report) { _mmstreamrec_dbg_err("Recording report fail(%s). Out of memory.", finfo->filename); } else { - report->recording_filename = strdup(finfo->filename); + report->recording_filename = g_strdup(finfo->filename); msg.param.data = report; msg.param.code = 1; _mmstreamrecorder_send_message((MMHandleType) hstreamrecorder, &msg); @@ -1326,525 +1535,11 @@ int _mmstreamrecorder_video_handle_eos(MMHandleType handle) return TRUE; } -/* AUDIO */ - -int _mmstreamrecorder_create_audio_pipeline(MMHandleType handle) +int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long long timestamp, GstBuffer *buffer, int size) { mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); _MMStreamRecorderSubContext *sc = NULL; - - mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - sc = MMF_STREAMRECORDER_SUBCONTEXT(handle); - - mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - - return _mmstreamrecorder_create_audiop_with_encodebin(handle); -} - -/** - * This function destroy audio pipeline. - * - * @param[in] handle Handle of streamrecorder. - * @return void - * @remarks - * @see _mmstreamrecorder_destroy_audio_pipeline() - * - */ -void _mmstreamrecorder_destroy_audio_pipeline(MMHandleType handle) -{ - mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); - _MMStreamRecorderSubContext *sc = NULL; - _MMStreamRecorderAudioInfo *info = NULL; - mmf_return_if_fail(hstreamrecorder); - sc = MMF_STREAMRECORDER_SUBCONTEXT(handle); - - mmf_return_if_fail(sc && sc->info_audio); - - info = sc->info_audio; - - _mmstreamrec_dbg_log("start"); - - if (sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst) { - _mmstreamrec_dbg_warn("release audio pipeline"); - - _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst, GST_STATE_NULL); - - _mmstreamrecorder_remove_all_handlers((MMHandleType) hstreamrecorder, _MMSTREAMRECORDER_HANDLER_CATEGORY_ALL); - - if (info->bMuxing) { - GstPad *reqpad = NULL; - /* FIXME: - Release request pad - The ref_count of mux is always # of streams in here, i don't know why it happens. - So, i unref the mux manually - */ - reqpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "audio"); - gst_element_release_request_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, reqpad); - gst_object_unref(reqpad); - - if (GST_IS_ELEMENT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst) && GST_OBJECT_REFCOUNT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst) > 1) { - gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst); - } - } - gst_object_unref(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst); - } - - _mmstreamrec_dbg_log("done"); - - return; -} - -int _mmstreamrecorder_create_audiop_with_encodebin(MMHandleType handle) -{ - int err = MM_ERROR_NONE; - char *aenc_name = NULL; - char *mux_name = NULL; - char *err_name = NULL; - int rec_mode = 0; - - GstBus *bus = NULL; - GstPad *srcpad = NULL; - GstPad *sinkpad = NULL; - GList *element_list = NULL; - - _MMStreamRecorderAudioInfo *info = NULL; - mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); - _MMStreamRecorderSubContext *sc = NULL; - /* type_element *aenc_elem = NULL; */ - /* type_element *mux_elem = NULL; */ - - mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - sc = MMF_STREAMRECORDER_SUBCONTEXT(handle); - - mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - - info = (_MMStreamRecorderAudioInfo *) sc->info_audio; - - _mmstreamrec_dbg_log(""); - - err = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_RECORDER_MODE, &rec_mode, NULL); - - if (!mux_name || !strcmp(mux_name, "wavenc")) { - /* IF MUX in not chosen then record in raw file */ - _mmstreamrec_dbg_log("Record without muxing."); - info->bMuxing = FALSE; - } else { - _mmstreamrec_dbg_log("Record with mux."); - info->bMuxing = TRUE; - } - - /* Create GStreamer pipeline */ - _MMSTREAMRECORDER_PIPELINE_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE, "recorder_pipeline", err); - - err = _mmstreamrecorder_create_audiosrc_bin(handle); - if (err != MM_ERROR_NONE) - return err; - - if (info->bMuxing) { - /* Muxing. can use encodebin. */ - err = _mmstreamrecorder_create_encodesink_bin((MMHandleType) hstreamrecorder, MM_STREAMRECORDER_ENCBIN_PROFILE_AUDIO); - if (err != MM_ERROR_NONE) - return err; - - } else { - /* without muxing. can't use encodebin. */ - - _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AQUE, "queue", NULL, element_list, err); - - if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) { - if (strcmp(hstreamrecorder->ini.name_of_encsink_bin_audio_encoder, "wavenc") != 0) { - _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_CONV, "audioconvert", NULL, element_list, err); - } - } - - _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC, aenc_name, NULL, element_list, err); - - _MMSTREAMRECORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK, hstreamrecorder->ini.name_of_encsink_sink, NULL, element_list, err); - } - - /* Add and link elements */ - if (info->bMuxing) { - /* IF MUX is indicated create MUX */ - gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, NULL); - - srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, "src"); - sinkpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_BIN].gst, "audio_sink0"); - _MM_GST_PAD_LINK_UNREF(srcpad, sinkpad, err, pipeline_creation_error); - } else { - /* IF MUX in not chosen then record in raw amr file */ - if (!strcmp(aenc_name, "wavenc")) { - gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL); - - if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) { - err = MM_ERROR_STREAMRECORDER_GST_LINK; - goto pipeline_creation_error; - } - } else { - if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) { - gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_CONV].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL); - - if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_CONV].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) { - err = MM_ERROR_STREAMRECORDER_GST_LINK; - goto pipeline_creation_error; - } - } else { - gst_bin_add_many(GST_BIN(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst), sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL); - - if (!_MM_GST_ELEMENT_LINK_MANY(sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_BIN].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, NULL)) { - err = MM_ERROR_STREAMRECORDER_GST_LINK; - goto pipeline_creation_error; - } - } - } - } - - if (info->bMuxing) { - MMSTREAMRECORDER_SIGNAL_CONNECT(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_MUX].gst, _MMSTREAMRECORDER_HANDLER_AUDIOREC, "pad-added", __mmstreamrecorder_audiorec_pad_added_cb, hstreamrecorder); - } else { - srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AENC].gst, "src"); - MMSTREAMRECORDER_ADD_BUFFER_PROBE(srcpad, _MMSTREAMRECORDER_HANDLER_AUDIOREC, __mmstreamrecorder_audio_dataprobe_record, hstreamrecorder); - gst_object_unref(srcpad); - srcpad = NULL; - } - - bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst)); - - /* register message callback */ - hstreamrecorder->pipeline_cb_event_id = gst_bus_add_watch(bus, (GstBusFunc) _mmstreamrecorder_pipeline_cb_message, hstreamrecorder); - - /* set sync callback */ - gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, hstreamrecorder, NULL); - - gst_object_unref(bus); - bus = NULL; - - if (element_list) { - g_list_free(element_list); - element_list = NULL; - } - - return MM_ERROR_NONE; - - pipeline_creation_error: - _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCODE_MAIN_PIPE); - _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_AUDIOSRC_BIN); - _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AQUE); - if (rec_mode == MM_STREAMRECORDER_MODE_MEDIABUFFER) { - _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_CONV); - } - _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_AENC); - _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_SINK); - _MMSTREAMRECORDER_ELEMENT_REMOVE(sc->encode_element, _MMSTREAMRECORDER_ENCSINK_BIN); - - if (element_list) { - g_list_free(element_list); - element_list = NULL; - } - - return err; -} - -int _mmstreamrecorder_audio_command(MMHandleType handle, int command) -{ - int cmd = command; - int ret = MM_ERROR_NONE; - int err = 0; - guint64 free_space = 0; - guint64 cal_space = 0; - char *dir_name = NULL; - char *err_attr_name = NULL; - guint count = 0; - int size = 0; - - GstElement *pipeline = NULL; - GstElement *audioSrc = NULL; - - mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); - _MMStreamRecorderSubContext *sc = NULL; - _MMStreamRecorderAudioInfo *info = NULL; - _MMStreamRecorderFileInfo *finfo = NULL; - - mmf_return_val_if_fail(hstreamrecorder, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - sc = MMF_STREAMRECORDER_SUBCONTEXT(handle); - - mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - mmf_return_val_if_fail(sc->info_audio, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - mmf_return_val_if_fail(sc->info_file, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); - pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst; - info = sc->info_audio; - finfo = sc->info_file; - - _mmstreamrec_dbg_log(""); - - pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst; - audioSrc = sc->encode_element[_MMSTREAMRECORDER_AUDIOSRC_SRC].gst; - switch (cmd) { - case _MM_STREAMRECORDER_CMD_RECORD: - /* check status for resume case */ - { - guint imax_size = 0; - guint imax_time = 0; - char *temp_filename = NULL; - - if (sc->pipeline_time) - gst_element_set_start_time((GstElement *) GST_PIPELINE(pipeline), sc->pipeline_time); - - sc->pipeline_time = hstreamrecorder->ini.reset_pause_time; - - ret = mm_streamrecorder_get_attributes(handle, &err_attr_name, MMSTR_TARGET_MAX_SIZE, &imax_size, MMSTR_TARGET_TIME_LIMIT, &imax_time, MMSTR_FILE_FORMAT, &(finfo->fileformat), MMSTR_FILENAME, &temp_filename, &size, NULL); - if (ret != MM_ERROR_NONE) { - _mmstreamrec_dbg_warn("failed to get attribute. (%s:%x)", err_attr_name, ret); - SAFE_FREE(err_attr_name); - goto _ERR_STREAMRECORDER_AUDIO_COMMAND; - } - - finfo->filename = strdup(temp_filename); - if (!finfo->filename) { - _mmstreamrec_dbg_err("STRDUP was failed"); - goto _ERR_STREAMRECORDER_AUDIO_COMMAND; - } - - _mmstreamrec_dbg_log("Record start : set file name using attribute - %s\n ", finfo->filename); - - MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, "location", finfo->filename); - - sc->ferror_send = FALSE; - sc->ferror_count = 0; - sc->bget_eos = FALSE; - info->filesize = 0; - - /* set max size */ - if (imax_size <= 0) - info->max_size = 0; /* do not check */ - else - info->max_size = ((guint64) imax_size) << 10; /* to byte */ - - /* set max time */ - if (imax_time <= 0) - info->max_time = 0; /* do not check */ - else - info->max_time = ((guint64) imax_time) * 1000; /* to millisecond */ - - /* TODO : check free space before recording start, need to more discussion */ - dir_name = g_path_get_dirname(finfo->filename); - err = _mmstreamrecorder_get_freespace(dir_name, &free_space); - - _mmstreamrec_dbg_warn("current space for recording - %s : [%" G_GUINT64_FORMAT "]", dir_name, free_space); - - if (dir_name) { - g_free(dir_name); - dir_name = NULL; - } - cal_space = (guint64)(hstreamrecorder->ini.audio_frame_minimum_space); - cal_space = cal_space + (5 * 1024); - if ((err == -1) || free_space <= cal_space) { - _mmstreamrec_dbg_err("No more space for recording"); - return MM_MESSAGE_STREAMRECORDER_NO_FREE_SPACE; - } - } - - ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING); - if (ret != MM_ERROR_NONE) - goto _ERR_STREAMRECORDER_AUDIO_COMMAND; - - break; - - case _MM_STREAMRECORDER_CMD_PAUSE: - { - GstClock *l_clock = NULL; - - if (info->b_commiting) { - _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd); - return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING; - } - - for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) { - if (info->filesize > 0) { - break; - } else if (count == hstreamrecorder->ini.retrial_count) { - _mmstreamrec_dbg_err("Pause fail, wait 200 ms, but file size is %lld", info->filesize); - return MM_ERROR_STREAMRECORDER_INVALID_CONDITION; - } else { - _mmstreamrec_dbg_warn("Wait for enough audio frame, retry count[%d], file size is %lld", count, info->filesize); - } - usleep(hstreamrecorder->ini.audio_frame_wait_time); - } - - ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PAUSED); - if (ret != MM_ERROR_NONE) - goto _ERR_STREAMRECORDER_AUDIO_COMMAND; - - /* FIXME: consider delay. */ - l_clock = gst_pipeline_get_clock(GST_PIPELINE(pipeline)); - sc->pipeline_time = gst_clock_get_time(l_clock) - gst_element_get_base_time(GST_ELEMENT(pipeline)); - break; - } - - case _MM_STREAMRECORDER_CMD_CANCEL: - if (info->b_commiting) { - _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd); - return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING; - } - - ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY); - if (ret != MM_ERROR_NONE) - goto _ERR_STREAMRECORDER_AUDIO_COMMAND; - - if (info->bMuxing) { - MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE); - } else { - MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, "empty-buffers", FALSE); - } - - _mmstreamrecorder_gst_set_state(handle, sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SINK].gst, GST_STATE_NULL); - - sc->pipeline_time = 0; - sc->pause_time = 0; - sc->isMaxsizePausing = FALSE; - sc->isMaxtimePausing = FALSE; - - if (finfo->filename) { - _mmstreamrec_dbg_log("file delete(%s)", finfo->filename); - unlink(finfo->filename); - g_free(finfo->filename); - finfo->filename = NULL; - } - break; - - case _MM_STREAMRECORDER_CMD_COMMIT: - { - - _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT"); - - if (info->b_commiting) { - _mmstreamrec_dbg_warn("now on commiting previous file!!(cmd : %d)", cmd); - return MM_ERROR_STREAMRECORDER_CMD_IS_RUNNING; - } else { - _mmstreamrec_dbg_log("_MM_STREAMRECORDER_CMD_COMMIT : start"); - info->b_commiting = TRUE; - } - - for (count = 0; count <= hstreamrecorder->ini.retrial_count; count++) { - if (info->filesize > 0) { - break; - } else if (count == hstreamrecorder->ini.retrial_count) { - _mmstreamrec_dbg_err("Commit fail, waited 200 ms, but file size is %lld", info->filesize); - info->b_commiting = FALSE; - return MM_ERROR_STREAMRECORDER_INVALID_CONDITION; - } else { - _mmstreamrec_dbg_warn("Waiting for enough audio frame, re-count[%d], file size is %lld", count, info->filesize); - } - usleep(hstreamrecorder->ini.audio_frame_wait_time); - } - - if (audioSrc) { - GstPad *pad = gst_element_get_static_pad(audioSrc, "src"); - ret = gst_element_send_event(audioSrc, gst_event_new_eos()); - gst_object_unref(pad); - pad = NULL; - /* for pause -> commit case */ - /*if (_mmstreamrecorder_get_state((MMHandleType)hstreamrecorder) == MM_STREAMRECORDER_STATE_PAUSED) { - ret = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING); - if (ret != MM_ERROR_NONE) { - goto _ERR_STREAMRECORDER_AUDIO_COMMAND; - } - } */ - } - - /* wait until finishing EOS */ - _mmstreamrec_dbg_log("Start to wait EOS"); - if ((ret = _mmstreamrecorder_get_eos_message(handle)) != MM_ERROR_NONE) - goto _ERR_STREAMRECORDER_AUDIO_COMMAND; - - break; - } - default: - ret = MM_ERROR_STREAMRECORDER_INVALID_ARGUMENT; - break; - } - - _ERR_STREAMRECORDER_AUDIO_COMMAND: - return ret; -} - -int _mmstreamrecorder_audio_handle_eos(MMHandleType handle) -{ - int err = MM_ERROR_NONE; - mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); - _MMStreamRecorderSubContext *sc = NULL; - _MMStreamRecorderAudioInfo *info = NULL; - _MMStreamRecorderFileInfo *finfo = NULL; - GstElement *pipeline = NULL; - _MMStreamRecorderMsgItem msg; - MMStreamRecordingReport *report; - - mmf_return_val_if_fail(hstreamrecorder, FALSE); - sc = MMF_STREAMRECORDER_SUBCONTEXT(handle); - - mmf_return_val_if_fail(sc, FALSE); - mmf_return_val_if_fail(sc->info_audio, FALSE); - mmf_return_val_if_fail(sc->info_file, FALSE); - - _mmstreamrec_dbg_err(""); - - info = sc->info_audio; - finfo = sc->info_file; - - pipeline = sc->encode_element[_MMSTREAMRECORDER_ENCODE_MAIN_PIPE].gst; - - err = _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_READY); - - if (err != MM_ERROR_NONE) - _mmstreamrec_dbg_warn("Failed:_MM_STREAMRECORDER_CMD_COMMIT:GST_STATE_READY. err[%x]", err); - - /* Send recording report message to application */ - msg.id = MM_MESSAGE_STREAMRECORDER_AUDIO_CAPTURED; - report = (MMStreamRecordingReport *) malloc(sizeof(MMStreamRecordingReport)); - if (!report) { - _mmstreamrec_dbg_err("Recording report fail(%s). Out of memory.", finfo->filename); - return FALSE; - } - - /* START TAG HERE */ - /* MM_AUDIO_CODEC_AAC + MM_FILE_FORMAT_MP4 */ - if (finfo->fileformat == MM_FILE_FORMAT_3GP || finfo->fileformat == MM_FILE_FORMAT_MP4) - _mmstreamrecorder_audio_add_metadata_info_m4a(handle); - /* END TAG HERE */ - - report->recording_filename = strdup(finfo->filename); - msg.param.data = report; - - _mmstreamrecorder_send_message(handle, &msg); - - if (info->bMuxing) { - MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_ENCBIN].gst, "block", FALSE); - } else { - MMSTREAMRECORDER_G_OBJECT_SET(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_AQUE].gst, "empty-buffers", FALSE); - } - - _mmstreamrecorder_gst_set_state(handle, pipeline, GST_STATE_NULL); - - sc->pipeline_time = 0; - sc->pause_time = 0; - sc->isMaxsizePausing = FALSE; - sc->isMaxtimePausing = FALSE; - - g_free(finfo->filename); - finfo->filename = NULL; - - _mmstreamrec_dbg_err("_MM_STREAMRECORDER_CMD_COMMIT : end"); - - info->b_commiting = FALSE; - - return TRUE; -} - -int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size) -{ - mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); - _MMStreamRecorderSubContext *sc = NULL; - GstPad *srcpad = NULL; + /* GstPad *srcpad = NULL; */ GstCaps *srccaps = NULL; char *err_name = NULL; int video_fps = 0; @@ -1860,25 +1555,33 @@ int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long mmf_return_val_if_fail(sc, MM_ERROR_STREAMRECORDER_NOT_INITIALIZED); if (buffer == NULL || size == 0) { - _mmstreamrec_dbg_err("video : Buffer is %p , size %d, time stamp is %ld", buffer, size, timestamp); + _mmstreamrec_dbg_err("video : Buffer is %p , size %d, time stamp is %lld", buffer, size, timestamp); return MM_ERROR_STREAMRECORDER_RESOURCE_CREATION; } - _mmstreamrec_dbg_log("video : Buffer is %p , size %d, time stamp is %ld", buffer, size, timestamp); + _mmstreamrec_dbg_log("video : Buffer is %p , size %d, time stamp is %lld", buffer, size, timestamp); /* check element availability */ ret = mm_streamrecorder_get_attributes(handle, &err_name, MMSTR_VIDEO_FRAMERATE, &video_fps, MMSTR_VIDEO_SOURCE_FORMAT, &video_src, MMSTR_VIDEO_RESOLUTION_WIDTH, &video_width, MMSTR_VIDEO_RESOLUTION_HEIGHT, &video_height, MMSTR_VIDEO_SOURCE_FORMAT, &video_source_format, NULL); + if (ret != MM_ERROR_NONE) { + _mmstreamrec_dbg_err("Error in mm_streamrecorder_get_attributes (%s:%d)", err_name, ret); + SAFE_FREE(err_name); + return ret; + } + if (sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst) { - /*_mmstreamrec_dbg_log("Buffer Push start , time stamp %ld",timestamp);*/ - srcpad = gst_element_get_static_pad(sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, "src"); - srccaps = gst_pad_get_current_caps(srcpad); - srccaps = gst_set_videosrcpad_caps(video_src, video_width, video_height, video_fps, 1); - gst_app_src_set_caps((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, srccaps); - /*_mmstreamrec_dbg_err("newbuf streamrecorder(%p) ",newbuf);*/ + srccaps = gst_set_videosrcpad_caps_sw(video_src, video_width, video_height, video_fps, 1); + if (srccaps) { + gst_app_src_set_caps((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, srccaps); + gst_caps_unref(srccaps); + srccaps = NULL; + } + /*_mmstreamrec_dbg_err("newbuf streamrecorder(%p) ",newbuf);*/ ret = gst_app_src_push_buffer((GstAppSrc *) sc->encode_element[_MMSTREAMRECORDER_ENCSINK_SRC].gst, buffer); + if (ret) { _mmstreamrec_dbg_err("video gst_app_src_push_buffer %d", ret); ret = MM_ERROR_STREAMRECORDER_VIDEOBUFFER_PUSH; @@ -1890,7 +1593,7 @@ int _mmstreamrecorder_push_videostream_buffer(MMHandleType handle, unsigned long return ret; } -int _mmstreamrecorder_push_audiostream_buffer(MMHandleType handle, unsigned long timestamp, GstBuffer *buffer, int size) +int _mmstreamrecorder_push_audiostream_buffer(MMHandleType handle, unsigned long long timestamp, GstBuffer *buffer, int size) { mmf_streamrecorder_t *hstreamrecorder = MMF_STREAMRECORDER(handle); _MMStreamRecorderSubContext *sc = NULL;