kapil kaushik
kapil kaushik

Reputation: 1

GStreamer VC++ for converting RTP (Payload Type 96 (PT-96) ) to wav audio file

My application requirement is that I need to sniff network packets from the network card and filter RTP packet of payload type 96 (PT-96) and convert and save them in a wav audio file. I have filtered and stored RTP packets in a container like vector and later i tried to convert them into a wav using Gstreamer libraries but i am not able to convert them in audio file.

I have sniffed packets using pcap library but converting rpt packet to audio is still remaining. My experience in Gstreamer is at a very beginner level. below is my code for GStreamer processing pipeline.


void gstreamer_processing() {
    AppData appdata;
    appdata.pipeline = gst_pipeline_new("audio-receive-pipeline");
    appdata.appsrc = gst_element_factory_make("appsrc", "appsrc");
    appdata.rtpjitterbuffer = gst_element_factory_make("rtpjitterbuffer", "jitterbuffer");
    appdata.rtpdepay = gst_element_factory_make("rtpL16depay", "rtpdepay");
    appdata.audioconvert = gst_element_factory_make("audioconvert", "audioconvert");
    appdata.audioResample = gst_element_factory_make("audioresample","resample");
    appdata.wavenc = gst_element_factory_make("wavenc", "wavenc");
    appdata.filesink = gst_element_factory_make("filesink", "filesink");

    if (!appdata.pipeline || !appdata.appsrc || !appdata.rtpjitterbuffer || !appdata.rtpdepay || !appdata.audioconvert || !appdata.audioResample || !appdata.wavenc || !appdata.filesink) {
        g_printerr("Not all elements could be created.\n");
        return;
    }

    GstAppSrc *appsrc;
    // Set properties
    GstCaps *caps = gst_caps_new_simple("application/x-rtp",
        "media", G_TYPE_STRING, "audio",
        "clock-rate", G_TYPE_INT, 44100,
        "encoding-name", G_TYPE_STRING, "L16",
        "channels", G_TYPE_INT, 2,
        NULL);

    appsrc = GST_APP_SRC(appdata.appsrc);
    gst_app_src_set_stream_type(appsrc, GST_APP_STREAM_TYPE_STREAM);
    gst_app_src_set_caps(appsrc, caps);
    gst_caps_unref(caps);

    g_object_set(G_OBJECT(appdata.filesink), "location", "output.wav", NULL);

    // Add elements to the pipeline
    gst_bin_add_many(GST_BIN(appdata.pipeline), appdata.appsrc, appdata.rtpjitterbuffer,    appdata.rtpdepay, appdata.audioconvert, appdata.audioResample, appdata.wavenc, appdata.filesink, NULL);

    // Link elements
    if (!gst_element_link_many(appdata.appsrc, appdata.rtpjitterbuffer, appdata.rtpdepay, appdata.audioconvert,  appdata.audioResample, appdata.wavenc, appdata.filesink, NULL)) {
        g_printerr("Elements could not be linked.\n");
        gst_object_unref(appdata.pipeline);
        return;
    }
        
    // Set the pipeline to playing state
    gst_element_set_state(appdata.pipeline, GST_STATE_PLAYING);
    static int iCntr = 0;
    while (capturing || !rtp_packets.empty()) 
    {
        if (rtp_packets.empty())
            break;
        iCntr++;
        std::cout << "processing packet "<< iCntr << std::endl;
        if(!rtp_packets.empty()) 
        {
            std::vector<u_char> rtp_packet = std::move(rtp_packets.front());
            
            rtp_packets.erase(rtp_packets.begin());

            if (rtp_packet.size() > 0)
            {
                GstBuffer *buffer = gst_buffer_new_wrapped_full((GstMemoryFlags)0, (gpointer)rtp_packet.data(), rtp_packet.size(), 0, rtp_packet.size(), NULL, NULL);
                if (buffer != NULL)
                {

                    // Debugging print statements
                    GstMapInfo info;
                    if (gst_buffer_map(buffer, &info, GST_MAP_READ)) {
                        guint8 payload_type = info.data[1] & 0x7F;//TODO::check debuggged and changed from orignal code
                        //g_print("Payload type:KK %d\n", payload_type);
                        guint16 seq_num = (info.data[2] << 8) | info.data[3]; // Extracting sequence number
                        gst_buffer_unmap(buffer, &info);
                    }


                    GstFlowReturn ret;
                    //g_signal_emit_by_name(appdata.appsrc, "push-buffer", buffer, &ret);
                    g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
                    gst_buffer_unref(buffer);
                    if (ret != GST_FLOW_OK) {
                        g_printerr("Error pushing buffer to appsrc: %s\n", gst_flow_get_name(ret));
                    }
                }
                else
                {
                    g_printerr("Failed to create GstBuffer for RTP packet.\n");
                }
            }
            else
            {
                capturing = false;
                break;
            }

            //lock.lock();
        }
    }

    // Signal end-of-stream
    //g_signal_emit_by_name(appdata.appsrc, "end-of-stream", NULL);
    g_signal_emit_by_name(appsrc, "end-of-stream", NULL);

    // Run the main loop until the pipeline finishes processing
    GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    g_main_loop_run(loop);

    // Clean up
    gst_element_set_state(appdata.pipeline, GST_STATE_NULL);
    gst_object_unref(GST_OBJECT(appdata.pipeline));
    g_main_loop_unref(loop);
}

Upvotes: 0

Views: 61

Answers (0)

Related Questions