Hi Guys,
I am trying to modify wxMediaCtrl so that I can save a file. wxMediaCtrl uses playbin (which I am updating to playbin2). I have experimented with GST_PLAY_FLAG_DOWNLOAD, but the quality is not really good enough. So I am trying to create a new top-level bin containing the following tee name=t ! t. ! queue ! ffmpegcolorspace ! ximagesink ! t. ! queue videorate ! video/x-raw-yuv,framerate=10/1 ! y4menc ! filesink location=vid_tmp_mkv I then attach playbin2 to bin via its video-sink property with ghostpads. My issue is that I get nothing. No errors just a blank screen. The code follows. Many thanks in advance for your help. Regards Steve //-------------------------------------------------------------------------- --- // wxGStreamerMediaBackend::DeviceCapture // // Used to Capture and store input from a local device (eg /dev/video0) in a specified file. //-------------------------------------------------------------------------- --- //bool wxGStreamerMediaBackend::DeviceCapture(const gchar* fileSaveName, // If NULL just plays device, doesn't save. // const wxString& inputDevice, // Defaults to /dev/video0 // const wxString& gst_encoder, // Defaults to y4menc // long encode_quality, // Defaults to encoder default // long framesSecond) // Defaults to 10/1 bool wxGStreamerMediaBackend::DeviceCapture() { // Pause video and delete Bin. g_printerr ("DeviceCapture starts.\n"); // Set playbin to ready to stop the current media... if( gst_element_set_state (m_playbin, GST_STATE_READY) == GST_STATE_FAILURE || !SyncStateChange(m_playbin, GST_STATE_READY)) { wxLogSysError(wxT("wxGStreamerMediaBackend::Load - ") wxT("Could not set initial state to ready")); return false; } // free current media resources gst_element_set_state (m_playbin, GST_STATE_NULL); // // Create DeviceCapture object // GstElement *bin, *videotee, *monitorqueue, *filequeue, *colorspace, *encoder, *filesink; GstPad *pad, *ghostpad; // Create elements bin = gst_bin_new ("sink_bin"); videotee = gst_element_factory_make ("tee", "videotee"); monitorqueue = gst_element_factory_make ("queue", "monitorqueue"); filequeue = gst_element_factory_make ("queue", "filequeue"); colorspace = gst_element_factory_make ("ffmpegcolorspace", "colorspace"); // Setup video sink - first try gconf, then auto, then xvimage and // then finally plain ximage GstElement* videosink = gst_gconf_get_default_video_sink(); if( !TryVideoSink(videosink) ) { videosink = gst_element_factory_make ("autovideosink", "video-sink"); if( !TryVideoSink(videosink) ) { videosink = gst_element_factory_make ("xvimagesink", "video-sink"); if( !TryVideoSink(videosink) ) { // finally, do a final fallback to ximagesink videosink = gst_element_factory_make ("ximagesink", "video-sink"); if( !TryVideoSink(videosink) ) { g_object_unref(videosink); wxLogSysError(wxT("Could not find a suitable video sink")); return false; } } } } encoder = gst_element_factory_make ("y4menc", "videoenc"); filesink = gst_element_factory_make ("filesink", "filesink"); // Error reporting if (!bin|| !colorspace || !encoder || !videotee ) { g_printerr ("One element could not be created.\n"); return NULL; } // Set paramaters for the GstElements g_object_set (G_OBJECT (filesink), "location", "tmp_vid.mkv", NULL); // add elements to pipeline gst_bin_add_many (GST_BIN (bin), colorspace, encoder, videotee, monitorqueue, videosink, filequeue, filesink, NULL); pad = gst_element_get_static_pad (videotee, "sink"); ghostpad = gst_ghost_pad_new ("sink_pad", pad); gst_element_add_pad(bin, ghostpad); // link elements. gst_element_link_many( videotee, monitorqueue, colorspace, videosink, NULL ); gst_element_link_many( videotee, filequeue, NULL ); // Create caps stuff GstCaps *caps; caps = gst_caps_new_simple ("video/x-raw-yuv", // "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), // "width", G_TYPE_INT, 384, // "height", G_TYPE_INT, 288, "framerate", GST_TYPE_FRACTION, 10, 1, NULL); gboolean link_ok; link_ok = gst_element_link_filtered (filequeue, encoder, caps); if (!link_ok) { g_warning ("Failed to link filequeue and encoder."); } gst_caps_unref (caps); if (!GST_IS_ELEMENT(bin)) { if(G_IS_OBJECT(bin)) g_object_unref(bin); wxLogSysError(wxT("Got an invalid bin")); return false; } gst_element_link_many( encoder, filesink, NULL ); // // Now that we know (or, rather think) our video and audio sink // // are valid set our playbin to use them g_object_set (G_OBJECT (m_playbin), "video-sink", bin, NULL); // Try to pause media as gstreamer won't let us query attributes // such as video size unless it is paused or playing if( gst_element_set_state (m_playbin, GST_STATE_PAUSED) == GST_STATE_FAILURE || !SyncStateChange(m_playbin, GST_STATE_PAUSED)) { return false; // no real error message needed here as this is // generic failure 99% of the time (i.e. no // source etc.) and has an error message } g_printerr ("DeviceCapture activated.\n"); return true; } _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
On 10/11/2011 05:01 PM, Steve wrote:
> Hi Guys, > > I am trying to modify wxMediaCtrl so that I can save a file. > > wxMediaCtrl uses playbin (which I am updating to playbin2). I have > experimented with GST_PLAY_FLAG_DOWNLOAD, but the quality is not really good > enough. > > So I am trying to create a new top-level bin containing the following > > tee name=t ! t. ! queue ! ffmpegcolorspace ! ximagesink ! t. ! queue > videorate ! video/x-raw-yuv,framerate=10/1 ! y4menc ! filesink > location=vid_tmp_mkv videorate ! video/x-raw-yuv,framerate=10/1 ! y4menc ! filesink location=vid_tmp_mkv two ! too much, but in the code it looks alright. You could use GST_DEBUG_BIN_TO_DOT_FILE to get a graph of the resulting pipleine Stefan > I then attach playbin2 to bin via its video-sink property with ghostpads. > > My issue is that I get nothing. No errors just a blank screen. > > The code follows. > > Many thanks in advance for your help. > > Regards > > Steve > > //-------------------------------------------------------------------------- > --- > // wxGStreamerMediaBackend::DeviceCapture > // > // Used to Capture and store input from a local device (eg /dev/video0) in a > specified file. > //-------------------------------------------------------------------------- > --- > //bool wxGStreamerMediaBackend::DeviceCapture(const gchar* fileSaveName, // > If NULL just plays device, doesn't save. > // const wxString& inputDevice, // Defaults to /dev/video0 > // const wxString& gst_encoder, // Defaults to y4menc > // long encode_quality, // Defaults to encoder default > // long framesSecond) // Defaults to 10/1 > bool wxGStreamerMediaBackend::DeviceCapture() > { > // Pause video and delete Bin. > > g_printerr ("DeviceCapture starts.\n"); > // Set playbin to ready to stop the current media... > if( gst_element_set_state (m_playbin, > GST_STATE_READY) == GST_STATE_FAILURE || > !SyncStateChange(m_playbin, GST_STATE_READY)) > { > wxLogSysError(wxT("wxGStreamerMediaBackend::Load - ") > wxT("Could not set initial state to ready")); > return false; > } > // free current media resources > gst_element_set_state (m_playbin, GST_STATE_NULL); > // > // Create DeviceCapture object > // > GstElement *bin, *videotee, *monitorqueue, *filequeue, *colorspace, > *encoder, *filesink; > GstPad *pad, *ghostpad; > // Create elements > bin = gst_bin_new ("sink_bin"); > > videotee = gst_element_factory_make ("tee", "videotee"); > monitorqueue = gst_element_factory_make ("queue", "monitorqueue"); > filequeue = gst_element_factory_make ("queue", "filequeue"); > colorspace = gst_element_factory_make ("ffmpegcolorspace", > "colorspace"); > > // Setup video sink - first try gconf, then auto, then xvimage and > // then finally plain ximage > GstElement* videosink = gst_gconf_get_default_video_sink(); > if( !TryVideoSink(videosink) ) > { > videosink = gst_element_factory_make ("autovideosink", "video-sink"); > if( !TryVideoSink(videosink) ) > { > videosink = gst_element_factory_make ("xvimagesink", "video-sink"); > if( !TryVideoSink(videosink) ) > { > // finally, do a final fallback to ximagesink > videosink = > gst_element_factory_make ("ximagesink", "video-sink"); > if( !TryVideoSink(videosink) ) > { > g_object_unref(videosink); > wxLogSysError(wxT("Could not find a suitable video sink")); > return false; > } > } > } > } > > encoder = gst_element_factory_make ("y4menc", "videoenc"); > filesink = gst_element_factory_make ("filesink", "filesink"); > > > // Error reporting > if (!bin|| !colorspace || !encoder > || !videotee ) { > g_printerr ("One element could not be created.\n"); > return NULL; > } > > // Set paramaters for the GstElements > g_object_set (G_OBJECT (filesink), "location", "tmp_vid.mkv", NULL); > > // add elements to pipeline > gst_bin_add_many (GST_BIN (bin), > colorspace, encoder, videotee, monitorqueue, videosink, filequeue, > filesink, NULL); > pad = gst_element_get_static_pad (videotee, "sink"); > ghostpad = gst_ghost_pad_new ("sink_pad", pad); > gst_element_add_pad(bin, ghostpad); > // link elements. > gst_element_link_many( videotee, monitorqueue, colorspace, videosink, > NULL ); > gst_element_link_many( videotee, filequeue, NULL ); > > // Create caps stuff > GstCaps *caps; > caps = gst_caps_new_simple ("video/x-raw-yuv", > // "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), > // "width", G_TYPE_INT, 384, > // "height", G_TYPE_INT, 288, > "framerate", GST_TYPE_FRACTION, 10, 1, > NULL); > gboolean link_ok; > link_ok = gst_element_link_filtered (filequeue, encoder, caps); > if (!link_ok) { > g_warning ("Failed to link filequeue and encoder."); > } > gst_caps_unref (caps); > > if (!GST_IS_ELEMENT(bin)) > { > if(G_IS_OBJECT(bin)) > g_object_unref(bin); > wxLogSysError(wxT("Got an invalid bin")); > return false; > } > gst_element_link_many( encoder, filesink, NULL ); > > // // Now that we know (or, rather think) our video and audio sink > // // are valid set our playbin to use them > g_object_set (G_OBJECT (m_playbin), > "video-sink", bin, > NULL); > > // Try to pause media as gstreamer won't let us query attributes > // such as video size unless it is paused or playing > if( gst_element_set_state (m_playbin, > GST_STATE_PAUSED) == GST_STATE_FAILURE || > !SyncStateChange(m_playbin, GST_STATE_PAUSED)) > { > return false; // no real error message needed here as this is > // generic failure 99% of the time (i.e. no > // source etc.) and has an error message > } > g_printerr ("DeviceCapture activated.\n"); > > return true; > } > > > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hi Stefan,
Thanks for this. There were actually a lot of silly bugs in the code. Too many to go into here, but the main one I haven't fixed is the caps code: This doesn't work, > gst_element_link_many( videotee, monitorqueue, colorspace, videosink, > NULL ); > gst_element_link_many( videotee, filequeue, NULL ); > > // Create caps stuff > GstCaps *caps; > caps = gst_caps_new_simple ("video/x-raw-yuv", > "framerate", GST_TYPE_FRACTION, 10, 1, > NULL); > gst_element_link_filtered (filequeue, encoder, caps); > gst_element_link_many( encoder, filesink, NULL ); But this does: > gst_element_link_many( videotee, monitorqueue, colorspace, videosink, > NULL ); > gst_element_link_many( videotee, filequeue, encoder, filesink, NULL ); I still can't see what's not working. Regards Steve _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
On 10/14/2011 02:26 AM, Steve wrote:
> Hi Stefan, > > Thanks for this. There were actually a lot of silly bugs in the code. Too > many to go into here, but the main one I haven't fixed is the caps code: > > This doesn't work, > >> gst_element_link_many( videotee, monitorqueue, colorspace, > videosink, >> NULL ); >> gst_element_link_many( videotee, filequeue, NULL ); >> >> // Create caps stuff >> GstCaps *caps; >> caps = gst_caps_new_simple ("video/x-raw-yuv", >> "framerate", GST_TYPE_FRACTION, 10, 1, >> NULL); >> gst_element_link_filtered (filequeue, encoder, caps); >> gst_element_link_many( encoder, filesink, NULL ); > But this does: You probably want to include a videorate element before the capsfilter. gst_element_link_many( videotee, filequeue, videorate, NULL ); gst_element_link_filtered (videorate, encoder, caps); gst_element_link_many( encoder, filesink, NULL ); Before you miss something that adjust to the rate you want to select by using a caps filter. Also it would be a good idea to check the return values from gst_element_link_*. That would hae told you ... Stefan >> gst_element_link_many( videotee, monitorqueue, colorspace, > videosink, >> NULL ); >> gst_element_link_many( videotee, filequeue, encoder, filesink, NULL > ); > > I still can't see what's not working. > > Regards > > Steve > > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hi Stefan,
>You probably want to include a videorate element before the capsfilter. >gst_element_link_many( videotee, filequeue, videorate, NULL ); >gst_element_link_filtered (videorate, encoder, caps); >gst_element_link_many( encoder, filesink, NULL ); >Before you miss something that adjust to the rate you want to select by >using a caps filter. Also it would be a good idea to check the return >values from gst_element_link_*. That would hae told you ... Thanks for this. It worked perfectly. And you were right about checking the return values. I put the checks in. Regards Steve _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |