Lost video
Ian Davidson
id012c3076 at blueyonder.co.uk
Wed Jan 16 13:56:58 PST 2013
Hi,
I'm still getting problems - sometimes when I use gst-launch, I also
only get 1 second plus 2 frames of video. I am not aware of any
particular actions which cause it to work correctly or fail. I modified
my gst-launch to tee off the audio so that I could write 2 files - 1 AVI
with both audio and video and 1 WAV file. I recorded for about 17
seconds and the WAV file came out as 3.1 MB while the AVI was 6.2 MB. I
was wondering whether the video content was actually getting written
(but not properly linked) - but with those file sizes, I am prepared to
believe that only 27 video frames were written to the file.
I would appreciate any help to track down what is going wrong.
Ian
On 14/01/2013 14:56, Ian Davidson wrote:
> My program now works - for very short videos (up to 1 second and 2
> frames duration!)
>
> I have been testing my program and thought it was almost working -
> until I discovered a problem. I had been testing with a video camera
> pointing nowhere in particular and all seemed well, but then, when I
> waved to the camera, I noticed that the video did not include me
> waving. I transferred the video to another machine and noticed that
> while the audio continued as expected, the video stopped after about 1
> second and 2 frames. I tested with the following gst-launch but it
> seems to work OK.
>
> gst-launch-1.0 -e --gst-debug-level=6 v4l2src norm=PAL !
> 'video/x-raw,format=(string)I420,width=320,height=240,framerate=(fraction)25/1'
> ! queue ! mux. alsasrc ! audioconvert !
> 'audio/x-raw,rate=44100,channels=2' ! queue ! mux. avimux name=mux !
> filesink location=test.avi
>
> The program is intended to be functionally the same - the only
> 'embellishment' is that this test version is set to stop recording
> after 1 minute (the live version will have a 40 minute cutoff). The
> program also supports Ctrl-C to stop recording. I have (I hope)
> attached a zip file of the debug output (the middle 56 seconds have
> been removed). I can see that the debug shows
>
> * at 0:00:00.343548749, the pipeline is 'Playing' - so what went
> before is configuration and establishment.
> * it appears to be reporting that both pads have data, repeatedly
> throughout the session
> * there is activity after 1 minute when the EOS gets sent
>
> but I have not noticed anything reporting problems after 1 second when
> the video content stops recording.
>
> I have also tested using gst_parse_launch (instead of constructing the
> pipeline 'by hand') and I get the same problem with the video stopping
> after a second.
>
> Can anyone see what might be going wrong?
>
> Ian
>
> #include <gst/gst.h>
> #include <glib.h>
> #include <signal.h>
> #include <string.h>
>
> static GstElement *pipeline;
> gulong timeout_id;
>
> static gboolean
> bus_call (GstBus *bus,
> GstMessage *msg,
> gpointer data)
> {
> GMainLoop *loop = (GMainLoop *) data;
> switch (GST_MESSAGE_TYPE (msg)) {
>
> case GST_MESSAGE_EOS:
> g_print ("End of stream\n");
> g_main_loop_quit (loop);
> break;
>
> case GST_MESSAGE_ERROR: {
> gchar *debug;
> GError *error;
>
> gst_message_parse_error (msg, &error, &debug);
> g_free (debug);
>
> g_printerr ("Error: %s\n", error->message);
> g_error_free (error);
>
> g_main_loop_quit (loop);
> break;
> }
>
> case GST_MESSAGE_APPLICATION:{
> const GstStructure *s;
>
> s = gst_message_get_structure (msg);
>
> if (gst_structure_has_name (s, "GstLaunchInterrupt")) {
> /* this application message is posted when we caught an
> interrupt and
> * we need to stop the pipeline. */
> g_print ("Interrupt: Stopping pipeline ...\n");
> gst_element_send_event (pipeline, gst_event_new_eos ());
> }
> break;
> }
>
> default:
> break;
> }
>
> return TRUE;
> }
>
>
>
>
> static void
> sigint_restore (void)
> {
> struct sigaction action;
>
> memset (&action, 0, sizeof (action));
> action.sa_handler = SIG_DFL;
>
> sigaction (SIGINT, &action, NULL);
> }
>
>
> static void
> sigint_handler_sighandler (int signum)
> {
> g_print ("Caught interrupt -- ");
>
> gst_element_send_event (pipeline, gst_event_new_eos ());
> sigint_restore ();
> }
>
>
> static void
> sigint_setup (void)
> {
> struct sigaction action;
>
> memset (&action, 0, sizeof (action));
> action.sa_handler = sigint_handler_sighandler;
>
> sigaction (SIGINT, &action, NULL);
> }
>
> /* is called every 40 minutes.
> * I will send an EOS to the pipeline. */
> static gboolean
> times_up (GstElement * pipeline)
> {
> gst_element_send_event (pipeline, gst_event_new_eos ());
> sigint_restore ();
> return FALSE;
> }
>
>
>
> int
> main (int argc,
> char *argv[])
> {
> GMainLoop *loop;
>
> GstElement *vsource, *vcapsfilter, *vidrate, *queue1;
> GstElement *asource, *aconv, *audrate, *acapsfilter, *queue2;
> GstElement *mux, *sink;
> GstBus *bus;
> guint bus_watch_id;
>
> GstCaps *caps;
>
> /* Initialisation */
> gst_init (&argc, &argv);
>
> loop = g_main_loop_new (NULL, FALSE);
>
>
> /* Check input arguments */
> if (argc != 2) {
> g_printerr ("Usage: %s <AVI filename>\n", argv[0]);
> return -1;
> }
>
>
> /* Create gstreamer elements */
> pipeline = gst_pipeline_new ("av-recorder");
> vsource = gst_element_factory_make ("v4l2src", "vid-source");
> vcapsfilter = gst_element_factory_make ("capsfilter", "vid-caps");
> vidrate = gst_element_factory_make ("videorate", "vidrate");
> queue1 = gst_element_factory_make ("queue", "queue1");
> asource = gst_element_factory_make ("alsasrc", "alsa-source");
> aconv = gst_element_factory_make ("audioconvert", "audio-conv");
> acapsfilter = gst_element_factory_make ("capsfilter", "audio-caps");
> audrate = gst_element_factory_make ("audiorate", "audrate");
> queue2 = gst_element_factory_make ("queue", "queue2");
> mux = gst_element_factory_make ("avimux", "avi-mux");
> sink = gst_element_factory_make ("filesink", "file-output");
>
> if (!pipeline || !vsource || !vcapsfilter || !vidrate || !queue1 ||
> !asource || !aconv || !audrate || !acapsfilter || !queue2 || !mux ||
> !sink) {
> g_printerr ("One element could not be created. Exiting.\n");
> return -1;
> }
>
> /* Set up the pipeline */
>
> /* we set the output filename to the sink element */
> g_object_set (G_OBJECT (sink), "location", argv[1], NULL);
>
> /* we set the video capabilities on the vidcaps element */
> caps =
> gst_caps_from_string("video/x-raw,format=(string)I420,width=320,height=240,framerate=(fraction)25/1");
> g_object_set (G_OBJECT (vcapsfilter), "caps", caps, NULL);
> gst_caps_unref (caps);
>
> /* we set the audio capabilities on the audiocaps element */
> caps = gst_caps_from_string("audio/x-raw,rate=44100,channels=2");
> g_object_set (G_OBJECT (acapsfilter), "caps", caps, NULL);
> gst_caps_unref (caps);
>
> g_object_set (G_OBJECT (vsource), "norm", 255, NULL);
>
> /* we add a message handler */
> bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
> bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
> gst_object_unref (bus);
>
> /* we add all elements into the pipeline */
> /* vsource, vcapsfilter, vidrate, queue1,
> asource, aconv, acapsfilter, queue2,
> mux, sink */
> gst_bin_add_many (GST_BIN (pipeline),
> vsource, vcapsfilter, queue1,
> /* vsource, vidrate, vcapsfilter, queue1,*/
> asource, aconv, acapsfilter, queue2,
> /* asource, aconv, audrate, acapsfilter, queue2,*/
> mux, sink, NULL);
>
> /* we link the elements together */
> /* vsource -> vcapsfilter -> vidrate -> queue1 -> avimux
> asource -> aconv -> acapsfilter -> queue2 -> avimux
> mux -> sink */
> gst_element_link_many (vsource, vcapsfilter, queue1, mux, NULL);
> /* gst_element_link_many (vsource, vcapsfilter, vidrate, queue1, mux,
> NULL);*/
> gst_element_link_many (asource, aconv, acapsfilter, queue2, mux,
> NULL);
> /* gst_element_link_many (asource, aconv, audrate, acapsfilter,
> queue2, mux, NULL);*/
> gst_element_link_many (mux, sink, NULL);
>
>
> /* Set the pipeline to "playing" state*/
> g_print ("Now recording: %s\n", argv[1]);
> gst_element_set_state (pipeline, GST_STATE_PLAYING);
>
> sigint_setup ();
> /* timeout_id = g_timeout_add (40 * 60000, (GSourceFunc) times_up,
> pipeline); */
> timeout_id = g_timeout_add (1 * 60000, (GSourceFunc) times_up,
> pipeline);
>
>
> /* Iterate */
> g_print ("Recording (or not!)...\n");
> g_main_loop_run (loop);
>
>
> /* Out of the main loop, clean up nicely */
> g_print ("Returned, stopping recording\n");
> gst_element_set_state (pipeline, GST_STATE_NULL);
>
> g_print ("Deleting pipeline\n");
> gst_object_unref (GST_OBJECT (pipeline));
> g_source_remove (bus_watch_id);
> g_main_loop_unref (loop);
>
> return 0;
> }
>
>
> --
> Ian Davidson
> --
> Facts used in this message may or may not reflect an underlying
> objective reality. Facts are supplied for personal use only.
> Recipients quoting supplied information do so at their own risk. Facts
> supplied may vary in whole or part from widely accepted standards.
> While painstakingly researched, facts may or may not be indicative of
> actually occurring events or natural phenomena.
> The author accepts no responsibility for personal loss or injury
> resulting from memorisation and subsequent use.
>
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
--
--
Ian Davidson
--
Facts used in this message may or may not reflect an underlying
objective reality. Facts are supplied for personal use only.
Recipients quoting supplied information do so at their own risk. Facts
supplied may vary in whole or part from widely accepted standards.
While painstakingly researched, facts may or may not be indicative of
actually occurring events or natural phenomena.
The author accepts no responsibility for personal loss or injury
resulting from memorisation and subsequent use.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20130116/9570bf45/attachment-0001.html>
More information about the gstreamer-devel
mailing list