pngenc: output one frame only in snapshot mode
authorTim-Philipp Müller <tim@centricular.com>
Tue, 24 Oct 2023 17:12:44 +0000 (18:12 +0100)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 27 Oct 2023 18:58:29 +0000 (18:58 +0000)
In snapshot mode pngenc should output exactly one frame
and then return FLOW_EOS to upstream. If upstream sends
more input frames before shutting down, it should keep
returning FLOW_EOS but not output any more encoded frames.

After a flushing seek it should output frames again though.

Fixes #3069.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5564>

subprojects/gst-plugins-good/ext/libpng/gstpngenc.c
subprojects/gst-plugins-good/ext/libpng/gstpngenc.h

index f807e4c..3f606ad 100644 (file)
@@ -86,6 +86,7 @@ static GstFlowReturn gst_pngenc_handle_frame (GstVideoEncoder * encoder,
     GstVideoCodecFrame * frame);
 static gboolean gst_pngenc_set_format (GstVideoEncoder * encoder,
     GstVideoCodecState * state);
+static gboolean gst_pngenc_flush (GstVideoEncoder * encoder);
 static gboolean gst_pngenc_propose_allocation (GstVideoEncoder * encoder,
     GstQuery * query);
 
@@ -143,6 +144,7 @@ gst_pngenc_class_init (GstPngEncClass * klass)
   venc_class->set_format = gst_pngenc_set_format;
   venc_class->handle_frame = gst_pngenc_handle_frame;
   venc_class->propose_allocation = gst_pngenc_propose_allocation;
+  venc_class->flush = gst_pngenc_flush;
   gobject_class->finalize = gst_pngenc_finalize;
 
   GST_DEBUG_CATEGORY_INIT (pngenc_debug, "pngenc", 0, "PNG image encoder");
@@ -262,6 +264,16 @@ user_write_data (png_structp png_ptr, png_bytep data, png_uint_32 length)
   gst_buffer_append_memory (pngenc->buffer_out, mem);
 }
 
+static gboolean
+gst_pngenc_flush (GstVideoEncoder * encoder)
+{
+  GstPngEnc *pngenc = GST_PNGENC (encoder);
+
+  pngenc->frame_count = 0;
+
+  return TRUE;
+}
+
 static GstFlowReturn
 gst_pngenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
 {
@@ -273,6 +285,10 @@ gst_pngenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
   GstVideoFrame vframe;
 
   pngenc = GST_PNGENC (encoder);
+
+  if (pngenc->snapshot && pngenc->frame_count > 0)
+    return GST_FLOW_EOS;
+
   info = &pngenc->input_state->info;
 
   GST_DEBUG_OBJECT (pngenc, "BEGINNING");
@@ -343,6 +359,8 @@ gst_pngenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
   if ((ret = gst_video_encoder_finish_frame (encoder, frame)) != GST_FLOW_OK)
     goto done;
 
+  ++pngenc->frame_count;
+
   if (pngenc->snapshot)
     ret = GST_FLOW_EOS;
 
index 878038c..2cd7db6 100644 (file)
@@ -47,7 +47,7 @@ struct _GstPngEnc
   guint compression_level;
 
   gboolean snapshot;
-  gboolean newmedia;
+  guint    frame_count;
 };
 
 GST_ELEMENT_REGISTER_DECLARE (pngenc);