I have a need to put multiple video windows in a single application. This means multiple pipelines. For example, the RTSP URL is different for each player, and so I get a new pipeline for each invocation of gst_parse_launch.
I can share code, but in general: what is the best way to do this? The way I'm doing this now (for EACH player I've instantiated in the SAME app): 1) gst_parse_launch, get back the pipeline, 2) gst_pipeline_get_bus, to create a bus on this pipeline. 3) g_main_loop_new(NULL, FALSE) to create a new loop (this is where my main question is at) 4) gst_bus_add_watch to create an add watch on this pipeline, 5) gst_element_set_state to set my pipeline state to GST_STATE_PLAYING 6) g_main_loop_run on the loop returned from #3 7) Then I play until a stop is issued.... 8) gst_element_set_state(pipeline, GST_STATE_NULL) 9) unref the bus, 10) unref the pipeline 11) unref the loop I ask about this order, and the fact I'm creating a new loop without an independent context because I'm getting some random crashes in my app hosting multiple players, and it appears to be during tear down. In general, is this pattern acceptable, or have I committed a sin somewhere? _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Steps 8-10 are in the correct order (my code does it that way). But I don't have a step 11 because I don't use a GMainLoop. I would guess that the main loop should stop before step 8 but I am only guessing. On Fri, Sep 6, 2019 at 1:32 PM Ben Rush <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Do I need a different context for each main loop? Do the steps leading up to 8 look okay? Your advice about the PDBs was invaluable today, by the way. When I track all bits of this down I'll send out an update. On Fri, Sep 6, 2019, 3:51 PM David Ing <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I do not use `gst_parse_launch`, `gst_bus_add_watch`, or anything related to GMainLoop. I am not familiar enough to give you stronger advice. You might want to look through the samples and tutorials (many of which use a GMailLoop) if you haven't done that already. On Fri, Sep 6, 2019 at 2:08 PM Ben Rush <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I have. Things look similar. I'll keep looking. Question: is there a reason you're not using the main loop? Have you seen it improve stability? On Fri, Sep 6, 2019, 4:19 PM David Ing <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
There is no legitimate reason why I'm avoiding the GMailLoop. I just didn't want to take the time to understand what it is and how it works. On Fri, Sep 6, 2019 at 2:21 PM Ben Rush <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by Ben Rush
Hi,
You don't need a separate gmainloop per pipeline, you can use the same one for all of them. They'll all use the default main context. So you do steps 3 & 6 only once. Olivier On September 6, 2019 4:32:41 p.m. EDT, Ben Rush <[hidden email]> wrote: >I have a need to put multiple video windows in a single application. >This >means multiple pipelines. For example, the RTSP URL is different for >each >player, and so I get a new pipeline for each invocation >of gst_parse_launch. > >I can share code, but in general: what is the best way to do this? The >way >I'm doing this now (for EACH player I've instantiated in the SAME app): > >1) gst_parse_launch, get back the pipeline, >2) gst_pipeline_get_bus, to create a bus on this pipeline. >3) g_main_loop_new(NULL, FALSE) to create a new loop (this is where my >main >question is at) >4) gst_bus_add_watch to create an add watch on this pipeline, >5) gst_element_set_state to set my pipeline state to GST_STATE_PLAYING >6) g_main_loop_run on the loop returned from #3 >7) Then I play until a stop is issued.... >8) gst_element_set_state(pipeline, GST_STATE_NULL) >9) unref the bus, >10) unref the pipeline >11) unref the loop > >I ask about this order, and the fact I'm creating a new loop without an >independent context because I'm getting some random crashes in my app >hosting multiple players, and it appears to be during tear down. In >general, is this pattern acceptable, or have I committed a sin >somewhere? -- Olivier Crête [hidden email] _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
This is a guess.
I suspect that step 8 (setting the state to NULL) may take some time to complete. Does it raise a signal when the state changes? If you set the state to NULL and then blindly go ahead and unref things you are hoping that the state change will have completed quickly. So, sometimes, you will 'get away with it' and sometimes you will crash. Ian On 06/09/19 23:45, Olivier Crête wrote: > Hi, > > You don't need a separate gmainloop per pipeline, you can use the same one for all of them. They'll all use the default main context. So you do steps 3 & 6 only once. > > Olivier > > On September 6, 2019 4:32:41 p.m. EDT, Ben Rush <[hidden email]> wrote: >> I have a need to put multiple video windows in a single application. >> This >> means multiple pipelines. For example, the RTSP URL is different for >> each >> player, and so I get a new pipeline for each invocation >> of gst_parse_launch. >> >> I can share code, but in general: what is the best way to do this? The >> way >> I'm doing this now (for EACH player I've instantiated in the SAME app): >> >> 1) gst_parse_launch, get back the pipeline, >> 2) gst_pipeline_get_bus, to create a bus on this pipeline. >> 3) g_main_loop_new(NULL, FALSE) to create a new loop (this is where my >> main >> question is at) >> 4) gst_bus_add_watch to create an add watch on this pipeline, >> 5) gst_element_set_state to set my pipeline state to GST_STATE_PLAYING >> 6) g_main_loop_run on the loop returned from #3 >> 7) Then I play until a stop is issued.... >> 8) gst_element_set_state(pipeline, GST_STATE_NULL) >> 9) unref the bus, >> 10) unref the pipeline >> 11) unref the loop >> >> I ask about this order, and the fact I'm creating a new loop without an >> independent context because I'm getting some random crashes in my app >> hosting multiple players, and it appears to be during tear down. In >> general, is this pattern acceptable, or have I committed a sin >> somewhere? _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
That is correct actually. Do a get_state to wait for the state change to complete. On Sat, Sep 7, 2019, 1:25 AM Ian Davidson <[hidden email]> wrote: This is a guess. _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hey, thanks guy, I'll give that a shot and report back if I encounter any other issues. Cheers and have a good weekend. On Sat, Sep 7, 2019 at 8:38 AM David Ing <[hidden email]> wrote:
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by Ian Davidson
Thanks for all your help everyone. On Sat, Sep 7, 2019 at 3:25 AM Ian Davidson <[hidden email]> wrote: This is a guess. _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by David Ing
Hi,
Actually, changes to NULL should always be synchronous, so you don't need to wait afterwards. They should generally be quite fast also unless there is a bug. Olivier On September 7, 2019 9:38:17 a.m. EDT, David Ing <[hidden email]> wrote: >That is correct actually. Do a get_state to wait for the state change >to >complete. > >On Sat, Sep 7, 2019, 1:25 AM Ian Davidson <[hidden email]> >wrote: > >> This is a guess. >> >> I suspect that step 8 (setting the state to NULL) may take some time >to >> complete. Does it raise a signal when the state changes? If you set >the >> state to NULL and then blindly go ahead and unref things you are >hoping >> that the state change will have completed quickly. So, sometimes, >you >> will 'get away with it' and sometimes you will crash. >> >> Ian >> >> >> On 06/09/19 23:45, Olivier Crête wrote: >> > Hi, >> > >> > You don't need a separate gmainloop per pipeline, you can use the >same >> one for all of them. They'll all use the default main context. So you >do >> steps 3 & 6 only once. >> > >> > Olivier >> > >> > On September 6, 2019 4:32:41 p.m. EDT, Ben Rush <[hidden email]> >> wrote: >> >> I have a need to put multiple video windows in a single >application. >> >> This >> >> means multiple pipelines. For example, the RTSP URL is different >for >> >> each >> >> player, and so I get a new pipeline for each invocation >> >> of gst_parse_launch. >> >> >> >> I can share code, but in general: what is the best way to do this? >The >> >> way >> >> I'm doing this now (for EACH player I've instantiated in the SAME >app): >> >> >> >> 1) gst_parse_launch, get back the pipeline, >> >> 2) gst_pipeline_get_bus, to create a bus on this pipeline. >> >> 3) g_main_loop_new(NULL, FALSE) to create a new loop (this is >where my >> >> main >> >> question is at) >> >> 4) gst_bus_add_watch to create an add watch on this pipeline, >> >> 5) gst_element_set_state to set my pipeline state to >GST_STATE_PLAYING >> >> 6) g_main_loop_run on the loop returned from #3 >> >> 7) Then I play until a stop is issued.... >> >> 8) gst_element_set_state(pipeline, GST_STATE_NULL) >> >> 9) unref the bus, >> >> 10) unref the pipeline >> >> 11) unref the loop >> >> >> >> I ask about this order, and the fact I'm creating a new loop >without an >> >> independent context because I'm getting some random crashes in my >app >> >> hosting multiple players, and it appears to be during tear down. >In >> >> general, is this pattern acceptable, or have I committed a sin >> >> somewhere? >> >> _______________________________________________ >> gstreamer-devel mailing list >> [hidden email] >> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel -- Olivier Crête [hidden email] _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hi,
You might have a look to the small app https://github.com/dabrain34/gst-n-launch/ Best regards -- 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 |