Hi,
Using the Gstreamer to get the contents of the given URL as TS packet. When I give one of the playlist in the master manifest it is working. But when I provide master manifest as input, it retrieves only the first chunk and then getting EOS. When I tried with a program (just souphttp, hlsdemux and appsink (added after new pad signal) I see a new pad request again before the application stops. What this new pad (after the appsink added) really mean? Output has first chunk in this case. OUTPUT: ~/gst/gst-template/gst-app/src$ gst-app http://devimages.apple.com.edgekey.net/iphone/samples/bipbop/bipbopall.m3u8 outf1.ts Pipeline state changed from NULL to READY: *Received new pad 'src_0' from 'hlsdemux' (0x90ece0:(nil)):* Link succeeded (type 'video/mpegts'). Pipeline state changed from READY to PAUSED: Pipeline state changed from PAUSED to PLAYING: *Received new pad 'src_1' from 'hlsdemux' (0x90fd10:0x90ece0):* Already linked sink1 type=video/mpegts End-Of-Stream reached. *I tried with gst-launch and found the same behavior. Why? and how to fix this?* gst-launch-1.0 -v souphttpsrc location="http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8" ! hlsdemux ! tsdemux ! h264parse ! avdec_h264 ! autovideosink ----- Stops after the first chunk gst-launch-1.0 -v souphttpsrc location="http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8 -- Working but with a chosen playlist. Source code: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <gst/gst.h> #include <gst/app/gstappsink.h> #define MAX_URL_LEN 150 #define MAX_FILENAME_LEN 100 /* Structure to contain all our information, so we can pass it to callbacks */ typedef struct _CustomData { GstElement *pipeline; GstElement *httpsrc; GstElement *hlsDemux; GstElement *filesink; GstElement *appsink1; char url[MAX_URL_LEN]; char outFile[MAX_FILENAME_LEN]; int fHandle; GstPad *curr_pad; } CustomData; /* Handler for the pad-added signal */ static void pad_added_handler(GstElement *src, GstPad *pad, CustomData *data); /* called when the appsink notifies us that there is a new buffer ready for * processing */ static GstFlowReturn on_new_sample_from_sink(GstElement * elt, CustomData * data) { GstSample *sample; GstBuffer *app_buffer, *buffer; GstFlowReturn ret; GstMapInfo map; /* get the sample from appsink */ sample = gst_app_sink_pull_sample(GST_APP_SINK(elt)); buffer = gst_sample_get_buffer(sample); gst_buffer_map(buffer, &map, GST_MAP_READ); write(data->fHandle, map.data, map.size); /* we don't need the appsink sample anymore */ gst_sample_unref(sample); return ret; } int main(int argc, char *argv[]) { CustomData data; GstBus *bus; GstMessage *msg; GstStateChangeReturn ret; gboolean terminate = FALSE; if (argc < 3) { g_printerr("Usage: %s url outfile\n", argv[0]); return -1; } strcpy(data.url, argv[1]); strcpy(data.outFile, argv[2]); // open output file. data.fHandle = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (data.fHandle < 0) { g_printerr("Could not open file '%s'\n", argv[2]); return -1;; } /* Initialize GStreamer */ gst_init(&argc, &argv); /* Create the elements */ data.httpsrc = gst_element_factory_make("souphttpsrc", "source"); data.hlsDemux = gst_element_factory_make("hlsdemux", "hlsdemux"); data.appsink1 = gst_element_factory_make("appsink", "appsink1"); /* Create the empty pipeline */ data.pipeline = gst_pipeline_new("test-pipeline"); if (!data.pipeline || !data.httpsrc || !data.hlsDemux || !data.appsink1 ) { g_printerr("Not all elements could be created.\n"); return -1; } /* Build the pipeline. Note that we are NOT linking the appsink at this * point. We will do it later. */ gst_bin_add_many(GST_BIN(data.pipeline), data.httpsrc, data.hlsDemux, data.appsink1, NULL); if (!gst_element_link(data.httpsrc, data.hlsDemux)) { g_printerr("element link failed\n"); gst_object_unref(data.pipeline); return -1; } /* Modify the source's properties */ /* Set the URI to play */ // g_object_set(data.httpsrc, "location", "http://devimages.apple.com/iphone/samples/bipbop/gear4/prog_index.m3u8", NULL); g_object_set(data.httpsrc, "location", data.url, NULL); /* Set properties of appsink*/ g_object_set(data.appsink1, "emit-signals", TRUE, "sync", TRUE, NULL); g_signal_connect(data.appsink1, "new-sample", G_CALLBACK(on_new_sample_from_sink), &data); /* Connect to the pad-added signal */ g_signal_connect(data.hlsDemux, "pad-added", G_CALLBACK(pad_added_handler), &data); /* 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; } /* Listen to the bus */ bus = gst_element_get_bus(data.pipeline); do { msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_STATE_CHANGED | 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); terminate = TRUE; break; case GST_MESSAGE_EOS: g_print("End-Of-Stream reached.\n"); terminate = TRUE; break; case GST_MESSAGE_STATE_CHANGED: /* We are only interested in state-changed messages from the pipeline */ if (GST_MESSAGE_SRC(msg) == GST_OBJECT(data.pipeline)) { GstState old_state, new_state, pending_state; gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state); g_print("Pipeline state changed from %s to %s:\n", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state)); } break; default: /* We should not reach here */ g_printerr("Unexpected message received.\n"); break; } gst_message_unref(msg); } } while (!terminate); /* Free resources */ gst_object_unref(bus); gst_element_set_state(data.pipeline, GST_STATE_NULL); gst_object_unref(data.pipeline); close(data.fHandle); return 0; } /* This function will be called by the pad-added signal */ static void pad_added_handler(GstElement *src, GstPad *new_pad, CustomData *data) { GstPad *sink_pad = gst_element_get_static_pad(data->appsink1, "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' (%p:%p):\n", GST_PAD_NAME(new_pad), GST_ELEMENT_NAME(src), new_pad, data->curr_pad); /* Check the new pad's type */ new_pad_caps = gst_pad_get_current_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 our converter is already linked, we have nothing to do here */ if (gst_pad_is_linked(sink_pad)) { g_print("Already linked sink1 type=%s\n", new_pad_type); goto exit; } if (!sink_pad) { g_print("couldnt get appsink pad\n"); 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); data->curr_pad = new_pad; } 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); } Thanks -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
BTW when I tried to link appsink again to the new_pad, I get the error
GST_PAD_LINK_WRONG_HIERARCHY. What could be happening? -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Sorry.. Last info was wrong.. I really tried to add another sink I created
but not in pipeline and so got that error. What I tried when I got the new request add a pad was to remove the appsink from old and connected with the new pad. Link was successful. Played and got "bytes" than before. But when I tried to play I got only 9 seconds of valid video and then stopped. This was the point it was stopping without the addition of new pad. Any ideas? -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Got More info.
I closed the file when the second pad request came in and opened another file to store the TS from from the time I linked the appsink again. First file had 9:26 seconds of TS with video at 192x144. Second file started at 10:00 seconds and went until the end (30 mins) with video at 480x360. What should I infer from this? -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |