#include <gst/audio/audio-format.h>
#include <gst/video/videooverlay.h>
#include <gst/video/cameracontrol.h>
-#include <gst/wayland/wayland.h>
#include <sys/time.h>
#include <unistd.h>
g_object_set(G_OBJECT(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst), "socket-path", socket_path, NULL);
} else {
- if (hcamcorder->use_videoconvert && !strcmp(videosink_name, "waylandsink")) {
+ if (hcamcorder->use_videoconvert && (!strcmp(videosink_name, "waylandsink") || !strcmp(videosink_name, "directvideosink"))) {
/* get video convert name */
_mmcamcorder_conf_get_value_element_name(sc->VideoconvertElement, &videoconvert_name);
char *stream_type = NULL;
char stream_type_len = 0;
int stream_index = 0;
+ int buffer_interval = 0;
+ int blocksize = 0;
GstCaps *caps = NULL;
GstPad *pad = NULL;
/* set audiosrc properties in ini configuration */
_mmcamcorder_conf_set_value_element_property(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst, AudiosrcElement);
+ /* set block size */
+ _mmcamcorder_conf_get_value_int((MMHandleType)hcamcorder, hcamcorder->conf_main,
+ CONFIGURE_CATEGORY_MAIN_AUDIO_INPUT,
+ "AudioBufferInterval",
+ &buffer_interval);
+
+ if (_mmcamcorder_get_audiosrc_blocksize(rate, format, channel, buffer_interval, &blocksize)) {
+ _mmcam_dbg_log("set audiosrc block size %d", blocksize);
+ MMCAMCORDER_G_OBJECT_SET(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst, "blocksize", blocksize);
+ }
+
_MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_AUDIOSRC_FILT, "capsfilter", "audiosrc_capsfilter", element_list, err);
_MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_AUDIOSRC_QUE, "queue", "audiosrc_queue", element_list, err);
int _mmcamcorder_create_encodesink_bin(MMHandleType handle, MMCamcorderEncodebinProfile profile)
{
int err = MM_ERROR_NONE;
+ int file_name_len = 0;
int channel = 0;
int audio_enc = 0;
int v_bitrate = 0;
const char *str_aar = NULL;
const char *str_acs = NULL;
char *err_name = NULL;
+ char *file_name = NULL;
const char *videoconvert_name = NULL;
GstCaps *audio_caps = NULL;
GstCaps *video_caps = NULL;
MMCAM_AUDIO_CHANNEL, &channel,
MMCAM_VIDEO_ENCODER_BITRATE, &v_bitrate,
MMCAM_AUDIO_ENCODER_BITRATE, &a_bitrate,
+ MMCAM_TARGET_FILENAME, &file_name, &file_name_len,
NULL);
if (err != MM_ERROR_NONE) {
/* Sink */
if (profile != MM_CAMCORDER_ENCBIN_PROFILE_IMAGE) {
/* for recording */
- _mmcamcorder_conf_get_element(handle, hcamcorder->conf_main,
- CONFIGURE_CATEGORY_MAIN_RECORD,
- "RecordsinkElement",
- &RecordsinkElement);
- _mmcamcorder_conf_get_value_element_name(RecordsinkElement, &gst_element_rsink_name);
+ if (file_name) {
+ _mmcamcorder_conf_get_element(handle, hcamcorder->conf_main,
+ CONFIGURE_CATEGORY_MAIN_RECORD,
+ "RecordsinkElement",
+ &RecordsinkElement);
+ _mmcamcorder_conf_get_value_element_name(RecordsinkElement, &gst_element_rsink_name);
- _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_SINK, gst_element_rsink_name, NULL, element_list, err);
+ _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_SINK, gst_element_rsink_name, NULL, element_list, err);
- _mmcamcorder_conf_set_value_element_property(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, RecordsinkElement);
+ _mmcamcorder_conf_set_value_element_property(sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst, RecordsinkElement);
+ } else {
+ /* if file_name is not set, add fakesink for muxed stream callback */
+ _MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_SINK, "fakesink", NULL, element_list, err);
+ }
} else {
/* for stillshot */
_MMCAMCORDER_ELEMENT_MAKE(sc, sc->encode_element, _MMCAMCORDER_ENCSINK_SINK, "fakesink", NULL, element_list, err);
{
int err = MM_ERROR_NONE;
int size = 0;
- int retx = 0;
- int rety = 0;
- int retwidth = 0;
- int retheight = 0;
+ int rect_x = 0;
+ int rect_y = 0;
+ int rect_width = 0;
+ int rect_height = 0;
int visible = 0;
int rotation = MM_DISPLAY_ROTATION_NONE;
int flip = MM_FLIP_NONE;
/* Get video display information */
err = mm_camcorder_get_attributes(handle, &err_name,
- MMCAM_DISPLAY_RECT_X, &retx,
- MMCAM_DISPLAY_RECT_Y, &rety,
- MMCAM_DISPLAY_RECT_WIDTH, &retwidth,
- MMCAM_DISPLAY_RECT_HEIGHT, &retheight,
+ MMCAM_DISPLAY_RECT_X, &rect_x,
+ MMCAM_DISPLAY_RECT_Y, &rect_y,
+ MMCAM_DISPLAY_RECT_WIDTH, &rect_width,
+ MMCAM_DISPLAY_RECT_HEIGHT, &rect_height,
MMCAM_DISPLAY_ROTATION, &rotation,
MMCAM_DISPLAY_FLIP, &flip,
MMCAM_DISPLAY_VISIBLE, &visible,
_mmcam_dbg_err("display handle(eavs object) is NULL");
return MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
}
- } else if (!strcmp(videosink_name, "waylandsink")) {
+ } else if (!strcmp(videosink_name, "waylandsink") || !strcmp(videosink_name, "directvideosink")) {
MMCamWaylandInfo *wl_info = (MMCamWaylandInfo *)overlay;
if (wl_info) {
gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(vsink), (guintptr)wl_info->global_surface_id);
gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(vsink),
wl_info->window_x, wl_info->window_y, wl_info->window_width, wl_info->window_height);
-#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("Handle is NULL. skip setting.");
}
/* Set attribute */
if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "waylandsink") ||
- !strcmp(videosink_name, "evaspixmapsink")) {
+ !strcmp(videosink_name, "evaspixmapsink") || !strcmp(videosink_name, "directvideosink")) {
/* set rotation */
MMCAMCORDER_G_OBJECT_SET(vsink, "rotate", rotation);
MMCAMCORDER_G_OBJECT_SET(vsink, "zoom", zoom_level);
if (display_geometry_method == MM_DISPLAY_METHOD_CUSTOM_ROI) {
- g_object_set(vsink,
- "dst-roi-x", retx,
- "dst-roi-y", rety,
- "dst-roi-w", retwidth,
- "dst-roi-h", retheight,
- NULL);
+ if (!strcmp(videosink_name, "waylandsink")) {
+ gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(vsink),
+ rect_x, rect_y, rect_width, rect_height);
+ } else {
+ g_object_set(vsink,
+ "dst-roi-x", rect_x,
+ "dst-roi-y", rect_y,
+ "dst-roi-w", rect_width,
+ "dst-roi-h", rect_height,
+ NULL);
+ }
}
}
GstMapInfo mapinfo;
mmf_return_val_if_fail(buffer, GST_PAD_PROBE_DROP);
- mmf_return_val_if_fail(gst_buffer_n_memory(buffer) , GST_PAD_PROBE_DROP);
+ mmf_return_val_if_fail(gst_buffer_n_memory(buffer), GST_PAD_PROBE_DROP);
mmf_return_val_if_fail(hcamcorder, GST_PAD_PROBE_DROP);
sc = MMF_CAMCORDER_SUBCONTEXT(u_data);
/* push buffer in appsrc to encode */
if (!sc->info_video) {
_mmcam_dbg_warn("sc->info_video is NULL!!");
- return FALSE;
+ return GST_PAD_PROBE_DROP;
}
if (sc->info_video->push_encoding_buffer == PUSH_ENCODING_BUFFER_RUN &&
}
+GstPadProbeReturn __mmcamcorder_muxed_dataprobe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+ MMCamcorderMuxedStreamDataType stream;
+ mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(u_data);
+ _MMCamcorderSubContext *sc = NULL;
+ GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
+ GstMapInfo mapinfo;
+
+ mmf_return_val_if_fail(buffer, GST_PAD_PROBE_OK);
+ mmf_return_val_if_fail(gst_buffer_n_memory(buffer), GST_PAD_PROBE_OK);
+ mmf_return_val_if_fail(hcamcorder, GST_PAD_PROBE_OK);
+
+ sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
+ mmf_return_val_if_fail(sc, GST_PAD_PROBE_OK);
+
+ if (!gst_buffer_map(buffer, &mapinfo, GST_MAP_READ)) {
+ _mmcam_dbg_warn("map failed : buffer %p", buffer);
+ return GST_PAD_PROBE_OK;
+ }
+
+ /* call application callback */
+ _MMCAMCORDER_LOCK_MSTREAM_CALLBACK(hcamcorder);
+
+ if (hcamcorder->mstream_cb) {
+ stream.data = (void *)mapinfo.data;
+ stream.length = mapinfo.size;
+ stream.offset = sc->muxed_stream_offset;
+ hcamcorder->mstream_cb(&stream, hcamcorder->mstream_cb_param);
+ }
+
+ _MMCAMCORDER_UNLOCK_MSTREAM_CALLBACK(hcamcorder);
+
+ /* calculate current offset */
+ sc->muxed_stream_offset += mapinfo.size;
+
+ gst_buffer_unmap(buffer, &mapinfo);
+
+ return GST_PAD_PROBE_OK;
+}
+
+
+GstPadProbeReturn __mmcamcorder_eventprobe_monitor(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
+ mmf_camcorder_t *hcamcorder = NULL;
+ _MMCamcorderSubContext *sc = NULL;
+ GstObject *parent = NULL;
+
+ switch (GST_EVENT_TYPE(event)) {
+ case GST_EVENT_UNKNOWN:
+ /* upstream events */
+ case GST_EVENT_QOS:
+ case GST_EVENT_SEEK:
+ case GST_EVENT_NAVIGATION:
+ case GST_EVENT_LATENCY:
+ /* downstream serialized events */
+ case GST_EVENT_TAG:
+ case GST_EVENT_BUFFERSIZE:
+ _mmcam_dbg_log("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+ break;
+ case GST_EVENT_SEGMENT:
+ _mmcam_dbg_log("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+
+ hcamcorder = MMF_CAMCORDER(u_data);
+ if (!hcamcorder) {
+ _mmcam_dbg_warn("NULL handle");
+ break;
+ }
+
+ sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
+ if (!sc) {
+ _mmcam_dbg_warn("NULL sub context");
+ break;
+ }
+
+ if (!sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst) {
+ _mmcam_dbg_warn("no encoder sink");
+ break;
+ }
+
+ parent = gst_pad_get_parent(pad);
+ if (!parent) {
+ _mmcam_dbg_warn("get parent failed");
+ break;
+ }
+
+ if (parent == (GstObject *)sc->encode_element[_MMCAMCORDER_ENCSINK_SINK].gst) {
+ const GstSegment *segment;
+ gst_event_parse_segment(event, &segment);
+ if (segment->format == GST_FORMAT_BYTES) {
+ _mmcam_dbg_log("change current offset %llu -> %llu",
+ sc->muxed_stream_offset, segment->start);
+
+ sc->muxed_stream_offset = (unsigned long long)segment->start;
+ }
+ }
+
+ gst_object_unref(parent);
+ parent = NULL;
+ break;
+ case GST_EVENT_EOS:
+ _mmcam_dbg_warn("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+ break;
+ /* bidirectional events */
+ case GST_EVENT_FLUSH_START:
+ case GST_EVENT_FLUSH_STOP:
+ _mmcam_dbg_err("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+ break;
+ default:
+ _mmcam_dbg_log("[%s:%s] gots %s", GST_DEBUG_PAD_NAME(pad), GST_EVENT_TYPE_NAME(event));
+ break;
+ }
+
+ return GST_PAD_PROBE_OK;
+}
+
+
int __mmcamcorder_get_amrnb_bitrate_mode(int bitrate)
{
int result = MM_CAMCORDER_MR475;
- if (bitrate < 5150) {
+ if (bitrate < 5150)
result = MM_CAMCORDER_MR475; /*AMR475*/
- } else if (bitrate < 5900) {
+ else if (bitrate < 5900)
result = MM_CAMCORDER_MR515; /*AMR515*/
- } else if (bitrate < 6700) {
+ else if (bitrate < 6700)
result = MM_CAMCORDER_MR59; /*AMR59*/
- } else if (bitrate < 7400) {
+ else if (bitrate < 7400)
result = MM_CAMCORDER_MR67; /*AMR67*/
- } else if (bitrate < 7950) {
+ else if (bitrate < 7950)
result = MM_CAMCORDER_MR74; /*AMR74*/
- } else if (bitrate < 10200) {
+ else if (bitrate < 10200)
result = MM_CAMCORDER_MR795; /*AMR795*/
- } else if (bitrate < 12200) {
+ else if (bitrate < 12200)
result = MM_CAMCORDER_MR102; /*AMR102*/
- } else {
+ else
result = MM_CAMCORDER_MR122; /*AMR122*/
- }
return result;
}
}
+int _mmcamcorder_check_codec_fileformat_compatibility(const char *codec_type, int codec, int file_format)
+{
+ mmf_return_val_if_fail(codec_type, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
+
+ /* Check compatibility between codec and file format */
+ if (!strcmp(codec_type, MMCAM_AUDIO_ENCODER)) {
+ if (codec > MM_AUDIO_CODEC_INVALID && codec < MM_AUDIO_CODEC_NUM &&
+ file_format > MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) {
+ if (audiocodec_fileformat_compatibility_table[codec][file_format] == 0) {
+ _mmcam_dbg_err("Audio codec[%d] and file format[%d] compatibility FAILED.", codec, file_format);
+ return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
+ }
+
+ _mmcam_dbg_log("Audio codec[%d] and file format[%d] compatibility SUCCESS.", codec, file_format);
+ } else {
+ _mmcam_dbg_err("Audio codec[%d] or file format[%d] is INVALID.", codec, file_format);
+ return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
+ }
+ } else if (!strcmp(codec_type, MMCAM_VIDEO_ENCODER)) {
+ if (codec > MM_VIDEO_CODEC_INVALID && codec < MM_VIDEO_CODEC_NUM &&
+ file_format > MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) {
+ if (videocodec_fileformat_compatibility_table[codec][file_format] == 0) {
+ _mmcam_dbg_err("Video codec[%d] and file format[%d] compatibility FAILED.", codec, file_format);
+ return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
+ }
+
+ _mmcam_dbg_log("Video codec[%d] and file format[%d] compatibility SUCCESS.", codec, file_format);
+ } else {
+ _mmcam_dbg_err("Video codec[%d] or file format[%d] is INVALID.", codec, file_format);
+ return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
+ }
+ }
+
+ return MM_ERROR_NONE;
+}
+
+
int _mmcamcorder_check_audiocodec_fileformat_compatibility(MMHandleType handle)
{
int err = MM_ERROR_NONE;
char *err_name = NULL;
err = mm_camcorder_get_attributes(handle, &err_name,
- MMCAM_AUDIO_ENCODER, &audio_codec,
- MMCAM_FILE_FORMAT, &file_format,
- NULL);
+ MMCAM_AUDIO_ENCODER, &audio_codec,
+ MMCAM_FILE_FORMAT, &file_format,
+ NULL);
if (err != MM_ERROR_NONE) {
_mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, err);
SAFE_FREE(err_name);
}
/* Check compatibility between audio codec and file format */
- if (audio_codec > MM_AUDIO_CODEC_INVALID && audio_codec < MM_AUDIO_CODEC_NUM &&
- file_format > MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) {
- if (audiocodec_fileformat_compatibility_table[audio_codec][file_format] == 0) {
- _mmcam_dbg_err("Audio codec[%d] and file format[%d] compatibility FAILED.",
- audio_codec, file_format);
- return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
- }
-
- _mmcam_dbg_log("Audio codec[%d] and file format[%d] compatibility SUCCESS.",
- audio_codec, file_format);
- } else {
- _mmcam_dbg_err("Audio codec[%d] or file format[%d] is INVALID.",
- audio_codec, file_format);
- return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
- }
+ err = _mmcamcorder_check_codec_fileformat_compatibility(MMCAM_AUDIO_ENCODER, audio_codec, file_format);
- return MM_ERROR_NONE;
+ return err;
}
return err;
}
- /* Check compatibility between audio codec and file format */
- if (video_codec > MM_VIDEO_CODEC_INVALID && video_codec < MM_VIDEO_CODEC_NUM &&
- file_format > MM_FILE_FORMAT_INVALID && file_format < MM_FILE_FORMAT_NUM) {
- if (videocodec_fileformat_compatibility_table[video_codec][file_format] == 0) {
- _mmcam_dbg_err("Video codec[%d] and file format[%d] compatibility FAILED.",
- video_codec, file_format);
- return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
- }
+ /* Check compatibility between video codec and file format */
+ err = _mmcamcorder_check_codec_fileformat_compatibility(MMCAM_VIDEO_ENCODER, video_codec, file_format);
- _mmcam_dbg_log("Video codec[%d] and file format[%d] compatibility SUCCESS.",
- video_codec, file_format);
- } else {
- _mmcam_dbg_err("Video codec[%d] or file format[%d] is INVALID.",
- video_codec, file_format);
- return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
- }
-
- return MM_ERROR_NONE;
+ return err;
}
}
if (!strcmp(videosink_name, "waylandsink") || !strcmp(videosink_name, "xvimagesink") ||
- !strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "evaspixmapsink")) {
+ !strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "evaspixmapsink") ||
+ !strcmp(videosink_name, "directvideosink")) {
MMCAMCORDER_G_OBJECT_SET(sc->element[videosink_index].gst, "rotate", display_rotate);
_mmcam_dbg_log("Set display-rotate [%d] done.", display_rotate);
- return TRUE;
} else {
- _mmcam_dbg_warn("videosink[%s] does not support DISPLAY_ROTATION.", videosink_name);
- return FALSE;
+ _mmcam_dbg_warn("[%s] does not support DISPLAY_ROTATION, but no error", videosink_name);
}
+
+ return TRUE;
} else {
_mmcam_dbg_err("Videosink element is null");
return FALSE;
}
if (!strcmp(videosink_name, "waylandsink") || !strcmp(videosink_name, "xvimagesink") ||
- !strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "evaspixmapsink")) {
+ !strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "evaspixmapsink") ||
+ !strcmp(videosink_name, "directvideosink")) {
MMCAMCORDER_G_OBJECT_SET(sc->element[videosink_index].gst, "flip", display_flip);
_mmcam_dbg_log("Set display flip [%d] done.", display_flip);
- return TRUE;
} else {
- _mmcam_dbg_warn("videosink[%s] does not support DISPLAY_FLIP", videosink_name);
- return FALSE;
+ _mmcam_dbg_warn("[%s] does not support DISPLAY_FLIP, but no error", videosink_name);
}
+
+ return TRUE;
} else {
_mmcam_dbg_err("Videosink element is null");
return FALSE;
motion_rate, capture_width, capture_height, fps_auto,
sc->info_video->video_width, sc->info_video->video_height);
- if (motion_rate != _MMCAMCORDER_DEFAULT_RECORDING_MOTION_RATE) {
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "high-speed-fps", fps);
- } else {
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "high-speed-fps", 0);
- }
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst,
+ "high-speed-fps", (motion_rate != _MMCAMCORDER_DEFAULT_RECORDING_MOTION_RATE ? fps : 0));
MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-width", capture_width);
MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst, "capture-height", capture_height);