[gst-devel] Video freeze
lithium
cmaster2 at hotmail.com
Mon Jan 10 08:41:34 CET 2011
Well I've been working on debugging this. I've created debug logs of my
program run with --gst-debug-level 5
if i use gst_pad_set_blocked:
the first run of take screenshot causes a 0byte jpeg to be created.
The second time i click screenshot I get the image that was there when
screenshot was clicked the first time written to the jpeg, the video freezes
and the log shows this:
0:00:03.492790081 [332m 6199[00m 0x1703f30 [37mLOG [00m
[00;01;35m GST_SCHEDULING
gstpad.c:1036:gst_pad_set_blocked_async_full:<splitter:src2>[00m blocking
pad
0:00:03.492806842 [332m 6199[00m 0x1703f30 [37mLOG [00m
[00;01;35m GST_SCHEDULING
gstpad.c:1048:gst_pad_set_blocked_async_full:<splitter:src2>[00m waiting
for block
after which point nothing more shows up
if i remove the gst_pad_set_blocked lines:
the first run of take screenshot causes a 0byte jpeg to be created.
The second time i click screenshot I get the image that was there when
screenshot was clicked the first time written to the jpeg, the video does
not freeze, and the log continues having information about everything im
doing written to it.
Further clicks cause the image that was there when the screenshot was
clicked the first time to be re-written to the jpeg file.
In the bus sync handler I check for state paused because for reasons unknown
to me the message i construct telling it to set it to GST_STATE_NULL does
not set it to GST_STATE_NULL but GST_STATE_PAUSED
heres the current functions:
void close_screenshot(GstElement *jpegEncode, videoIOStruct *videoIO)
{
GstPad *sinkpad = gst_element_get_pad(videoIO->screenshotBin, "sink");
GstPad *srcpad = gst_pad_get_peer(sinkpad);
if (!srcpad)
return; //if we dont have a src pad its already been released need to
check because another jpeg may be encoded before we close the screenshot
gst_pad_set_blocked(srcpad, TRUE);
gst_pad_unlink(srcpad, sinkpad);
gst_pad_set_blocked(srcpad, FALSE);
gst_element_release_request_pad(videoIO->tee, srcpad);
gst_object_unref(srcpad);
gst_object_unref(sinkpad);
//send a state request back to main thread
GstMessage *setState =
gst_message_new_request_state(GST_OBJECT(videoIO->screenshotBin),
GST_STATE_NULL);
GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE(videoIO->pipeline));
gst_bus_post(bus, setState);
gst_object_unref(bus);
}
void take_screenshot(GtkWidget *widget, videoIOStruct *videoIO)
{
gst_element_set_state(videoIO->screenshotBin, GST_STATE_PAUSED);
gst_bin_add(GST_BIN(videoIO->pipeline), videoIO->screenshotBin);
GstPad *sinkpad = gst_element_get_pad(videoIO->screenshotBin, "sink");
GstPad *srcpad = gst_element_get_request_pad(videoIO->tee, "src%d");
g_print("srcpadref: %d\n", GST_OBJECT_REFCOUNT(GST_OBJECT(srcpad)));
gst_pad_set_blocked(srcpad, TRUE);
gst_pad_link(srcpad, sinkpad);
gst_pad_set_blocked(srcpad, FALSE);
gst_object_unref(sinkpad);
gst_element_set_state(videoIO->pipeline, GST_STATE_PLAYING);
}
int setup_screenshotBin(videoIOStruct *videoIO)
{
videoIO->screenshotBin = gst_bin_new("screenshot_bin");
GstElement *jpegOutput = gst_element_factory_make("filesink",
"jpegoutput");
GstElement *jpegQueue = gst_element_factory_make("queue", "jpgqueue");
GstElement *jpegEncode = gst_element_factory_make("jpegenc",
"jpegencoder");
if (!jpegOutput || !jpegQueue || !jpegEncode || !videoIO->screenshotBin)
return 0;
//set arguments
// g_object_set(G_OBJECT(jpegOutput), "location", g_strdup("test.jpg"),
NULL); //FIXME: why cant i use set_data???
//set arguments
gchar filename[] = "test.jpg";
g_object_set(G_OBJECT(jpegOutput), "location", filename, NULL);
//link stuff
gst_bin_add_many(GST_BIN(videoIO->screenshotBin), jpegQueue, jpegEncode,
jpegOutput, NULL);
gst_element_link_many(jpegQueue, jpegEncode, jpegOutput, NULL);
g_signal_connect(jpegEncode, "frame-encoded", G_CALLBACK(close_screenshot),
videoIO);
GstPad *sinkpad = gst_element_get_static_pad(jpegQueue, "sink");
gst_element_add_pad(videoIO->screenshotBin, gst_ghost_pad_new("sink",
sinkpad));
gst_object_unref(GST_OBJECT(sinkpad));
return 1;
}
int openVideoPipeline(videoIOStruct *videoIO)
{
/*
/----queue----xvimagesink //screenoutput
v4l2src-----tee-----
\----queue----filesink //screenshot
\----queue----\
----multiplexer ---filesink //recording
/----queue----/
alsasrc-----tee-----
\----queue----alsasink //playback from capture if needed
*/
//create elements
videoIO->pipeline = gst_pipeline_new("tvVideo");
videoIO->vidSrc = gst_element_factory_make("v4l2src", "v4lsource");
GstElement *vidSink = gst_element_factory_make("xvimagesink", "xvsink");
videoIO->tee = gst_element_factory_make("tee", "splitter");
GstElement *vidQueue = gst_element_factory_make("queue", "screenQueue");
if (!videoIO->pipeline || !videoIO->vidSrc || !vidSink || !videoIO->tee ||
!vidQueue)
return 0;
//set arguments
g_object_set(videoIO->vidSrc, "device", videoIO->devName, NULL);
gst_bin_add_many(GST_BIN(videoIO->pipeline), videoIO->vidSrc, videoIO->tee,
vidQueue, vidSink, NULL);
GstPad *teeSrc = gst_element_get_request_pad(videoIO->tee, "src%d");
//FIXME: release on program exit
GstPad *screenQueue = gst_element_get_static_pad(vidQueue, "sink");
//link stuff
gst_pad_link(teeSrc, screenQueue);
gst_object_unref(screenQueue);
gst_element_link(videoIO->vidSrc, videoIO->tee);
gst_element_link(vidQueue, vidSink);
if (!videoIO->pipeline)
return 0;
return 1;
}
GstBusSyncReply bus_sync_handler(GstBus *bus, GstMessage *message,
videoIOStruct *videoIO)
{
if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ASYNC_DONE)
{
GstState state;
GstState pending;
gst_element_get_state(videoIO->screenshotBin, &state, &pending, NULL);
if (state == GST_STATE_PAUSED)
{
GstObject *parent = gst_element_get_parent(videoIO->screenshotBin);
if (parent)
{
gst_bin_remove(GST_BIN(videoIO->pipeline), videoIO->screenshotBin);
gst_object_unref(parent);
}
}
}
if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (!gst_structure_has_name(message->structure, "prepare-xwindow-id"))
return GST_BUS_PASS;
if (*videoIO->videoWindowXId != 0)
{
GstXOverlay *xOverlay = GST_X_OVERLAY(GST_MESSAGE_SRC(message));
gst_x_overlay_set_xwindow_id(xOverlay, *videoIO->videoWindowXId);
}
else
g_warning("Should have obtained video_window_xid by now!");
gst_message_unref(message);
return GST_BUS_DROP;
}
any ideas?
--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Video-freeze-tp3171570p3206707.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
More information about the gstreamer-devel
mailing list