GstAppSrc错误已停止播放。未协商(-4)

时间:2018-07-27 09:33:01

标签: gstreamer rtp

以下是我用于构建管道以在rtp流上传输原始pcm样本的代码。刚好当管道更改其状态为正在播放时,在消耗了来自函数push_buffer2的一个或两个数据包之后,管道会在其总线上生成一条错误消息,并显示以下错误:GstAppSrc错误已停止播放。未协商(-4)

static gboolean 
            push_buffer2(AppData * app) 
    { 
            gpointer raw_buffer; 
            GstBuffer *app_buffer; 
            GstMemory *mem; 
            GstFlowReturn ret; 

            app->num_frame++; 

            if (!app->isCallConnected && connectedCalls != 0) { 
                    return TRUE; 
            } 
            char *data = app->dataQueue->pop(); 

            if (data == NULL) { 
                    data = (char*)malloc(sizeof(char) * 960); 
                    memset(data, 0, 960); 
            } 

            app_buffer = gst_buffer_new(); 

            //mem = gst_allocator_alloc(NULL, BUFFER_SIZE, NULL); 
            mem = 
gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, data, 960, 
0, 960, 
NULL, NULL); 
            gst_buffer_append_memory(app_buffer, mem); 
            gst_buffer_set_size(app_buffer, BUFFER_SIZE); 

            /* Setting the correct timestamp for the buffer 
is very important, 
otherwise the 
            * resulting file won't be created correctly */ 
            GST_BUFFER_TIMESTAMP(app_buffer) = (GstClockTime)((app->num_frame * 0.06) 
* 1e9); 

            /* push new buffer */ 
            g_signal_emit_by_name(app->source, "push-buffer", app_buffer, &ret); 
            gst_buffer_unref(app_buffer); 

            if (ret != GST_FLOW_OK) { 
                    /* some error, stop sending data */ 
                    return FALSE; 
            } 

            //return TRUE; 

            return TRUE; 
    } 

    /* This signal callback is called when appsrc needs data, we add an idle handler 
    * to the mainloop to start pushing data into the appsrc */ 
    static void 
            start_feed(GstElement * pipeline, guint size, AppData * app) 
    { 
            if (app->source_id == 0) { 
                    //g_print("start feeding at frame %i\n", app->num_frame); 
                    app->source_id = g_idle_add((GSourceFunc)push_buffer2, app); 
            } 
    } 

    /* This callback is called when appsrc has enough data 
and we can stop sending. 
    * We remove the idle handler from the mainloop */ 
    static void 
            stop_feed(GstElement * pipeline, AppData * app) 
    { 
            if (app->source_id != 0) { 
                    //g_print("stop feeding at frame %i\n", app->num_frame); 
                    g_source_remove(app->source_id); 
                    app->source_id = 0; 
            } 
    } 

