static int(*aenc_opus_vtable[])() = {&__mc_fill_input_buffer_with_packet, /* Opus Encoder Vtable */
&__mc_fill_aenc_packet_with_output_buffer};
+#define MEDIACODEC_CROP_ARRAY_LENGTH 4
#define MEDIACODEC_ELEMENT_SET_STATE(x_element, x_state) \
do { \
LOGD("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME(x_element)); \
{
int i = 0;
gchar *caps_str = NULL;
+ tbm_surface_h surface = NULL;
+ tbm_surface_info_s sinfo = {0, };
if (!core || !mcbuffer) {
LOGE("NULL core[%p] or mcbuffer[%p]", core, mcbuffer);
return FALSE;
}
- for (i = 0 ; i < GST_VIDEO_INFO_N_PLANES(core->video_info) ; i++) {
- GST_VIDEO_INFO_PLANE_OFFSET(core->video_info, i) = 0;
- media_packet_get_video_stride_width(mcbuffer->packet, i, &GST_VIDEO_INFO_PLANE_STRIDE(core->video_info, i));
+ if (media_packet_get_tbm_surface(mcbuffer->packet, &surface) != MEDIA_PACKET_ERROR_NONE) {
+ LOGE("get surface failed");
+ return FALSE;
+ }
+
+ if (tbm_surface_get_info(surface, &sinfo) != TBM_SURFACE_ERROR_NONE) {
+ LOGE("get surface info failed");
+ return FALSE;
+ }
+
+ for (i = 0 ; i < sinfo.num_planes ; i++) {
+ GST_VIDEO_INFO_PLANE_OFFSET(core->video_info, i) = sinfo.planes[i].offset;
+ GST_VIDEO_INFO_PLANE_STRIDE(core->video_info, i) = sinfo.planes[i].stride;
LOGI("[%d] offset[%zu], stride[%d]", i,
GST_VIDEO_INFO_PLANE_OFFSET(core->video_info, i),
new_core->codec_id = id;
new_core->codec_type = &codec_map[i].type;
new_core->mc_caps_new = video ? &_mc_gst_vid_caps_new : &_mc_gst_aud_caps_new;
+ new_core->extra_converter = &mc_handle->extra_converter;
new_core->bufmgr = tbm_bufmgr_init(new_core->drm_fd);
if (new_core->bufmgr == NULL) {
return FALSE;
}
+static GstElement *__mc_gst_extra_converter_new(mc_extra_converter_t *extra_converter)
+{
+ GstElement *element = NULL;
+ gint array[MEDIACODEC_CROP_ARRAY_LENGTH] = {0, };
+
+ if (!extra_converter) {
+ LOGE("NULL extra converter");
+ return NULL;
+ }
+
+ LOGI("extra converter[%s]", extra_converter->name);
+
+ element = gst_element_factory_make(extra_converter->name, NULL);
+ if (!element) {
+ LOGE("create element[%s] failed", extra_converter->name);
+ return NULL;
+ }
+
+ array[0] = extra_converter->crop_x;
+ array[1] = extra_converter->crop_y;
+ array[2] = extra_converter->crop_w;
+ array[3] = extra_converter->crop_h;
+
+ if (mc_gst_set_property_array_int(element,
+ "crop", array, MEDIACODEC_CROP_ARRAY_LENGTH) != MC_ERROR_NONE) {
+ gst_object_unref(element);
+ return NULL;
+ }
+
+ LOGI("set crop to extra converter[%d,%d,%dx%d]",
+ array[0], array[1], array[2], array[3] );
+
+ return element;
+}
+
+
+#ifdef TIZEN_FEATURE_ENABLE_DUMP_SOURCE
+static GstPadProbeReturn __dump_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
+{
+ static int count = 0;
+ int i = 0;
+ const gchar *dump_path = (const gchar *)u_data;
+ GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
+ GstMemory *memory = NULL;
+ FILE *fp = NULL;
+ tbm_surface_h surface = NULL;
+ tbm_surface_info_s sinfo = {0, };
+
+ if (!dump_path) {
+ LOGW("NULL path");
+ return GST_PAD_PROBE_OK;
+ }
+
+ if (count++ > 10) {
+ LOGW("[%s] SKIP DUMP", dump_path);
+ return GST_PAD_PROBE_OK;
+ }
+
+ memory = gst_buffer_peek_memory(buffer, 0);
+
+ if (!gst_is_tizen_memory(memory)) {
+ LOGW("Not tizen memory");
+ return GST_PAD_PROBE_OK;
+ }
+
+ surface = gst_tizen_memory_get_surface(memory);
+ if (!surface) {
+ LOGW("No surface");
+ return GST_PAD_PROBE_OK;
+ }
+
+ fp = fopen(dump_path, "a");
+ if (!fp) {
+ LOGW("file open failed[%s]", dump_path);
+ return GST_PAD_PROBE_OK;
+ }
+
+ tbm_surface_get_info(surface, &sinfo);
+
+ for (i = 0 ; i < sinfo.num_planes ; i++) {
+ LOGI("[dump:%s] write plane[%d] size[%u]", dump_path, i, sinfo.planes[i].size);
+ fwrite(sinfo.planes[i].ptr, 1, sinfo.planes[i].size, fp);
+ }
+
+ fclose(fp);
+
+ return GST_PAD_PROBE_OK;
+}
+#endif /* TIZEN_FEATURE_ENABLE_DUMP_SOURCE */
+
+
mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, const gchar *factory_name)
{
int i = 0;
if (!core->video && core->encoder) {
core->audioconvert = gst_element_factory_make("audioconvert", NULL);
-
if (!core->audioconvert) {
LOGE("audioconvert can't create");
goto ERROR;
}
core->audioresample = gst_element_factory_make("audioresample", NULL);
-
if (!core->audioresample) {
LOGE("audioresample can't create");
goto ERROR;
}
}
- if (core->video && core->encoder) {
- core->videoconvert = gst_element_factory_make("videoconvert", NULL);
-
+ if (core->video && core->encoder && core->extra_converter->enable) {
+ core->videoconvert = __mc_gst_extra_converter_new(core->extra_converter);
if (!core->videoconvert) {
- LOGE("videoconvert can't create");
- goto ERROR;
- }
-
- core->videoscale = gst_element_factory_make("videoscale", NULL);
- if (!core->videoscale) {
- LOGE("videoscale can't create");
+ LOGE("create[%s] failed", core->extra_converter->name);
goto ERROR;
}
}
goto ERROR;
}
} else if (core->video && core->encoder) {
- gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
+ if (core->extra_converter->enable) {
+ gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->videoconvert, core->codec, core->fakesink, NULL);
- /* link elements */
- if (!(gst_element_link_many(core->appsrc, core->codec, core->fakesink, NULL))) {
- LOGE("gst_element_link_many is failed");
- goto ERROR;
+ /* link elements */
+ if (!(gst_element_link_many(core->appsrc, core->videoconvert, core->codec, core->fakesink, NULL))) {
+ LOGE("gst_element_link_many is failed");
+ goto ERROR;
+ }
+ } else {
+ gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
+
+ /* link elements */
+ if (!(gst_element_link_many(core->appsrc, core->codec, core->fakesink, NULL))) {
+ LOGE("gst_element_link_many is failed");
+ goto ERROR;
+ }
}
} else {
gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
}
}
+#ifdef TIZEN_FEATURE_ENABLE_DUMP_SOURCE
+ {
+ GstPad *pad = NULL;
+
+ pad = gst_element_get_static_pad(core->videoconvert, "sink");
+ if (pad) {
+ gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, __dump_probe, "/tmp/input.dump", NULL);
+ gst_object_unref(pad);
+ pad = NULL;
+ }
+
+ pad = gst_element_get_static_pad(core->videoconvert, "src");
+ if (pad) {
+ gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, __dump_probe, "/tmp/output.dump", NULL);
+ gst_object_unref(pad);
+ pad = NULL;
+ }
+ }
+#endif /* TIZEN_FEATURE_ENABLE_DUMP_SOURCE */
+
/* connect signals, bus watcher */
bus = gst_pipeline_get_bus(GST_PIPELINE(core->pipeline));
core->bus_watch_id = gst_bus_add_watch(bus, __mc_gst_bus_callback, core);
*packet_pool = pool;
return MC_ERROR_NONE;
}
+
+mc_ret_e mc_gst_set_property_array_int(GstElement *element, const gchar *property_name, gint *array, guint array_length)
+{
+ guint i = 0;
+ GValue value = G_VALUE_INIT;
+ GValue tmp = G_VALUE_INIT;
+
+ if (!element || !property_name || !array) {
+ LOGE("NULL param[%p,%p,%p]", element, property_name, array);
+ return MC_PARAM_ERROR;
+ }
+
+ g_value_init(&value, GST_TYPE_ARRAY);
+ g_value_init(&tmp, G_TYPE_INT);
+
+ LOGI("set element[%s], property[%s], array_length[%d]",
+ GST_ELEMENT_NAME(element), property_name, array_length);
+
+ gst_value_array_init(&value, array_length);
+
+ for (i = 0 ; i < array_length ; i++) {
+ LOGI(" array[%u] %d", i, array[i]);
+ g_value_set_int(&tmp, array[i]);
+ gst_value_array_append_value(&value, &tmp);
+ }
+
+ g_object_set_property(G_OBJECT(element), property_name, &value);
+
+ g_value_unset(&tmp);
+ g_value_unset(&value);
+
+ return MC_ERROR_NONE;
+}