Hello everybody.
I know that subject is very popular here but any suggested decisions do not work for me, I don't know why. I have a h264 video stream and i want to save it directly to different files via "h264parse", "matroskamux" and "filesink" gstreamer elements. I want to generate a new file each hour for instance. The pipeline tail which is saving stream into file is: ....<recieving H264 stream>.... -> tee -> FILE_queue -> h264parse -> matroskamux -> filesink (here "FILE_queue" is the name of the queue element just for convenience) For changing filesink location I am trying to do the following: 1) asynchronously blocking FILE_queue src pad with the callback 2) in this callback: - unlink h264parse from FILE_queue - send EOS to h264parse sink pad - making this: g_idle_add(destroy_filesink_tail, NULL), where "destroy_filesink_tail" sets "h264parse", "matroskamux" and "filesink" to NULL state and after that it removes its from pipeline with gst_bin_remove - adding to pipeline already created new elements "h264parse2", "matroskamux2" and "filesink2" where "filesink2" has a new location property - linking new elements with FILE_queue; - unblocking FILE_queue src pad with gst_pad_set_blocked_async(...FALSE...) THE C CODE IS FOLLOWING: //--------------------------------------------------------------------------------------------------- void timer_1_hour_timeout() { timer_1_hour_stop_forever(); FILE_queue_pad = gst_element_get_static_pad(FILE_queue, "src"); gst_pad_set_blocked_async(FILE_queue_pad, TRUE, replace_filesink_tail, NULL); gst_object_unref(GST_OBJECT(FILE_queue_pad )); } //--------------------------------------------------------------------------------------------------- static void replace_filesink_tail(GstPad * pad, gboolean blocked, gpointer user_data) { if(blocked==TRUE) { GstPad * sinkpad; g_static_rec_mutex_lock(&mutex); sinkpad = gst_element_get_static_pad(h264parse, "sink"); gst_element_unlink(FILE_queue,h264parse); gst_pad_send_event(sinkpad, gst_event_new_eos()); g_idle_add(destroy_filesink_tail, NULL); gst_bin_add_many(GST_BIN (pipeline),h264parse2, matroskamux2, filesink2, NULL); gst_element_link_many(FILE_queue, h264parse2, matroskamux2, filesink2, NULL); g_static_rec_mutex_unlock(&mutex); gst_pad_set_blocked_async(pad, FALSE, replace_filesink_tail, NULL); } return; } //--------------------------------------------------------------------------------------------------- static gboolean destroy_filesink_tail(gpointer user_data) { gst_element_set_state (h264parse, GST_STATE_NULL); gst_element_set_state (matroskamux, GST_STATE_NULL); gst_element_set_state (filesink, GST_STATE_NULL); gst_bin_remove (GST_BIN(pipeline), h264parse); gst_bin_remove (GST_BIN(pipeline), matroskamux); gst_bin_remove (GST_BIN(pipeline), filesink); return FALSE; } //--------------------------------------------------------------------------------------------------- This code is supposed to work fine for one time just for beginning. When I start my program it generates first video file which is OK. It's playable and seekable. It means that old filesink tail catching EOS event and handle it properly. After generating this first videofile pipeline generates a new videofile which corresponds to new filesink2 element. But this second file is always empty and a whole pipeline is stopping forever and never continue its operating. What did I wrong? Very appreciate any suggestions. Thank you. |
Somebody, help please..
|
Admins, Am I banned or my task is totally impossible?
|
In reply to this post by oligarch
On 07/03/12 20:46, oligarch wrote:
> Hello everybody. > > I know that subject is very popular here but any suggested decisions do not > work for me, I don't know why. > I have a h264 video stream and i want to save it directly to different files > via "h264parse", "matroskamux" and "filesink" gstreamer elements. I want to > generate a new file each hour for instance. The pipeline tail which is > saving stream into file is: > > ....<recieving H264 stream>.... -> tee -> FILE_queue -> h264parse -> > matroskamux -> filesink > > (here "FILE_queue" is the name of the queue element just for convenience) > > For changing filesink location I am trying to do the following: > 1) asynchronously blocking FILE_queue src pad with the callback > 2) in this callback: > - unlink h264parse from FILE_queue > - send EOS to h264parse sink pad > - making this: g_idle_add(destroy_filesink_tail, NULL), where > "destroy_filesink_tail" sets > "h264parse", "matroskamux" and "filesink" to NULL state and > after that it removes its from > pipeline with gst_bin_remove > - adding to pipeline already created new elements > "h264parse2", "matroskamux2" and "filesink2" > where "filesink2" has a new location property > - linking new elements with FILE_queue; > - unblocking FILE_queue src pad with > gst_pad_set_blocked_async(...FALSE...) > To me, this looks like you should use state changes instead. GStreamer is heavily multithreaded, and what you describe sounds like a deadlock. Check out http://gstreamer.freedesktop.org/data/doc/gstreamer/0.10.36/gstreamer/html/GstElement.html#GstStateChange . _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Is it really works? I will deffenetly try this solution. The main problem is sending EOS and after that closing each videofile correctly. Only after that I have a correct videofiles. Is this solution resolve this problem? |
In reply to this post by Carlos Rafael Giani
I suppose this solution will never gives a correct result because any events goes down from the first element to last element. And to stop filesink I have to stop udpsrc first. But it is not good for me. I need change filesink only in live pipeline in runtime. Thank you. |
Free forum by Nabble | Edit this page |