static void runGstPipeline() { 
GstBus *bus = NULL; 
            //GstElement *appsrc = NULL; 
            //GstElement *appsrc2 = NULL; 
            GstElement *pipeline, *mixer, *ac1, *mulawenc, 
*rtppcmupay, *udpsink, *appsrc, *ac2, *ar, *wavenc, 
*wavparse, *ac3; 

            GstCaps *caps = gst_caps_new_simple("audio/x-raw", 
                    "format", G_TYPE_STRING, "S16LE", 
                    "channels", G_TYPE_INT, 1, 
                    "rate", G_TYPE_INT, 8000, NULL); 
            GstPad *adder_sinkpad1; 

            gst_init(NULL, NULL); 

            pipeline = gst_pipeline_new("audio-send-pipeline"); 
            mixer = gst_element_factory_make("adder", "audio-mixer"); 

            ac1 = gst_element_factory_make("audioconvert", "conv1"); 
            mulawenc = gst_element_factory_make("mulawenc", "mulaw-enc"); 
            rtppcmupay = gst_element_factory_make("rtppcmupay", "pay"); 
            udpsink = gst_element_factory_make("udpsink", "sink"); 

            g_object_set(udpsink, 
                    "host", "127.0.0.1", 
                    "port", 5000, 
                    NULL); 

            appsrc = gst_element_factory_make("appsrc", "source1"); 
            gst_app_src_set_caps(GST_APP_SRC(appsrc), caps); 

            ac2 = gst_element_factory_make("audioconvert", "conv2"); 
            ar = gst_element_factory_make("audioresample", "resam1"); 

            wavenc = gst_element_factory_make("wavenc", "enc1"); 
            wavparse = gst_element_factory_make("wavparse", "parse1"); 

            ac3 = gst_element_factory_make("audioconvert", "conv3"); 


            if (!pipeline || !mixer || !ac1 || !mulawenc || 
!rtppcmupay || !udpsink || !appsrc || !ac2 || !ar || !wavenc 
|| !wavparse || !ac3) { 
                    g_printerr("One or more elements could not be created. Exiting\n"); 
                    return; 
            } 

            bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); 
            gst_bin_add_many(GST_BIN(pipeline), 
                    mixer ,ac1 ,mulawenc ,rtppcmupay,udpsink 
,appsrc ,ac2 ,ar ,wavenc ,wavparse ,ac3, NULL); 

            int n = 0; 
            if ((n = gst_element_link(mixer, ac1)) == 0) { 
                    g_print("link error: %d\n", n); 
                    g_print("cannot link mixer with caps-filter-1\n"); 
            } 

            if ((n = gst_element_link(ac1, mulawenc)) == 0) { 
                    g_print("link error: %d\n", n); 
                    g_print("cannot link audio-convert-1 with mulawenc\n"); 
            } 

            if ((n = gst_element_link(mulawenc, udpsink)) == 0) { 
                    g_print("link error: %d\n", n); 
                    g_print("cannot link mulawenc with udpsink\n"); 
            } 

            if ((n = gst_element_link(appsrc, ac2)) == 0) { 
                    g_print("link error: %d\n", n); 
                    g_print("cannot link appsrc with caps-filter-2\n"); 
            } 

            if ((n = gst_element_link(ac2, ar)) == 0) { 
                    g_print("link error: %d\n", n); 
                    g_print("cannot link audio-convert-2 with audio-resample\n"); 
            } 

            if ((n = gst_element_link(ar, wavenc)) == 0) { 
                    g_print("link error: %d\n", n); 
                    g_print("cannot link audio-resample with wav-enc\n"); 
            } 

            if ((n = gst_element_link(wavenc, wavparse)) == 0) { 
                    g_print("link error: %d\n", n); 
                    g_print("cannot link wav-enc with wav-parse\n"); 
            } 

            if ((n = gst_element_link(wavparse, ac3)) == 0) { 
                    g_print("link error: %d\n", n); 
                    g_print("cannot link wav-parse with ac3\n"); 
            } 

            adder_sinkpad1 = gst_element_get_request_pad(mixer, "sink_%u"); 
            g_print("PadName : %s", gst_pad_get_name(adder_sinkpad1)); 

            GstPad *srcPad = gst_element_get_static_pad(ac3, "src"); 
            if ((n = gst_pad_link(srcPad, adder_sinkpad1)) != 0) { 
                    g_print("pad error: %d\n", n); 
                    g_print("cannot link audio-convert-3 with adder"); 
            } 


            sendAppData = g_new0(AppData, 1); 
            sendAppData->pipeline = pipeline; 
            sendAppData->loop = g_main_loop_new(NULL, FALSE); 

            /* setting up pipeline, we push media data into this pipeline that will 
            * then be recorded to a file, encoded with a codec*/ 
            if (sendAppData->pipeline == NULL) { 
                    g_print("Bad pipeline\n"); 
                    return; 
            } 

            sendAppData->source = appsrc; 
            sendAppData->dataQueue = &dataQueue; 

            /* setting maximum of bytes queued */ 
            gst_app_src_set_max_bytes((GstAppSrc *)appsrc, QUEUED_FRAMES * BUFFER_SIZE); 

            g_signal_connect(sendAppData->source, "need-data", G_CALLBACK(start_feed), sendAppData); 
            g_signal_connect(sendAppData->source, "enough-data", G_CALLBACK(stop_feed), sendAppData); 

            /* add watch for messages */ 
            //bus = gst_element_get_bus(sendAppData->pipeline); 
            gst_bus_add_watch(bus, (GstBusFunc)on_pipeline_message, sendAppData); 
            gst_object_unref(bus); 

            /* configure the appsrc, we will push data into the appsrc from the 
            * mainloop */ 
            gst_element_set_state(sendAppData->pipeline, GST_STATE_PLAYING); 

            sendAppData->dataQueue = new ThreadSafeQueue<char*>(); 

            available.push(sendAppData); 

            /* this mainloop is stopped when we receive an error or EOS */ 
            g_print("Creating movie...\n"); 
            g_main_loop_run(sendAppData->loop); 
            g_print("Done.\n"); 

            gst_element_set_state(sendAppData->pipeline, GST_STATE_NULL); 

            /* Cleaning up */ 
            gst_object_unref(sendAppData->source); 
            gst_object_unref(sendAppData->pipeline); 
            g_main_loop_unref(sendAppData->loop); 
            g_free(sendAppData); 
            /* $$$$$$$$$$$$$$$$$$$$$$$$ STOP PIPELINE AND RETURN $$$$$$$$$$$$$$$$$$$$$$$$ */ 
}

0 个答案:

没有答案