2013-07-10 2 views
2

오디오 스트리머에 대해 작업 중이며 스트리밍중인 파일과 스트리밍 대상 파일을 수정할 수 있기를 원합니다. 이렇게하려면 내 filesrc의 위치를 ​​수정하거나 내 udpsink의 호스트/포트를 수정합니다.부품 수정의 목적으로 gstreamer 파이프 라인 만들기

이 파이프 라인을 함께 연결하여 재생하는 데 필요한 모든 것을 이해하는 데 문제가 있습니다. 이전에 내가 열심히 모든 것을 코딩하고,이 파이프 라인 GST 파이프 라인 분석 도구 사용 :

filesrc location=/storage/sdcard0/Music/RunToTheHills.ogg ! oggdemux ! vorbisdec ! audioresample ! audioconvert ! audio/x-raw-int,channels=2,depth=16,width=16,rate=44100 ! rtpL16pay ! udpsink host=192.168.100.126 port=9001 

지금 나는 filesrc의 위치를 ​​변경하려면, 위에서 언급 한 바와 같이 UDP 호스트/포트입니다.

내 응용 프로그램은 NDK를 사용하는 Android 앱입니다. 그러나 이것은 파이프 라인을 설정하는 데 필요한 코드에 영향을주지 않습니다.

여기까지 내가 지금까지 가지고있는 것이 있는데, 그 결과 segfault가 발생합니다.

내 데이터 구조 : 여기

/** 
* Structure to hold all the various variables we need. 
* This is handed to callbacks 
*/ 
typedef struct _CustomData { 
    jobject app; /* The Java app */ 
    GstElement *pipeline; /* gStreamer pipeline */ 
    GstElement *filesrc; /* Input file */ 
    GstPad *fileblock; /* Used to block filesrc */ 
    GstElement *ogg; /* Ogg demultiplexer */ 
    GstElement *vorbis; /* Vorbis decoder */ 
    GstElement *resample; 
    GstElement *convert; 
    GstCaps *caps; 
    GstElement *rtp; /* RTP packer */ 
    GstElement *udp; /* UDP sender */ 
    GMainContext *context; /* GLib Context */ 
    GMainLoop *main_loop; /* GLib main loop */ 
    gboolean initialised; /* True after initialisation */ 
    GstState state; /* Pipeline state */ 
    GstState target_state; /* What state we want to put the pipeline into */ 
    gint64 duration; /* Clip length */ 
    gint64 desired_position; /* Where we want to track to within the clip */ 
    GstClockTime last_seek_time; /* Used to throttle seeking */ 
    gboolean is_live; /* Live streams don't need buffering */ 
} CustomData; 

와의 파이프 라인의 내 생성 :

data->pipeline = gst_pipeline_new("pipeline"); 

data->filesrc = gst_element_factory_make("filesrc", NULL); 
if (!data->filesrc) { 
    GST_ERROR("Failed to create filesrc."); 
    return NULL; 
} 
g_object_set(G_OBJECT(data->filesrc), "location", "/storage/sdcard0/Music/RunToTheHills.ogg", NULL); 

data->fileblock = gst_element_get_static_pad(data->filesrc, "src"); 

data->ogg = gst_element_factory_make("oggdemux", NULL); 
if (!data->ogg) { 
    GST_ERROR("Failed to create oggdemux."); 
    return NULL; 
} 

data->vorbis = gst_element_factory_make("vorbisdec", NULL); 
if (!data->vorbis) { 
    GST_ERROR("Failed to create vorbisdec."); 
    return NULL; 
} 

data->resample = gst_element_factory_make("audioresample", NULL); 
if (!data->resample) { 
    GST_ERROR("Failed to create audioresample."); 
    return NULL; 
} 

data->convert = gst_element_factory_make("audioconvert", NULL); 
if (!data->convert) { 
    GST_ERROR("Failed to create audioconvert."); 
    return NULL; 
} 

data->caps = gst_caps_new_simple("audio/x-raw-int", 
     "channels", G_TYPE_INT, 2, 
     "depth", G_TYPE_INT, 16, 
     "width", G_TYPE_INT, 16, 
     "rate", G_TYPE_INT, 44100); 

if (!data->caps) { 
    GST_ERROR("Failed to create caps"); 
    return NULL; 
} 

data->rtp = gst_element_factory_make("rtpL16pay", NULL); 
if (!data->rtp) { 
    GST_ERROR("Failed to create rtpL16pay."); 
    return NULL; 
} 

data->udp = gst_element_factory_make("udpsink", NULL); 
if (!data->udp) { 
    GST_ERROR("Failed to create udpsink."); 
    return NULL; 
} 
g_object_set(G_OBJECT(data->udp), "host", "192.168.100.126", NULL); 
g_object_set(G_OBJECT(data->udp), "port", 9001, NULL); 


if (!data->ogg || !data->vorbis || !data->resample || !data->convert || !data->caps || !data->rtp || !data->udp) { 
    GST_ERROR("Unable to create all elements!"); 
    return NULL; 
} 

gst_bin_add_many(GST_BIN(data->pipeline), data->filesrc, data->ogg, data->vorbis, 
     data->resample, data->convert, data->caps, data->rtp, data->udp); 

/* Link all the elements together */ 
gst_element_link(data->filesrc, data->ogg); 
gst_element_link(data->ogg, data->vorbis); 
gst_element_link(data->vorbis, data->resample); 
gst_element_link(data->resample, data->convert); 
gst_element_link_filtered(data->convert, data->rtp, data->caps); 
gst_element_link(data->rtp, data->udp); 

누군가가 나에게 내가 잘못 어디로 갔는지에 관한 몇 가지 힌트를 줄 수 있습니까? 디멀티플렉서는 때때로 패드을 가지고 있기 때문에, 당신은 단순히 vorbisdec에 oggdemux를 링크 할 수 없습니다

data->pipeline = gst_parse_launch("filesrc location=/storage/sdcard0/Music/RunToTheHills.ogg ! oggdemux ! vorbisdec ! audioresample ! audioconvert ! audio/x-raw-int,channels=2,depth=16,width=16,rate=44100 ! rtpL16pay ! udpsink host=192.168.100.126 port=9001", &error); 
if (error) { 
    gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message); 
    g_clear_error (&error); 
    set_ui_message(message, data); 
    g_free (message); 
    return NULL; 
} 
+0

현재이 문제를 해결하기 위해 파이프 라인이 변경 될 때마다 작업하고 있습니다. 더 좋은 방법을 찾으면 여기에 게시하겠습니다. – dantheman

답변

0

:

관심은 여기 내 이전 작업 파이프 라인입니다.

demux의 'pad-added'신호에 대한 핸들러 함수를 추가하고 거기에서 링크를 수행해야합니다.

/* Connect to the pad-added signal */ 
g_signal_connect (data->ogg, "pad-added", G_CALLBACK (pad_added_handler), data); 

그리고 핸들러 : 또한

void on_pad_added (GstElement *src, GstPad *new_pad, CustomData *data) 
{ 
GstPad *sink_pad = gst_element_get_static_pad (data->vorbis, "sink"); 
GstPadLinkReturn ret; 
GstCaps *new_pad_caps = NULL; 
GstStructure *new_pad_struct = NULL; 
const gchar *new_pad_type = NULL; 

g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src)); 

/* If our converter is already linked, we have nothing to do here */ 
if (gst_pad_is_linked (sink_pad)) { 
g_print (" We are already linked. Ignoring.\n"); 
goto exit; 
} 

/* Check the new pad's type */ 
new_pad_caps = gst_pad_get_caps (new_pad); 
new_pad_struct = gst_caps_get_structure (new_pad_caps, 0); 
new_pad_type = gst_structure_get_name (new_pad_struct); 
if (!g_str_has_prefix (new_pad_type, "audio/x-raw")) { 
g_print (" It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type); 
goto exit; 
} 

/* Attempt the link */ 
ret = gst_pad_link (new_pad, sink_pad); 
if (GST_PAD_LINK_FAILED (ret)) { 
g_print (" Type is '%s' but link failed.\n", new_pad_type); 
} else { 
g_print (" Link succeeded (type '%s').\n", new_pad_type); 
} 

exit: 
/* Unreference the new pad's caps, if we got them */ 
if (new_pad_caps != NULL) 
gst_caps_unref (new_pad_caps); 

/* Unreference the sink pad */ 
gst_object_unref (sink_pad); 
} 

, 당신이 세그먼트 오류를 ​​얻고 있기 때문에, 나는 메모리 문제가있다 생각합니다. CustomData 구조를 올바르게 사용하고 있습니까? data.element 대신 data-> element를 사용하고 있음을 확인합니다.

관련 문제