From: Sangchul Lee Date: Fri, 22 Jan 2021 08:12:15 +0000 (+0900) Subject: webrtc_test: Add H264 test case for media packet source X-Git-Tag: submit/tizen/20210729.023123~140 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F69%2F252069%2F10;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_test: Add H264 test case for media packet source __DEBUG_VALIDATE_MEDIA_PACKET__ definition is added to test the media packet for H264 encoded data only with local rendering pipeline. [Version] 0.1.101 [Issue Type] Test application Change-Id: I8f3d4ffd9113ec61f1d224f9a43f7d6942591067 Signed-off-by: Sangchul Lee --- diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 525930fd..a6c54222 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -1,6 +1,6 @@ Name: capi-media-webrtc Summary: A WebRTC library in Tizen Native API -Version: 0.1.100 +Version: 0.1.101 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/test/webrtc_test.c b/test/webrtc_test.c index cd1c1607..87c22aa5 100644 --- a/test/webrtc_test.c +++ b/test/webrtc_test.c @@ -33,6 +33,8 @@ #endif #define PACKAGE "webrtc_test" +//#define __DEBUG_VALIDATE_MEDIA_PACKET__ + #ifdef LOG_TAG #undef LOG_TAG #endif @@ -115,9 +117,15 @@ typedef struct { webrtc_h webrtc; GstElement *src_pipeline; +#ifdef __DEBUG_VALIDATE_MEDIA_PACKET__ + GstElement *render_pipeline; + GstElement *appsrc; +#endif GstElement *src; GstElement *sink; + GstElement *demux; gulong handoff_signal_id; + gulong pad_added_signal_id; bool is_overflowed; bool is_stop_requested; GCond cond; @@ -328,6 +336,10 @@ static void __release_packet_source(int conn_idx, unsigned int source_idx) __disconnect_signal((GObject *)packet_source->sink, packet_source->handoff_signal_id); packet_source->handoff_signal_id = 0; } + if (packet_source->pad_added_signal_id > 0) { + __disconnect_signal((GObject *)packet_source->demux, packet_source->pad_added_signal_id); + packet_source->pad_added_signal_id = 0; + } g_clear_object(&packet_source->src_pipeline); packet_source->src_pipeline = NULL; @@ -503,7 +515,7 @@ static void _webrtc_remove_media_source(int index, unsigned int source_id) } #define VIDEO_WIDTH 352 -#define VIDEO_HIGHT 288 +#define VIDEO_HEIGHT 288 #define VIDEO_FRAME_RATE 30 #define AUDIO_CHANNEL 1 #define AUDIO_SAMPLERATE 8000 @@ -534,9 +546,12 @@ static int __create_formats(media_format_mimetype_e type, media_format_h *format } } else if (type & MEDIA_FORMAT_VIDEO) { + /* assume that h264 video file of 640x480 resolution */ + int width = (type == MEDIA_FORMAT_H264_SP) ? 640 : VIDEO_WIDTH; + int height = (type == MEDIA_FORMAT_H264_SP) ? 480 : VIDEO_HEIGHT; ret = media_format_set_video_mime(*format, type); - ret |= media_format_set_video_width(*format, VIDEO_WIDTH); - ret |= media_format_set_video_height(*format, VIDEO_HIGHT); + ret |= media_format_set_video_width(*format, width); + ret |= media_format_set_video_height(*format, height); ret |= media_format_set_video_frame_rate(*format, VIDEO_FRAME_RATE); if (ret != MEDIA_FORMAT_ERROR_NONE) { g_print("failed to set video format\n"); @@ -571,6 +586,9 @@ static void _webrtc_media_packet_source_set_format(int index, unsigned int sourc case 3: type = MEDIA_FORMAT_PCM_S16LE; break; + case 4: + type = MEDIA_FORMAT_H264_SP; + break; default: g_print("invalid value[%d]\n", value); return; @@ -1454,73 +1472,70 @@ static int __media_packet_finalize_cb(media_packet_h packet, int error_code, voi return MEDIA_PACKET_FINALIZE; } -static void __stream_handoff_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data) +static media_packet_h __make_media_packet(media_packet_source_s *packet_source, GstBuffer *buffer) { int ret; - media_packet_h packet; - media_packet_source_s *packet_source = (media_packet_source_s *)data; + media_packet_h packet = NULL; guchar *data_ptr; gsize size; GstClockTime pts; + GstClockTime dts; GstClockTime duration; GstMapInfo buff_info = GST_MAP_INFO_INIT; bool has_tbm_surface; tbm_surface_info_s ts_info; - if (!object || !buffer || !pad || !packet_source) { - g_printerr("invalid parameters, object[%p], buffer[%p], pad[%p], packet_source[%p]\n", object, buffer, pad, packet_source); - return; - } - - if (packet_source->is_stop_requested) { - g_print("stop requested, skip this buffer[%p]\n", buffer); - return; + if (!packet_source) { + g_printerr("packet_source is NULL\n"); + return NULL; } - - g_mutex_lock(&packet_source->mutex); - if (packet_source->is_overflowed) { - g_print("wait...\n"); - g_cond_wait(&packet_source->cond, &packet_source->mutex); - g_print("wake up...\n"); + if (!buffer) { + g_printerr("buffer is NULL\n"); + return NULL; } - g_mutex_unlock(&packet_source->mutex); - - size = gst_buffer_get_size(buffer); - pts = GST_BUFFER_PTS(buffer); - duration = GST_BUFFER_DURATION(buffer); - - g_print("__stream_handoff_cb(), buffer[%p], size[%u], pts[%llu], duration[%llu]\n", buffer, size, pts, duration); ret = media_packet_create_alloc(packet_source->format, __media_packet_finalize_cb, packet_source, &packet); if (ret != MEDIA_PACKET_ERROR_NONE) { g_printerr("failed to media_packet_create_alloc()\n"); - return; + return NULL; } gst_buffer_ref(buffer); + size = gst_buffer_get_size(buffer); + pts = GST_BUFFER_PTS(buffer); + dts = GST_BUFFER_DTS(buffer); + duration = GST_BUFFER_DURATION(buffer); + g_print("buffer[%p], size[%u], pts[%llu], dts[%llu], duration[%llu]\n", buffer, size, pts, dts, duration); + ret = media_packet_set_pts(packet, pts); if (ret != MEDIA_PACKET_ERROR_NONE) { g_printerr("failed to media_packet_set_pts()\n"); - goto exit; + goto error; + } + + ret = media_packet_set_dts(packet, dts); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_printerr("failed to media_packet_set_dts()\n"); + goto error; } ret = media_packet_set_duration(packet, duration); if (ret != MEDIA_PACKET_ERROR_NONE) { g_printerr("failed to media_packet_set_duration()\n"); - goto exit; + goto error; } ret = media_packet_set_buffer_size(packet, size); if (ret != MEDIA_PACKET_ERROR_NONE) { g_printerr("failed to media_packet_set_buffer_size()\n"); - goto exit; + goto error; } ret = media_packet_get_buffer_data_ptr(packet, (void **)&data_ptr); if (ret != MEDIA_PACKET_ERROR_NONE) { g_printerr("failed to media_packet_get_buffer_data_ptr()\n"); - goto exit; + goto error; } media_packet_has_tbm_surface_buffer(packet, &has_tbm_surface); @@ -1532,7 +1547,7 @@ static void __stream_handoff_cb(GstElement *object, GstBuffer *buffer, GstPad *p ret = tbm_surface_get_info(ts, &ts_info); if (ret != TBM_SURFACE_ERROR_NONE) { g_printerr("failed to tbm_surface_get_info()\n"); - goto exit; + goto error; } g_print("tbm surface[%p, %ux%u, size:%u, format:%u, num_planes:%u] found\n", ts, ts_info.width, ts_info.height, ts_info.size, ts_info.format, ts_info.num_planes); @@ -1551,18 +1566,186 @@ static void __stream_handoff_cb(GstElement *object, GstBuffer *buffer, GstPad *p memcpy(data_ptr, buff_info.data, size); } gst_buffer_unmap(buffer, &buff_info); - } else + } else { g_printerr("failed to gst_buffer_map()\n"); + goto error; + } - ret = webrtc_media_packet_source_push_packet(packet_source->webrtc, packet_source->source_id, packet); - if (ret != WEBRTC_ERROR_NONE) - g_printerr("failed to webrtc_media_packet_source_push_packet()\n"); + return packet; -exit: +error: media_packet_destroy(packet); gst_buffer_unref(buffer); + return NULL; } +#ifdef __DEBUG_VALIDATE_MEDIA_PACKET__ +static int __fill_gst_buffer_mapped_data_from_packet(GstBuffer *buffer, media_packet_h packet) +{ + bool has_tbm_surface = false; + tbm_surface_info_s ts_info; + guint64 size = 0; + GstMapInfo buff_info = GST_MAP_INFO_INIT; + + if (!buffer) { + g_printerr("buffer is NULL\n"); + return -1; + } + if (!packet) { + g_printerr("packet is NULL\n"); + return -1; + } + + media_packet_get_buffer_size(packet, &size); + media_packet_has_tbm_surface_buffer(packet, &has_tbm_surface); + + if (has_tbm_surface) { + int ret = TBM_SURFACE_ERROR_NONE; + tbm_surface_h ts; + + media_packet_get_tbm_surface(packet, &ts); + ret = tbm_surface_get_info(ts, &ts_info); + if (ret != TBM_SURFACE_ERROR_NONE) { + g_printerr("failed to tbm_surface_get_info()\n"); + return -1; + } + + g_printerr("tbm surface[%p, %ux%u, size:%u, format:%u, num_planes:%u] found\n", + ts, ts_info.width, ts_info.height, ts_info.size, ts_info.format, ts_info.num_planes); + } + + if (gst_buffer_map(buffer, &buff_info, GST_MAP_READWRITE)) { + if (has_tbm_surface) { + int i; + guint8 *ptr = buff_info.data; + for (i = 0; i < ts_info.num_planes; i++) { + g_print("plane[%d][ptr:%p size:%u]\n", i, ts_info.planes[i].ptr, ts_info.planes[i].size); + memcpy(ptr, ts_info.planes[i].ptr, ts_info.planes[i].size); + ptr += ts_info.planes[i].size; + } + + } else { + guchar *data_ptr; + media_packet_get_buffer_data_ptr(packet, (void **)&data_ptr); + if (data_ptr == NULL) { + g_printerr("invalid packet, data_ptr is NULL\n"); + gst_buffer_unmap(buffer, &buff_info); + return -1; + } + memcpy(buff_info.data, data_ptr, size); + } + + buff_info.size = size; + + g_print("buffer[%p], buff_info[data:%p, size:%u]\n", buffer, buff_info.data, buff_info.size); + + gst_buffer_unmap(buffer, &buff_info); + } + + return 0; +} + +GstBuffer *__get_buffer_from_packet(media_packet_h packet) +{ + int ret; + guchar *data_ptr; + GstBuffer *new_buffer; + guint64 pts = 0; + guint64 dts = 0; + guint64 duration = 0; + guint64 size = 0; + + media_packet_get_buffer_data_ptr(packet, (void **)&data_ptr); + if (data_ptr == NULL) { + g_printerr("invalid packet, data_ptr is NULL\n"); + return NULL; + } + + media_packet_get_buffer_size(packet, &size); + + new_buffer = gst_buffer_new_and_alloc(size); + if (!new_buffer) { + g_printerr("failed to gst_buffer_new_and_alloc()\n"); + return NULL; + } + + ret = __fill_gst_buffer_mapped_data_from_packet(new_buffer, packet); + if (ret == -1) { + g_printerr("failed to __fill_gst_buffer_mapped_data_from_packet()\n"); + gst_buffer_unref(new_buffer); + return NULL; + } + + media_packet_get_pts(packet, &pts); + GST_BUFFER_PTS(new_buffer) = pts; + media_packet_get_dts(packet, &dts); + GST_BUFFER_DTS(new_buffer) = dts; + + media_packet_get_duration(packet, &duration); + GST_BUFFER_DURATION(new_buffer) = duration; + + g_print("new gst buffer[%p, pts:%llu, dts:%llu, duration:%llu]\n", new_buffer, pts, dts, duration); + + return new_buffer; +} +#endif /* __DEBUG_VALIDATE_MEDIA_PACKET__ */ + +static void __stream_handoff_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data) +{ + media_packet_source_s *packet_source = (media_packet_source_s *)data; + media_packet_h packet; + + if (!object || !buffer || !pad || !packet_source) { + g_printerr("invalid parameters, object[%p], buffer[%p], pad[%p], packet_source[%p]\n", object, buffer, pad, packet_source); + return; + } + + if (packet_source->is_stop_requested) { + g_print("stop requested, skip this buffer[%p]\n", buffer); + return; + } + + g_mutex_lock(&packet_source->mutex); + if (packet_source->is_overflowed) { + g_print("wait...\n"); + g_cond_wait(&packet_source->cond, &packet_source->mutex); + g_print("wake up...\n"); + } + g_mutex_unlock(&packet_source->mutex); + + GstCaps *caps = gst_pad_get_current_caps(pad); + gchar *caps_str = gst_caps_to_string(caps); + g_print("__stream_handoff_cb(), buffer[%p] caps[%s]\n", buffer, caps_str); + g_free(caps_str); + gst_caps_unref(caps); + + packet = __make_media_packet(packet_source, buffer); + if (!packet) { + g_printerr("failed to __make_media_packet()\n"); + return; + } + +#ifdef __DEBUG_VALIDATE_MEDIA_PACKET__ + GstBuffer *buffer_from_packet = __get_buffer_from_packet(packet); + if (!buffer_from_packet) { + media_packet_destroy(packet); + g_printerr("buffer_from_packet is NULL\n"); + return; + } + + GstFlowReturn gst_ret = GST_FLOW_OK; + g_signal_emit_by_name(G_OBJECT(packet_source->appsrc), "push-buffer", buffer_from_packet, &gst_ret, NULL); + if (gst_ret != GST_FLOW_OK) + g_printerr("failed to 'push-buffer', gst_ret[0x%x]\n", gst_ret); + + gst_buffer_unref(buffer_from_packet); + +#else + if (webrtc_media_packet_source_push_packet(packet_source->webrtc, packet_source->source_id, packet) != WEBRTC_ERROR_NONE) + g_printerr("failed to webrtc_media_packet_source_push_packet()\n"); +#endif + media_packet_destroy(packet); +} static GstCaps *__make_raw_caps(media_format_h format) { @@ -1645,50 +1828,160 @@ static GstCaps *__make_raw_caps(media_format_h format) return caps; } -static GstElement* __make_src_pipeline(media_packet_source_s *packet_source) +static void __demux_pad_added_cb(GstElement *object, GstPad *pad, gpointer data) { - media_format_type_e format_type; - GstElement *src; + media_packet_source_s *packet_source = (media_packet_source_s *)data; + GstPad *sinkpad; + const gchar *media_type; + GstElement *h264parse; GstElement *capsfilter; - const char *factory_name_src = "videotestsrc"; - const char *factory_name_sink; GstCaps *caps; - gchar *caps_str; + + g_print("__demux_pad_added_cb(), object[%s] pad[%s] packet_source[%p]\n", + GST_ELEMENT_NAME(object), GST_PAD_NAME(pad), packet_source); + + media_type = gst_structure_get_name(gst_caps_get_structure(gst_pad_get_current_caps(pad), 0)); + + if (g_strrstr(media_type, "audio")) { + g_print("skip pad for audio"); + return; + } + + h264parse = gst_element_factory_make("h264parse", NULL); + if (!h264parse) { + g_printerr("failed to gst_element_factory_make(), h264parse\n"); + return; + } + + capsfilter = gst_element_factory_make("capsfilter", NULL); + if (!capsfilter) { + g_printerr("failed to gst_element_factory_make(), capsfilter\n"); + return; + } + caps = gst_caps_new_simple("video/x-h264", + "stream-format", G_TYPE_STRING, "byte-stream", + "alignment", G_TYPE_STRING, "au", + NULL); + + g_object_set(G_OBJECT(capsfilter), "caps", caps, NULL); + gst_caps_unref(caps); + + + gst_bin_add_many(GST_BIN(packet_source->src_pipeline), h264parse, capsfilter, packet_source->sink, NULL); + + sinkpad = gst_element_get_static_pad(h264parse, "sink"); + if (!sinkpad) { + g_printerr("failed to get static pad\n"); + return; + } + + if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) { + g_printerr("failed to link pad\n"); + return; + } + gst_object_unref(sinkpad); + + if (!gst_element_link_many(h264parse, capsfilter, packet_source->sink, NULL)) { + g_printerr("failed to gst_element_link_many()\n"); + return; + } + + if (!gst_element_sync_state_with_parent(h264parse)) { + g_print("failed to gst_element_sync_state_with_parent() for [%s]", GST_ELEMENT_NAME(h264parse)); + return; + } + if (!gst_element_sync_state_with_parent(capsfilter)) { + g_print("failed to gst_element_sync_state_with_parent() for [%s]", GST_ELEMENT_NAME(capsfilter)); + return; + } + if (!gst_element_sync_state_with_parent(packet_source->sink)) { + g_print("failed to gst_element_sync_state_with_parent() for [%s]", GST_ELEMENT_NAME(packet_source->sink)); + return; + } +} + +#define TEST_640_480_VIDEO_MP4_PATH "/opt/usr/home/owner/media/Videos/1.mp4" +static GstElement* __build_h264_format_pipeline(media_packet_source_s *packet_source) +{ + GstElement *pipeline; + GstElement *src; if (!packet_source) { g_printerr("packet_source is NULL\n"); return NULL; } - if (!packet_source->format) { - g_printerr("format is not set yet\n"); - return NULL; + pipeline = gst_pipeline_new("h264-format-src-pipeline"); + + src = gst_element_factory_make("filesrc", NULL); + if (!src) { + g_printerr("failed to gst_element_factory_make(), filesrc\n"); + goto error; } - packet_source->src_pipeline = gst_pipeline_new("src-pipeline"); - if (!packet_source) { - g_printerr("failed to gst_pipeline_new()\n"); - return NULL; + g_object_set(G_OBJECT(src), "location", TEST_640_480_VIDEO_MP4_PATH, NULL); + + packet_source->demux = gst_element_factory_make("qtdemux", NULL); + if (!packet_source->demux) { + g_printerr("failed to gst_element_factory_make(), qtdemux\n"); + goto error; } - if (media_format_get_type(packet_source->format, &format_type) != MEDIA_FORMAT_ERROR_NONE) { - g_printerr("failed to media_format_get_type()\n"); + packet_source->pad_added_signal_id = _connect_signal((GObject *)packet_source->demux, "pad-added", G_CALLBACK(__demux_pad_added_cb), packet_source); + if (packet_source->pad_added_signal_id == 0) + goto error; + + packet_source->sink = gst_element_factory_make("fakesink", NULL); + if (!packet_source->sink) { + g_printerr("failed to gst_element_factory_make(), fakesink\n"); + goto error; + } + + gst_bin_add_many(GST_BIN(pipeline), src, packet_source->demux, NULL); + if (!gst_element_link_many(src, packet_source->demux, NULL)) { + g_printerr("failed to gst_element_link_many(), filesrc, qtdemux\n"); + goto error; + } + + g_object_set(packet_source->sink, "signal-handoffs", TRUE, NULL); + packet_source->handoff_signal_id = _connect_signal((GObject *)packet_source->sink, "handoff", G_CALLBACK(__stream_handoff_cb), packet_source); + if (packet_source->handoff_signal_id == 0) + goto error; + + return pipeline; + +error: + gst_object_unref(pipeline); + if (packet_source->pad_added_signal_id > 0) { + __disconnect_signal((GObject *)packet_source->demux, packet_source->pad_added_signal_id); + packet_source->pad_added_signal_id = 0; + } + return NULL; +} + +static GstElement* __build_raw_format_pipeline(media_packet_source_s *packet_source, bool is_audio) +{ + GstElement *pipeline; + GstElement *src; + GstElement *capsfilter; + GstCaps *caps; + gchar *caps_str; + + if (!packet_source) { + g_printerr("packet_source is NULL\n"); return NULL; } - if (format_type == MEDIA_FORMAT_AUDIO) - factory_name_src = "audiotestsrc"; - else if (format_type == MEDIA_FORMAT_VIDEO) - factory_name_src = "videotestsrc"; + pipeline = gst_pipeline_new("raw-format-pipeline"); - src = gst_element_factory_make(factory_name_src, NULL); + src = gst_element_factory_make(is_audio ? "audiotestsrc" : "videotestsrc", NULL); if (!src) { - g_printerr("failed to gst_element_factory_make(), %s\n", factory_name_src); + g_printerr("failed to gst_element_factory_make(), %s\n", is_audio ? "audiotestsrc" : "videotestsrc"); goto error; } g_object_set(G_OBJECT(src), "is-live", TRUE, NULL); - if (format_type == MEDIA_FORMAT_VIDEO) + if (!is_audio) g_object_set(G_OBJECT(src), "pattern", 18, NULL); /* 18: ball */ capsfilter = gst_element_factory_make("capsfilter", NULL); @@ -1708,14 +2001,13 @@ static GstElement* __make_src_pipeline(media_packet_source_s *packet_source) g_object_set(G_OBJECT(capsfilter), "caps", caps, NULL); gst_caps_unref(caps); - factory_name_sink = "fakesink"; - packet_source->sink = gst_element_factory_make(factory_name_sink, NULL); + packet_source->sink = gst_element_factory_make("fakesink", NULL); if (!packet_source->sink) { - g_printerr("failed to gst_element_factory_make(), %s\n", factory_name_sink); + g_printerr("failed to gst_element_factory_make(), fakesink\n"); goto error; } - gst_bin_add_many(GST_BIN(packet_source->src_pipeline), src, capsfilter, packet_source->sink, NULL); + gst_bin_add_many(GST_BIN(pipeline), src, capsfilter, packet_source->sink, NULL); if (!gst_element_link_many(src, capsfilter, packet_source->sink, NULL)) { g_printerr("failed to gst_element_link_many()\n"); goto error; @@ -1726,14 +2018,129 @@ static GstElement* __make_src_pipeline(media_packet_source_s *packet_source) if (packet_source->handoff_signal_id == 0) goto error; - return packet_source->src_pipeline; + return pipeline; error: - gst_object_unref(packet_source->src_pipeline); - packet_source->src_pipeline = NULL; + gst_object_unref(pipeline); + return NULL; +} + +#ifdef __DEBUG_VALIDATE_MEDIA_PACKET__ +static GstElement* __build_appsrc_render_pipeline(media_packet_source_s *packet_source) +{ + GstElement *pipeline; + GstElement *src; + GstElement *dec; + GstElement *convert; + GstElement *sink; + GstCaps *caps; + + if (!packet_source) { + g_printerr("packet_source is NULL\n"); + return NULL; + } + + pipeline = gst_pipeline_new("appsrc-render-pipeline"); + + src = gst_element_factory_make("appsrc", NULL); + if (!src) { + g_printerr("failed to gst_element_factory_make(), appsrc\n"); + goto error; + } + + caps = gst_caps_new_simple("video/x-h264", + "stream-format", G_TYPE_STRING, "byte-stream", + "alignment", G_TYPE_STRING, "au", + NULL); + + g_object_set(G_OBJECT(src), "caps", caps, NULL); + dec = gst_element_factory_make("avdec_h264", NULL); + if (!dec) { + g_printerr("failed to gst_element_factory_make(), avdec_h264\n"); + goto error; + } + + convert = gst_element_factory_make("videoconvert", NULL); + if (!convert) { + g_printerr("failed to gst_element_factory_make(), videoconvert\n"); + goto error; + } + + sink = gst_element_factory_make("tizenwlsink", NULL); + if (!sink) { + g_printerr("failed to gst_element_factory_make(), tizenwlsink\n"); + goto error; + } + + gst_bin_add_many(GST_BIN(pipeline), src, dec, convert, sink, NULL); + if (!gst_element_link_many(src, dec, convert, sink, NULL)) { + g_printerr("failed to gst_element_link_many(), appsrc_render\n"); + goto error; + } + + packet_source->appsrc = src; + + return pipeline; + +error: + gst_object_unref(pipeline); return NULL; } +#endif + +static GstElement* __make_src_pipeline(media_packet_source_s *packet_source) +{ + media_format_type_e format_type; + + if (!packet_source) { + g_printerr("packet_source is NULL\n"); + return NULL; + } + + if (!packet_source->format) { + g_printerr("format is not set yet\n"); + return NULL; + } + + if (media_format_get_type(packet_source->format, &format_type) != MEDIA_FORMAT_ERROR_NONE) { + g_printerr("failed to media_format_get_type()\n"); + return NULL; + } + + if (format_type == MEDIA_FORMAT_AUDIO) { + packet_source->src_pipeline = __build_raw_format_pipeline(packet_source, true); + + } else if (format_type == MEDIA_FORMAT_VIDEO) { + media_format_mimetype_e mimetype; + int width; + int height; + + media_format_get_video_info(packet_source->format, &mimetype, &width, &height, NULL, NULL); + switch (mimetype) { + case MEDIA_FORMAT_H264_SP: + packet_source->src_pipeline = __build_h264_format_pipeline(packet_source); +#ifdef __DEBUG_VALIDATE_MEDIA_PACKET__ + packet_source->render_pipeline = __build_appsrc_render_pipeline(packet_source); +#endif + break; + case MEDIA_FORMAT_I420: + case MEDIA_FORMAT_NV12: + packet_source->src_pipeline = __build_raw_format_pipeline(packet_source, false); + break; + default: + g_printerr("unsupported mimetype(0x%x)", mimetype); + return NULL; + } + } + + if (!packet_source->src_pipeline) { + g_printerr("packet_source->src_pipeline is NULL\n"); + return NULL; + } + + return packet_source->src_pipeline; +} static void _start_pushing_packet(int index, int source_id) { @@ -1757,6 +2164,10 @@ static void _start_pushing_packet(int index, int source_id) } state_change_ret = gst_element_set_state(g_conns[index].packet_sources[i].src_pipeline, GST_STATE_PLAYING); +#ifdef __DEBUG_VALIDATE_MEDIA_PACKET__ + if (g_conns[index].packet_sources[i].render_pipeline) + state_change_ret = gst_element_set_state(g_conns[index].packet_sources[i].render_pipeline, GST_STATE_PLAYING); +#endif if (state_change_ret == GST_STATE_CHANGE_FAILURE) { g_printerr("failed to set state to PLAYING\n"); return; @@ -1786,6 +2197,10 @@ static void _stop_pushing_packet(int index, int source_id) g_conns[index].packet_sources[i].is_stop_requested = true; gst_element_set_state(g_conns[index].packet_sources[i].src_pipeline, GST_STATE_PAUSED); +#ifdef __DEBUG_VALIDATE_MEDIA_PACKET__ + if (g_conns[index].packet_sources[i].render_pipeline) + gst_element_set_state(g_conns[index].packet_sources[i].render_pipeline, GST_STATE_PAUSED); +#endif g_print("_stop_pushing_packet()\n"); } @@ -2403,7 +2818,7 @@ static void displaymenu() if (g_conns[g_conn_index].cnt == 0) g_print("*** input source id.\n"); else if (g_conns[g_conn_index].cnt == 1) - g_print("*** input media format.(1:I420 2:NV12 3:PCM_S16LE)\n"); + g_print("*** input media format.(1:I420 2:NV12 3:PCM_S16LE 4:H264)\n"); } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_GET_TRANSCEIVER_DIRECTION) { if (g_conns[g_conn_index].cnt == 0)