single frame snapshot

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

single frame snapshot

jmz
I want to take a snapshot of one single frame from H.264 stream. I have tried several pipelines but they did not work.

1. I used "pngenc snapshot=true ! filesink" as follows:
... ! h264parse ! avdec_h264 ! videoconvert ! pngenc snapshot=true ! filesink location=sink.png

Although one sink.png file was generated, several PNG images, in fact, are stored in this file (see the finding in my next pipeline).

2. I replaced filesink with multifilesink as follows:
... ! h264parse ! avdec_h264 ! videoconvert ! pngenc snapshot=true ! multifilesink location=img%d.png

Three files img1.png ~ img3.png were generated. I found that the total size of the three files is equal to the size of the previous sink.png. Why doesn't "snapshot=true" (Send EOS after encoding a frame) work with pngenc?

3. I added "next-file=key-frame" to multifilesink as follows:

... ! h264parse ! avdec_h264 ! videoconvert ! pngenc snapshot=true ! multifilesink location=key%d.png next-file=key-frame

Only one key1.png was generated. But the file size is equal to the sink.png (also the sum of img1.png ~ img3.png). Should "next-file=key-frame" generate new file at only keyframe?

Can I use jpegenc to take one single JPEG snapshot of H.264 stream?
Reply | Threaded
Open this post in threaded view
|

AW: single frame snapshot

Thornton, Keith
Hi, I do this by setting a pad probe at the start of the pipeline and only letting one frame through. I wait for the frame tob e an IDR frame bevor letting it through. Something similar to the logic below

pThumbnail->letBufferThrough();
gst_pad_add_probe(m_pFirstElementSinkPad, GST_PAD_PROBE_TYPE_BUFFER, static_cast<GstPadProbeCallback>(cb_blocked), pThumbnail, 0);

static GstPadProbeReturn cb_blocked(GstPad* pad, GstPadProbeInfo* info, gpointer user_data)
    {
        Q_UNUSED(info);
        Q_UNUSED(pad);
        GstreamerH264Thumbnail* pThumbnail = static_cast<GstreamerH264Thumbnail*>(user_data);
        if (pThumbnail->isLetBufferThrough())
        {
                        GstBuffer * pBuffer = gst_pad_probe_info_get_buffer(info);
                        if (pBuffer) {
                                if (GST_BUFFER_FLAG_IS_SET(pBuffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
                                        return GST_PAD_PROBE_DROP;
                                }
                        }
                        return GST_PAD_PROBE_PASS;
                }
        else
        {
            return GST_PAD_PROBE_DROP;
        }
    }




-----Ursprüngliche Nachricht-----
Von: gstreamer-devel [mailto:[hidden email]] Im Auftrag von jmz
Gesendet: Freitag, 14. Juli 2017 08:46
An: [hidden email]
Betreff: single frame snapshot

I want to take a snapshot of one single frame from H.264 stream. I have tried several pipelines but they did not work.

1. I used "pngenc snapshot=true ! filesink" as follows:
... ! h264parse ! avdec_h264 ! videoconvert ! pngenc snapshot=true !
filesink location=sink.png

Although one sink.png file was generated, several PNG images, in fact, are stored in this file (see the finding in my next pipeline).

2. I replaced filesink with multifilesink as follows:
... ! h264parse ! avdec_h264 ! videoconvert ! pngenc snapshot=true !
multifilesink location=img%d.png

Three files img1.png ~ img3.png were generated. I found that the total size of the three files is equal to the size of the previous sink.png. Why doesn't "snapshot=true" (Send EOS after encoding a frame) work with pngenc?

3. I added "next-file=key-frame" to multifilesink as follows:

... ! h264parse ! avdec_h264 ! videoconvert ! pngenc snapshot=true !
multifilesink location=key%d.png next-file=key-frame

Only one key1.png was generated. But the file size is equal to the sink.png (also the sum of img1.png ~ img3.png). Should "next-file=key-frame" generate new file at only keyframe?

Can I use jpegenc to take one single JPEG snapshot of H.264 stream?




--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/single-frame-snapshot-tp4683820.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: single frame snapshot

Baby Octopus
Administrator
In reply to this post by jmz
Pad probe is the option that you can use. Add a probe to the sink pad of filesink and let only one buffer pass through the probe. Once sent, tell the application to send EOS and shut the pipeline down

Another hacky option that you can try is this

... ! videorate ! video/x-raw,framerate=1/10000000 ! filesink

Videorate will send first frame and wait for next frame whcih is after a long time. You can shutdown the pipeline in that time
jmz
Reply | Threaded
Open this post in threaded view
|

Re: single frame snapshot

jmz
Thank Keith and BO for the suggestion on pad probe. I will try it.

On Fri, Jul 14, 2017 at 4:33 PM, Baby Octopus <jagadishkamathk@gmail.com> wrote:
> Another hacky option that you can try is this
> ... ! videorate ! video/x-raw,framerate=1/10000000 ! filesink
>
> Videorate will send first frame and wait for next frame whcih is after a
> long time. You can shutdown the pipeline in that time

I added videorate to my first pipeline as you suggested (I should use 'image/png' not 'video/x-raw', right?):
  ... ! pngenc snapshot=true ! videorate ! 'image/png,framerate=1/10000000' ! filesink location=sink.png

The pipeline did not wait a long time for the next frame and also generated single sink.png file.

I also added videorate to my second pipeline:
  ... ! pngenc snapshot=true ! videorate ! 'image/png,framerate=1/10000000' ! multifilesink location=img%d.png

The second pipeline generated 2 PNG files. However, the sum of the two PNG files is equal to the size of the previous sink.png. The results are the same as that without videorate.

I also found that gst_pngenc_handle_frame() is invoked more than once when snapshot=true is set. Is this correct?