// // Copyright (C) 2009 Jordi Mas i Hernandez, jmas@softcatala.org // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #include "mistelix.h" void* mistelix_take_screenshot (GstElement* playbin, GstBus* bus, GstElement* pixbufsink, int time); /* Creates a video screenshot using playbin and gdkpixbufsink */ void mistelix_video_screenshot (const char* filein, int second, void** image) { GstElement *playbin, *pixbufsink, *fakesink; GstBus* bus; gchar * uri; void *pix; #ifdef _DEBUG printf ("mistelix_video_snapshoot %s\n", filein); #endif mistelix_check_init (); pixbufsink = gst_element_factory_make ("gdkpixbufsink", "gdkpixbufsink"); fakesink = gst_element_factory_make ("fakesink", "fakesink"); playbin = gst_element_factory_make ("playbin", "playbin"); uri = g_filename_to_uri (filein, NULL, NULL); g_object_set (G_OBJECT (playbin), "uri", uri, NULL); g_object_set (G_OBJECT (playbin), "video-sink", pixbufsink, NULL); g_object_set (G_OBJECT (playbin), "audio-sink", fakesink, NULL); bus = gst_element_get_bus (playbin); g_assert (bus); /* Go to the second 5 since the beginning is black for many videos */ pix = mistelix_take_screenshot (playbin, bus, pixbufsink, second); gst_element_set_state (playbin, GST_STATE_NULL); gst_element_get_state (playbin, NULL, NULL, SEEK_TIMEOUT); gst_object_unref (playbin); gst_object_unref (bus); g_free (uri); *image = pix; } void* mistelix_take_screenshot (GstElement* playbin, GstBus* bus, GstElement* pixbufsink, int time) { void* pix; GstMessage *message; GstMessageType revent; GstStateChangeReturn ret; gst_element_set_state (GST_ELEMENT (playbin), GST_STATE_PAUSED); /* Cannot block for ever because the call never returns for incorrect files */ gst_element_get_state (playbin, NULL, NULL, 2 * GST_SECOND); gboolean bol = gst_element_seek (playbin, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, time * GST_SECOND, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); while (1) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); #ifdef _DEBUG printf ("*** run_pipeline message: %s (%x)\n", gst_message_type_get_name (revent), revent); #endif if (message) { revent = GST_MESSAGE_TYPE (message); gst_message_unref (message); } else revent = GST_MESSAGE_UNKNOWN; if (revent == GST_MESSAGE_UNKNOWN) { #ifdef _DEBUG printf ("*** run_pipeline exiting reason GST_MESSAGE_UNKNOWN\n"); #endif break; } if (revent == GST_MESSAGE_ERROR) { #ifdef _DEBUG printf ("*** run_pipeline exiting reason GST_MESSAGE_ERROR\n"); #endif break; } if (revent == GST_MESSAGE_EOS) { #ifdef _DEBUG printf ("*** run_pipeline exiting reason: GST_MESSAGE_EOS\n"); #endif break; } } g_object_get (G_OBJECT (pixbufsink), "last-pixbuf", &pix, NULL); return pix; }