Image conversion through a pipeline

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Image conversion through a pipeline

Olivier Aubert-2
Hello.

Two years ago, I posted some code
( http://article.gmane.org/gmane.comp.video.gstreamer.devel/17603 ) that
allowed me to convert a frame (from the playbin 'frame' property) into
PNG, through a fakesrc/fakesink-based pipeline. A condition variable is
used to "transform" the asynchronous gstreamer behaviour into a
synchronous "snapshot" call.

It has worked perfectly for 2 years, and stopped working in recent
gstreamer releases (at least 0.10.22). It appears that the "handoff"
signal from fakesink is generated only on its first occurrence (i.e. the
first time a snapshot is taken), but never after.
I have tried to use True or False as return values for the handoff
signal handler, to no avail.

I know that the preferred way is now to use appsrc/appsink, but the
fakesrc/sink version is still more generic for the moment (i.e. the
Debian packages have only recently began to ship appsrc/appsink), so I
would like to understand what changed in gstreamer to break my code.

Does anyone have a clue ?

Subsidiary question: how come I cannot do a "get_state" on the
conversion pipeline ? ( fakesrc name=src ! queue name=queue !
videoscale ! ffmpegcolorspace ! video/x-raw-rgb,width=160 ! pngenc !
fakesink name=sink signal-handoffs=true ).

Thanks for any hint.

Olivier



------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations
Conference from O'Reilly Media. Velocity features a full day of
expert-led, hands-on workshops and two days of sessions from industry
leaders in dedicated Performance & Operations tracks. Use code vel09scf
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Image conversion through a pipeline

Tim-Philipp Müller-2
On Thu, 2009-04-30 at 16:10 +0200, Olivier Aubert wrote:

Hi,

> Two years ago, I posted some code
> ( http://article.gmane.org/gmane.comp.video.gstreamer.devel/17603 ) that
> allowed me to convert a frame (from the playbin 'frame' property) into
> PNG, through a fakesrc/fakesink-based pipeline. A condition variable is
> used to "transform" the asynchronous gstreamer behaviour into a
> synchronous "snapshot" call.
>
> It has worked perfectly for 2 years, and stopped working in recent
> gstreamer releases (at least 0.10.22). It appears that the "handoff"
> signal from fakesink is generated only on its first occurrence (i.e. the
> first time a snapshot is taken), but never after.
> I have tried to use True or False as return values for the handoff
> signal handler, to no avail.
>
> I know that the preferred way is now to use appsrc/appsink, but the
> fakesrc/sink version is still more generic for the moment (i.e. the
> Debian packages have only recently began to ship appsrc/appsink), so I
> would like to understand what changed in gstreamer to break my code.
>
> Does anyone have a clue ?

I'm not sure what exactly has changed, but I'm surprised your code
worked all this time before, since what it does is really quite, erm,
unusual, esp. the bit where you insert buffers in the middle of the
pipeline by pushing the snapshot buffer onto the queue pad from the
application thread.

Anyway, so basically when you set the conversion pipeline to PLAYING,
fakesrc will start a streaming thread and start pushing zero-sized
buffers with no caps on them downstream. Videoscale should/will reject
these [no caps, 0 size] and the fakesrc streaming thread will stop with
a not-negotiated flow error; it will also push an eos event downstream
when it does that. This in turn will make basesink drop any buffers you
push into the pipeline after it has stopped streaming:

gstbasesink.c:2931:gst_base_sink_chain_unlocked:<sink> we are EOS,
dropping object, return UNEXPECTED

If for whatever reason you don't want to use appsrc, then you need to
use fakesrc and fakesrc's "handoff" callback rather than just push
buffers into the pipeline in the middle from other threads. Or write
your own source deriving from GstPushSrc.


> Subsidiary question: how come I cannot do a "get_state" on the
> conversion pipeline ? ( fakesrc name=src ! queue name=queue !
> videoscale ! ffmpegcolorspace ! video/x-raw-rgb,width=160 ! pngenc !
> fakesink name=sink signal-handoffs=true ).

Why "can't you"? I mean, what happens? What did you expect to happen -
etc.?

Cheers
 -Tim



------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations
Conference from O'Reilly Media. Velocity features a full day of
expert-led, hands-on workshops and two days of sessions from industry
leaders in dedicated Performance & Operations tracks. Use code vel09scf
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Image conversion through a pipeline

Olivier Aubert-2
Hi Tim

Thanks for the answer and indications. I know that my solution was
hackish, but it indeed worked perfectly for the last 2 years. I will
have a quick go at the fakesrc 'handoff' variation, but I think I will
eventually use appsrc/appsink since it is the more appropriate
approach.

For the get_state() issue, the call locks and never returns. This is
probably due to my weird buffer injection into the pipeline.

Cheers
Olivier

On Sat, 2009-05-02 at 17:28 +0100, Tim-Philipp Müller wrote:

> On Thu, 2009-04-30 at 16:10 +0200, Olivier Aubert wrote:
>
> Hi,
>
> > Two years ago, I posted some code
> > ( http://article.gmane.org/gmane.comp.video.gstreamer.devel/17603 ) that
> > allowed me to convert a frame (from the playbin 'frame' property) into
> > PNG, through a fakesrc/fakesink-based pipeline. A condition variable is
> > used to "transform" the asynchronous gstreamer behaviour into a
> > synchronous "snapshot" call.
> >
> > It has worked perfectly for 2 years, and stopped working in recent
> > gstreamer releases (at least 0.10.22). It appears that the "handoff"
> > signal from fakesink is generated only on its first occurrence (i.e. the
> > first time a snapshot is taken), but never after.
> > I have tried to use True or False as return values for the handoff
> > signal handler, to no avail.
> >
> > I know that the preferred way is now to use appsrc/appsink, but the
> > fakesrc/sink version is still more generic for the moment (i.e. the
> > Debian packages have only recently began to ship appsrc/appsink), so I
> > would like to understand what changed in gstreamer to break my code.
> >
> > Does anyone have a clue ?
>
> I'm not sure what exactly has changed, but I'm surprised your code
> worked all this time before, since what it does is really quite, erm,
> unusual, esp. the bit where you insert buffers in the middle of the
> pipeline by pushing the snapshot buffer onto the queue pad from the
> application thread.
>
> Anyway, so basically when you set the conversion pipeline to PLAYING,
> fakesrc will start a streaming thread and start pushing zero-sized
> buffers with no caps on them downstream. Videoscale should/will reject
> these [no caps, 0 size] and the fakesrc streaming thread will stop with
> a not-negotiated flow error; it will also push an eos event downstream
> when it does that. This in turn will make basesink drop any buffers you
> push into the pipeline after it has stopped streaming:
>
> gstbasesink.c:2931:gst_base_sink_chain_unlocked:<sink> we are EOS,
> dropping object, return UNEXPECTED
>
> If for whatever reason you don't want to use appsrc, then you need to
> use fakesrc and fakesrc's "handoff" callback rather than just push
> buffers into the pipeline in the middle from other threads. Or write
> your own source deriving from GstPushSrc.
>
>
> > Subsidiary question: how come I cannot do a "get_state" on the
> > conversion pipeline ? ( fakesrc name=src ! queue name=queue !
> > videoscale ! ffmpegcolorspace ! video/x-raw-rgb,width=160 ! pngenc !
> > fakesink name=sink signal-handoffs=true ).
>
> Why "can't you"? I mean, what happens? What did you expect to happen -
> etc.?
>
> Cheers
>  -Tim
>
>
>
> ------------------------------------------------------------------------------
> Register Now & Save for Velocity, the Web Performance & Operations
> Conference from O'Reilly Media. Velocity features a full day of
> expert-led, hands-on workshops and two days of sessions from industry
> leaders in dedicated Performance & Operations tracks. Use code vel09scf
> and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel


------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Image conversion through a pipeline

Tim-Philipp Müller-2
On Tue, 2009-05-05 at 12:05 +0200, Olivier Aubert wrote:

Hi,

> I know that my solution was hackish, but it indeed worked perfectly for
> the last 2 years.

Right, I was only really pointing out the hackish aspects of it in order
to justify why we don't jump to fix this 'regression' (which is what
we'd usually do if someone tells us that something that's worked for two
years suddenly stopped working) :)


> For the get_state() issue, the call locks and never returns. This is
> probably due to my weird buffer injection into the pipeline.

If streaming stops due to an error or some other reason (e.g. seek),
_get_state() will not abort and return. A gdb stack trace with debugging
symbols (thread apply all bt) often goes a long way to figure out
where/why it hangs.

Cheers
 -Tim



------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel