[gthumb] video viewer: fixed screenshot when using the opengl backend
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] video viewer: fixed screenshot when using the opengl backend
- Date: Thu, 10 Jan 2019 18:17:18 +0000 (UTC)
commit 473d9d3d8a5047bac76c36e9c3283569dcbe48cd
Author: Paolo Bacchilega <paobac src gnome org>
Date: Mon Dec 31 10:21:01 2018 +0100
video viewer: fixed screenshot when using the opengl backend
extensions/gstreamer_utils/gstreamer-utils.c | 105 ++++++++++++++++++++-------
1 file changed, 79 insertions(+), 26 deletions(-)
---
diff --git a/extensions/gstreamer_utils/gstreamer-utils.c b/extensions/gstreamer_utils/gstreamer-utils.c
index cf1ce49c..d1f5e972 100644
--- a/extensions/gstreamer_utils/gstreamer-utils.c
+++ b/extensions/gstreamer_utils/gstreamer-utils.c
@@ -42,6 +42,7 @@
#include <config.h>
#include <gst/gst.h>
+#include <gst/video/video.h>
#include <gthumb.h>
#include "gstreamer-utils.h"
@@ -682,62 +683,113 @@ _gst_playbin_get_current_frame (GstElement *playbin,
gpointer user_data)
{
ScreenshotData *data;
- GstCaps *to_caps;
+ GstElement *sink;
GstSample *sample;
GstCaps *sample_caps;
+ const char *format;
GstStructure *s;
- int outwidth;
- int outheight;
+ int width;
+ int height;
data = g_new0 (ScreenshotData, 1);
data->cb = cb;
data->user_data = user_data;
- /* our desired output format (RGB24) */
- to_caps = gst_caps_new_simple ("video/x-raw",
- "format", G_TYPE_STRING, "RGB",
- /* Note: we don't ask for a specific width/height here, so that
- * videoscale can adjust dimensions from a non-1/1 pixel aspect
- * ratio to a 1/1 pixel-aspect-ratio. We also don't ask for a
- * specific framerate, because the input framerate won't
- * necessarily match the output framerate if there's a deinterlacer
- * in the pipeline. */
- "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
- NULL);
-
- /* get frame */
+ sink = gst_bin_get_by_name (GST_BIN(playbin), "sink");
+ if (sink == NULL) {
+ g_warning ("Could not take screenshot: %s", "no sink on playbin");
+ screenshot_data_finalize (data);
+ return FALSE;
+ }
+
sample = NULL;
- g_signal_emit_by_name (playbin, "convert-sample", to_caps, &sample);
- gst_caps_unref (to_caps);
+ g_object_get (sink, "last-sample", &sample, NULL);
+ g_object_unref (sink);
if (sample == NULL) {
- g_warning ("Could not take screenshot: %s", "failed to retrieve or convert video frame");
+ g_warning ("Could not take screenshot: %s", "failed to retrieve video frame");
+ screenshot_data_finalize (data);
+ return FALSE;
+ }
+
+ sample_caps = gst_sample_get_caps (sample);
+ if (sample_caps == NULL) {
+ g_warning ("Could not take screenshot: %s", "no caps on output buffer");
screenshot_data_finalize (data);
return FALSE;
}
+ s = gst_caps_get_structure (sample_caps, 0);
+ format = gst_structure_get_string (s, "format");
+
+ /*g_print ("cap: %s\n", gst_caps_to_string (sample_caps));
+ g_print ("format: %s\n", format);*/
+
+ if ((g_strcmp0 (format, "RGB") != 0) && (g_strcmp0 (format, "RGBA") != 0)) {
+ GstCaps *to_caps;
+ GstSample *to_sample;
+ GError *error = NULL;
+
+ /* our desired output format (RGB24) */
+ to_caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "RGB",
+ /* Note: we don't ask for a specific width/height here, so that
+ * videoscale can adjust dimensions from a non-1/1 pixel aspect
+ * ratio to a 1/1 pixel-aspect-ratio. We also don't ask for a
+ * specific framerate, because the input framerate won't
+ * necessarily match the output framerate if there's a
deinterlacer
+ * in the pipeline. */
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
+ NULL);
+ to_sample = gst_video_convert_sample (sample, to_caps, GST_CLOCK_TIME_NONE, &error);
+
+ gst_caps_unref (to_caps);
+ gst_sample_unref (sample);
+
+ if (to_sample == NULL) {
+ g_warning ("Could not take screenshot: %s", (error != NULL) ? error->message :
"failed to convert video frame");
+ g_clear_error (&error);
+ screenshot_data_finalize (data);
+ return FALSE;
+ }
+
+ sample = to_sample;
+ }
+
sample_caps = gst_sample_get_caps (sample);
if (sample_caps == NULL) {
g_warning ("Could not take screenshot: %s", "no caps on output buffer");
+ screenshot_data_finalize (data);
return FALSE;
}
+ /*g_print ("cap: %s\n", gst_caps_to_string (sample_caps));*/
+
s = gst_caps_get_structure (sample_caps, 0);
- gst_structure_get_int (s, "width", &outwidth);
- gst_structure_get_int (s, "height", &outheight);
- if ((outwidth > 0) && (outheight > 0)) {
+ gst_structure_get_int (s, "width", &width);
+ gst_structure_get_int (s, "height", &height);
+ format = gst_structure_get_string (s, "format");
+
+ if ((g_strcmp0 (format, "RGB") != 0) && (g_strcmp0 (format, "RGBA") != 0)) {
+ g_warning ("Could not take screenshot: %s", "wrong format");
+ screenshot_data_finalize (data);
+ return FALSE;
+ }
+
+ if ((width > 0) && (height > 0)) {
GstMemory *memory;
GstMapInfo info;
+ gboolean with_alpha = (g_strcmp0 (format, "RGBA") == 0);
memory = gst_buffer_get_memory (gst_sample_get_buffer (sample), 0);
if (gst_memory_map (memory, &info, GST_MAP_READ))
data->pixbuf = gdk_pixbuf_new_from_data (info.data,
GDK_COLORSPACE_RGB,
- FALSE,
+ with_alpha,
8,
- outwidth,
- outheight,
- GST_ROUND_UP_4 (outwidth * 3),
+ width,
+ height,
+ GST_ROUND_UP_4 (width * (with_alpha ? 4 :
3)),
destroy_pixbuf,
sample);
@@ -747,6 +799,7 @@ _gst_playbin_get_current_frame (GstElement *playbin,
if (data->pixbuf == NULL)
g_warning ("Could not take screenshot: %s", "could not create pixbuf");
+ gst_sample_unref (sample);
screenshot_data_finalize (data);
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]