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; } |
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 |
Free forum by Nabble | Edit this page |