Appsink is only apparently processing 25% of data

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Appsink is only apparently processing 25% of data

Michael Rappaport
I have a pipeline that is taking in an RTP MPEG-2 TS, and doing a few things:
1) Playing back video and audio
2) Using filesink to save the file to disk
3) Using appsink to save samples to disk when they are received.

Basically, the program is creating two files, one by stdio, and one by the filesink. Because I am using a tee, I would expect the appsink file and the filesink file to be exactly the same. However, the appsink file is not nearly as big as the filesink file. I've been struggling with this one for quite some time, and any assistance would be greatly appreciated.

Here is my code:

#include <gst/gst.h>
#include <time.h>
#include <Windows.h>
#include <gst/app/gstappsink.h>
#include <string.h>
#include <stdio.h>
#include <gst/base/gstbasesink.h>
#include <gst/gstelement.h>

FILE *myfile;

typedef struct _CustomData {
        GstElement *pipeline;
        GstElement *source;
        GstElement *appsink;
} CustomData;

GstFlowReturn new_buffer(GstElement *sink) {
        GstSample *sample;
        GstFlowReturn ret = GST_FLOW_OK;
        /* Retrieve the buffer */
        sample = gst_app_sink_pull_sample(GST_APP_SINK(sink));
        //retreive buffer data
        GstMapInfo map;
        gst_buffer_map(gst_sample_get_buffer(sample), &map, GST_MAP_READ);
        //printe buffer data
        fprintf(myfile, "%s", map.data);
        return ret;
}



int main(int argc, char *argv[]) {
        CustomData data;
        //GstElement *pipeline, *textoverlay_element, *myTSsink;
        GstElement *LBR_Decode;
        GstBus *bus;
        GstMessage *msg;
        GstStateChangeReturn ret;
        GMainLoop *main_loop;

        myfile = fopen("app.ts", "w+");

        /* Initialize GStreamer */
        gst_init(&argc, &argv);


        //appsink + file
        data.pipeline = gst_parse_launch("udpsrc uri = udp://239.195.8.27:1234 caps=\"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP2T-ES, payload=(int)33\" name=myudpsrc ! tee name=t ! queue2 ! rtpjitterbuffer latency=1000 drop-on-latency=false ! application/x-rtp ! rtpmp2tdepay ! video/mpegts ! queue2 ! appsink name=myTSsink t. ! queue2 ! rtpjitterbuffer latency=1000 drop-on-latency=false ! application/x-rtp ! rtpmp2tdepay ! video/mpegts ! queue2 ! filesink location=file.ts t. ! queue2 ! rtpjitterbuffer latency=1000 drop-on-latency=false ! application/x-rtp ! rtpmp2tdepay ! video/mpegts ! queue2 ! tsdemux name=demux demux. ! queue2 ! faad ! audioconvert ! audioresample ! autoaudiosink demux. ! queue2 ! decodebin name=dec ! queue2 ! videoconvert ! autovideosink", NULL);


        //appsink stuff
        data.appsink = gst_bin_get_by_name(GST_BIN(data.pipeline), "myTSsink");
        GstAppSinkCallbacks mycallbacks;
        mycallbacks.eos = 0;
        mycallbacks.new_sample = new_buffer;
        mycallbacks.new_preroll = 0;
        GstCaps *caps = gst_caps_new_simple("video/mpegts", "packetsize", G_TYPE_INT, 188, "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
        gst_app_sink_set_caps(GST_APP_SINK(data.appsink), caps);
        gst_app_sink_set_callbacks(GST_APP_SINK(data.appsink), &mycallbacks, &data.appsink, 0);
        gst_app_sink_set_emit_signals(GST_APP_SINK(data.appsink), TRUE);
        gst_app_sink_set_max_buffers(GST_APP_SINK(data.appsink), 0);
        gst_app_sink_set_drop(GST_APP_SINK(data.appsink), FALSE);



        /* Start playing */
        ret = gst_element_set_state(data.pipeline, GST_STATE_PLAYING);
        if (ret == GST_STATE_CHANGE_FAILURE) {
                g_printerr("Unable to set the pipeline to the playing state.\n");
                gst_object_unref(data.pipeline);
                return -1;
        }

        /* Wait until error or EOS */
        bus = gst_element_get_bus(data.pipeline);
        msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

        /* Parse message */
        if (msg != NULL) {
                GError *err;
                gchar *debug_info;

                switch (GST_MESSAGE_TYPE(msg)) {
                case GST_MESSAGE_ERROR:
                        gst_message_parse_error(msg, &err, &debug_info);
                        g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME(msg->src), err->message);
                        g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none");
                        g_clear_error(&err);
                        g_free(debug_info);
                        break;
                case GST_MESSAGE_EOS:
                        g_print("End-Of-Stream reached.\n");
                        break;
                default:
                        /* We should not reach here because we only asked for ERRORs and EOS */
                        g_printerr("Unexpected message received.\n");
                        break;
                }
                gst_message_unref(msg);
        }

        /* Free resources */
        gst_object_unref(bus);
        gst_element_set_state(data.pipeline, GST_STATE_NULL);
        gst_object_unref(data.pipeline);
        return 0;
}
Reply | Threaded
Open this post in threaded view
|

Re: Appsink is only apparently processing 25% of data

Tim Müller
On Tue, 2016-10-25 at 12:24 -0700, Michael Rappaport wrote:

Hi Michael,

> I have a pipeline that is taking in an RTP MPEG-2 TS, and doing a few
> things:
> 1) Playing back video and audio
> 2) Using *filesink* to save the file to disk
> 3) Using *appsink* to save samples to disk when they are received.
>
> Basically, the program is creating two files, one by stdio, and one
> by the filesink. Because I am using a tee, I would expect the appsink
> file and the filesink file to be exactly the same. However, the
> appsink file is not nearly as big as the filesink file. I've been
> struggling with this one for quite some time, and any assistance
> would be greatly appreciated.
>
> Here is my code:
>  (snip)
>
> sample = gst_app_sink_pull_sample(GST_APP_SINK(sink));
> //retreive buffer data
> GstMapInfo map;
> gst_buffer_map(gst_sample_get_buffer(sample), &map,
> GST_MAP_READ);
> //printe buffer data
> fprintf(myfile, "%s", map.data);

This printf doesn't look right. The buffer is binary data, it's
basically a bunch of bytes. It might contain bytes that are 0.
printf("%s") will print the data until a 0 byte is encountered. In that
case it will write less data than there is in the buffer. If the buffer
does not contain a 0 byte it may read beyond the allocated memory and
write garbage into the file or even crash.

Try something like:

  fwrite(map.data, map.size, 1, myfile);

(Return value should be 1 on success).

Cheers
 -Tim

--
Tim Müller, Centricular Ltd - http://www.centricular.com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel