v 1.12, Incorrect current position of GstPipeline is reported

Mathieu Duponchelle mathieu at centricular.com
Tue Mar 27 10:56:55 UTC 2018


The GES timeline can indeed be used in a regular gstreamer pipeline, but there
are some undocumented quirks, amongst them the "query-position" signal emitted
by the NLEComposition wrapped by the GESTrack object, this is why using GESPipeline
is the recommended approach.

You can have fine-grained control over the encoders that will be picked by encodebin,
by setting the ranks of the various encoder plugins, for example if your system has
both software and hardware encoders for H264, you would list the encoder plugins
with gst_element_factory_list_filter, then set the ranks of those plugins with
gst_plugin_feature_get_rank, according to your order of preference. This will ensure
that the appropriate elements are picked by encodebin when constructing itself, and
spare you some low-level concerns.

On 03/27/2018 04:20 AM, David Ing wrote:
> Mathieu,
>
> Yes the reported duration is correct.
>
> I am not using GESPipeline because I need fine control over the encoders, and GESPipeline doesn't seem to allow that.  I think it forces the usage of encodebin which picks encoders in its own way.
>
> I can tell you that the documentation for GES suggests that GESPipeline exists for  convenience (but not because it is more compatible with GESTimeline).  It also suggests that GESTimeline talks about how it is just another GstElement which can be plugged into a GstPipeline accordingly.  Is the documentation wrong?
>
> I tried casting the GESPipeline down to a GstPipeline and building the pipeline manually myself but it didn't work.  Do you think it should have worked?  (Perhaps I didn't try hard enough.)
>
> Or is there some way of telling the GESPipeline to use specific GstElements with specific settings?  (I don't see anything that might allow that.)
>
> --------------------------------
> >Date: Tue, 27 Mar 2018 02:35:38 +0200
> >From: Mathieu Duponchelle <mathieu at centricular.com <mailto:mathieu at centricular.com>>
> >To: gstreamer-devel at lists.freedesktop.org <mailto:gstreamer-devel at lists.freedesktop.org>
> >Subject: Re: v 1.12, Incorrect current position of GstPipeline is
>         reported
> >Message-ID: <4f917e98-9649-e779-fe29-40078ae035e7 at centricular.com <mailto:4f917e98-9649-e779-fe29-40078ae035e7 at centricular.com>>
> >Content-Type: text/plain; charset="utf-8"
> >
> >Also, more importantly, do you have any reason for not using GESPipeline?
> >
> >If not, I advise you do so, as it's the recommended way to run a GES timeline.
> >
> >On 03/27/2018 02:20 AM, David Ing wrote:
> >> I have a gstreamer pipeline which basically incorporates a GESTimeline, two encoders (audio and video), a muxer, and a filesink.
> >>
> >> When I run the pipeline, I periodically query the stream position (as shown in code below) and print into the terminal (stdout).
> >>
> >> The problem is:  When I run the pipeline, the terminal says that I have reached 100% relatively early (within 2 seconds), but the pipeline itself continues to run for 10 more seconds.  When the terminal reports being 100% done, I can see that the target mp4 file (the final output of the pipeline) is less than 5% of it's final size.
> >>
> >> My goal is to get an accurate indication of the job's progress as it runs
> >>
> >> Other things I've tried.
> >>
> >>   * Tried listening for GST_MESSAGE_PROGRESS messages, but I don't get any.
> >>   * Tried executing `gst_element_query_position` on the filesink (the last element of the pipeline), instead of the entire pipeline itself, but my results did not change.
> >>
> >> The code for my main loop is shown below.  The progress printing occurs near the very bottom of the loop.
> >>
> >>     /// Run the job.  Will throw exception if unsuccessful.
> >>     void CompositionJob::run()
> >>     {
> >>         GstStateChangeReturn stateChangeReturn;
> >>         
> >>         //  Start playing the pipeline.
> >>         stateChangeReturn = gst_element_set_state(reinterpret_cast<GstElement*>(this->gstPipeline), GST_STATE_PLAYING);
> >>         if (stateChangeReturn == GST_STATE_CHANGE_FAILURE)
> >>             throw std::runtime_error("Unable to set the pipeline to the playing state.");
> >>
> >>         //  Talk to the message bus
> >>         this->gstBus = gst_element_get_bus(reinterpret_cast<GstElement*>(this->gstPipeline));
> >>         unique_gmob<GstMessage> gstMessage = nullptr;
> >>         
> >>         this->shouldTerminate = false;
> >>         while (!this->shouldTerminate)
> >>         {
> >>             gstMessage = gst_bus_timed_pop_filtered(this->gstBus, 100 * GST_MSECOND,
> >>                 (GstMessageType)(GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_DURATION));
> >>
> >>             if (gstMessage)
> >>             {
> >>                 this->handleMessage(gstMessage.get());
> >>                 gstMessage.reset();
> >>             }
> >>             else
> >>             {
> >>                 //  If we got no message, a timeout period has expired.
> >>                 if (this->isPlaying)
> >>                 {
> >>                     // Query the stream position (in nanoseconds).
> >>                     if (!gst_element_query_position(
> >>                             reinterpret_cast<GstElement*>(this->gstPipeline),
> >>                             GST_FORMAT_TIME,
> >>                             &this->streamPosition))
> >>                         GST_DEBUG("Could not query current position.");
> >>
> >>                     // Query the duration if we don't have it already.
> >>                     if (!GST_CLOCK_TIME_IS_VALID(this->streamDuration))
> >>                     {
> >>                         if (!gst_element_query_duration(
> >>                                 reinterpret_cast<GstElement*>(this->gstPipeline),
> >>                                 GST_FORMAT_TIME,
> >>                                 &this->streamDuration))
> >>                             GST_DEBUG("Could not get pipeline duration.");
> >>                     }
> >>
> >>                     //  Print position and duration.
> >>                     if (this->printProgress)
> >>                     {
> >>                         g_print("Position %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\r",
> >>                             GST_TIME_ARGS(this->streamPosition), GST_TIME_ARGS(this->streamDuration));
> >>                     }
> >>                 }
> >>             }
> >>         }
> >>     }
> >> 
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20180327/3371d1c8/attachment-0001.html>


More information about the gstreamer-devel mailing list