Commit 473d9d3d authored by Paolo Bacchilega's avatar Paolo Bacchilega

video viewer: fixed screenshot when using the opengl backend

parent b4cfc787
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment