unsubscribe

Bo Lechnowsky bo at respectech.com
Thu Aug 29 12:06:29 PDT 2013


On 8/29/2013 11:46 AM, Steve Cookson wrote:
> Hi Guys,
>
> I've been hacking the source code for wxMediaCtrl to get it working 
> for a video capture card while displaying and saving the output.  It 
> worked fine for v4l2src, but it doesn't work at all the for decklinksrc.
>
> The basic pipeline works with gst-launch, but the encoded version does 
> not work.  This is the pipeline:
>
> gst-launch -v decklinksrc connection = 3 mode=18 ! videoscale  ! 
> ffmpegcolorspace ! videobalance brightness=.3 contrast=.8 ! gamma 
> gamma=.5 ! tee name=videoTee videoTee. ! queue name=monitorQueue ! 
> xvimagesink sync=false force-aspect-ratio=true videoTee. ! queue 
> name=fileQueue ! videorate ! video/x-raw-yuv,framerate=15/1 ! 
> theoraenc quality=63 keyframe-force=1 ! oggmux ! filesink 
> location=video.ogg
>
> I hope it matches the code!!!
>
> Where have I slipped up?  Your thoughts would be very much appreciated.
>
> The code follows, sorry about it's length :(
>
> Regards
>
> Steve
>
> //----------------------------------------------------------------------------- 
>
> // wxGStreamerMediaBackend::DeviceCapture
> //
> // Used to Capture and store input from a local device (eg 
> /dev/video0) in a specified file.
> //----------------------------------------------------------------------------- 
>
> bool wxGStreamerMediaBackend::DeviceCapture(wxControl* ctrl, wxWindow* 
> parent,
>                                      wxWindowID id,
>                                      const wxPoint& pos,
>                                      const wxSize& size,
>                                      long style,
>                                      const wxValidator& validator,
>                                      const wxString& name)
> {
>         printf ("mediactrl->DeviceCapture option 'wxID_HIGHEST'.\n");
>
>  //   wxMutexLocker lock(m_asynclock); // lock state events and async 
> callbacks
>
>     //
>     //init gstreamer
>     //
>
>     //Convert arguments to unicode if enabled
> #if wxUSE_UNICODE
>     int i;
>     char **argvGST = new char*[wxTheApp->argc + 1];
>     for ( i = 0; i < wxTheApp->argc; i++ )
>     {
>         argvGST[i] = wxStrdupA(wxConvUTF8.cWX2MB(wxTheApp->argv[i]));
>     }
>
>     argvGST[wxTheApp->argc] = NULL;
>
>     int argcGST = wxTheApp->argc;
> #else
> #define argcGST wxTheApp->argc
> #define argvGST wxTheApp->argv
> #endif
>
>     //Really init gstreamer
>     gboolean bInited;
>     GError* error = NULL;
> #if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
>     bInited = gst_init_check(&argcGST, &argvGST, &error);
> #else
>     bInited = gst_init_check(&argcGST, &argvGST);
> #endif
>
>     // Cleanup arguments for unicode case
> #if wxUSE_UNICODE
>     for ( i = 0; i < argcGST; i++ )
>     {
>         free(argvGST[i]);
>     }
>
>     delete [] argvGST;
> #endif
>
>     if(!bInited)    //gst_init_check fail?
>     {
>         if(error)
>         {
>             wxLogSysError(wxT("Could not initialize GStreamer\n")
>                           wxT("Error Message:%s"),
>                           (const wxChar*) 
> wxConvUTF8.cMB2WX(error->message)
>                          );
>             g_error_free(error);
>         }
>         else
>             wxLogSysError(wxT("Could not initialize GStreamer"));
>
>         return false;
>     }
>
>     //
>     // wxControl creation
>     //
>     m_ctrl = wxStaticCast(ctrl, wxMediaCtrl);
>
> #ifdef __WXGTK__
>     // We handle our own GTK expose events
>     m_ctrl->m_noExpose = true;
> #endif
>
>     if( !m_ctrl->wxControl::Create(parent, id, pos, size,
>                             style,  // TODO: remove borders???
>                             validator, name) )
>     {
>         wxFAIL_MSG(wxT("Could not create wxControl!!!"));
>         return false;
>     }
>
> #ifdef __WXGTK__
>     // Turn off double-buffering so that
>     // so it doesn't draw over the video and cause sporadic
>     // disappearances of the video
>     gtk_widget_set_double_buffered(m_ctrl->m_wxwindow, FALSE);
> #endif
>
>     // don't erase the background of our control window
>     // so that resizing is a bit smoother
>     m_ctrl->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
>         // Ready video.
>
>     printf ("Create Pipeline method starts.\n");
>
> //m_playbin-----------------------------------------------------------
>     // decklinksrc connection = 18 mode=3 !
>     // videoscale  ! ffmpegcolorspace ! videobalance brightness=.3 
> contrast=.8 ! gamma gamma=.5 ! tee name=videoTee
>     // videoTee ! monitorQueue ! xvimagesink sync=false 
> force-aspect-ratio=true
>     // videoTee ! fileQueue ! videorate ! 
> video/x-raw-yuv,framerate=15/1 ! theoraenc quality=63 keyframe-force=1 !
>     // oggmux ! filesink location=video.ogg
>
>     //
>     // Create DeviceCapture object
>     //
>     //GstElement *m_playbin;
>     GstElement *videoSrc, *videoScale, *colorSpace, *videoBalance, 
> *videoGamma, *videoTee;
>     GstElement *monitorQueue, *videoSink;
>     GstElement *fileQueue, *videoRate, *encoder, *muxer, *fileSink;
>     //
>     // Create elements
>     //
>     m_playbin = gst_pipeline_new ("DeviceCapture m_playbin subsitute");
>     if (!m_playbin) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT("'m_playbin' could not be created."));
>         //g_printerr ("'m_playbin' could not be created.\n");
>         return NULL;
>     }
>         videoSrc = gst_element_factory_make ("decklinksrc", "videoSrc");
>     if (!videoSrc) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'videoSrc' could not be created.\n"));
>         return NULL;
>     }
>     videoScale = gst_element_factory_make ("videoscale", "videoScale");
>     if (!videoScale) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'videoScale' could not be created.\n"));
>         return NULL;
>     }
>     colorSpace = gst_element_factory_make ("ffmpegcolorspace", 
> "colorSpace");
>     if (!colorSpace) {
>         g_printerr ("'colorSpace' could not be created.\n");
>         return NULL;
>     }
>     videoBalance = gst_element_factory_make ("videobalance", 
> "videoBalance");
>     if (!videoBalance) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'videoBalance' could not be created.\n"));
>         return NULL;
>     }
>     videoGamma = gst_element_factory_make ("gamma", "videoGamma");
>     if (!videoGamma) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'videoGamma' could not be created.\n"));
>         return NULL;
>     }
>
>     videoTee = gst_element_factory_make ("tee", "videoTee");
>     if (!videoTee) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'videoTee' could not be created.\n"));
>         return NULL;
>     }
>     monitorQueue = gst_element_factory_make ("queue", "monitorQueue");
>     if (!monitorQueue) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'monitorQueue' could not be created.\n"));
>         return NULL;
>     }
>     fileQueue = gst_element_factory_make ("queue", "fileQueue");
>     if (!fileQueue) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'fileQueue' could not be created.\n"));
>         return NULL;
>     }
>     videoRate = gst_element_factory_make ("videorate", "videorate");
>     if (!videoRate) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'videoRate' could not be created.\n"));
>         return NULL;
>     }
>         encoder = gst_element_factory_make ("theoraenc", "videoenc");
>     if (!encoder) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'encoder' could not be created.\n"));
>         return NULL;
>     }
>     muxer = gst_element_factory_make ("oggmux", "muxer");
>     if (!muxer) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'muxer' could not be created.\n"));
>         return NULL;
>     }
>     fileSink = gst_element_factory_make ("filesink", "fileSink");
>     if (!fileSink) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("'fileSink' could not be created.\n"));
>         return NULL;
>     }
>     // Setup video sink - first try gconf, then auto, then xvimage and
>     // then finally plain ximage
>     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;
>                 }
>             }
>         }
>     }
>     // Error reporting
>     if (!m_playbin || !videoSrc || !videoScale || !colorSpace || 
> !videoBalance || !videoGamma || !videoTee || !monitorQueue || 
> !videoSink || !monitorQueue
>         || !fileQueue || !videoRate || !encoder || !muxer|| !fileSink) {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT ("One element could not be created.\n"));
>         return NULL;
>     }
>     // Set paramaters for the GstElements
>     // Video source
>     g_object_set (G_OBJECT (videoSrc), "connection", 3, NULL);
>     // Queue-size default is 2, set to 1 to reduce latency;
>     g_object_set (G_OBJECT (videoSrc), "mode", 18, NULL);
>     // Colour settings for camera
>     g_object_set (G_OBJECT (videoBalance), "brightness", .3, NULL);
>     g_object_set (G_OBJECT (videoBalance), "contrast", .8, NULL);
>     g_object_set (G_OBJECT (videoGamma), "gamma", .5, NULL);
>     // File location
>     g_object_set (G_OBJECT (fileSink), "location", 
> "/home/image/tmp_vid.ogg", NULL); // was .avi
>     // Encoder quality
>     g_object_set (G_OBJECT (encoder), "quality", 63, NULL);
>     // Encoder keyframe rate
>     g_object_set (G_OBJECT (encoder), "keyframe-force", 1, NULL);
>     // videoSink sync=false force-aspect-ratio=true
>     g_object_set (G_OBJECT (videoSink), "sync", false, 
> "force-aspect-ratio", true, NULL);
>     // g_object_set (G_OBJECT (videoSink), "sync", false, NULL);
>         // add elements to pipeline
>     gst_bin_add_many (GST_BIN (m_playbin),
>     videoSrc, videoScale, colorSpace, videoTee,
>     monitorQueue, videoSink,
>     fileQueue, videoRate, videoBalance, videoGamma, encoder, muxer, 
> fileSink, NULL);
>         // link elements.
>     if (!gst_element_link_many( videoSrc, videoScale, colorSpace, 
> videoBalance, videoGamma, videoTee, NULL )) {
>         g_warning ("Failed to link videoScale, colorSpace, 
> videoBalance, videoGamma and videoTee.");
>     }
>     if (!gst_element_link_many( videoTee, monitorQueue, videoSink, 
> NULL )) {
>         g_warning ("Failed to link videoTee, monitorQueue and 
> videoSink.");
>     }
>     if (!gst_element_link_many( videoTee, fileQueue, videoRate, NULL )) {
>         g_warning ("Failed to link videoTee, fileQueue and videoRate.");
>     }
>     // Create caps stuff
>     GstCaps *caps;
>     m_videoFps = 15;
>     caps = gst_caps_new_simple ("video/x-raw-yuv",
>         "framerate", GST_TYPE_FRACTION, 15, 1,
>         NULL);
>     if (!gst_element_link_filtered (videoRate, encoder, caps)) {
>         g_warning ("Failed to link videoRate and encoder.");
>     }
>     gst_caps_unref (caps);
>         if (!gst_element_link_many( encoder, muxer, fileSink, NULL )) {
>         g_warning ("Failed to link encoder, muxer and fileSink.");
>     }
>     if (!GST_IS_ELEMENT(m_playbin))
>     {
>         if(G_IS_OBJECT(m_playbin))
>             g_object_unref(m_playbin);
>         wxLogSysError(wxT("Got an invalid bin"));
>         return false;
>     }
>
>     // Set playbin to ready
>     if( gst_element_set_state (m_playbin, GST_STATE_READY) ==
>         GST_STATE_FAILURE || !SyncStateChange(m_playbin, 
> GST_STATE_READY))
>     {
>         wxLogSysError(wxT("wxGStreamerMediaBackend::DeviceCapture - ")
>                     wxT("Could not set initial state to paused"));
>         return false;
>     }
>
>     printf ("Playbin set.\n");
>
> #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
>     // Connect the glib events/callbacks we want to our playbin
>     g_signal_connect(m_playbin, "eos",
>                      G_CALLBACK(gst_finish_callback), this);
>     g_signal_connect(m_playbin, "error",
>                      G_CALLBACK(gst_error_callback), this);
>     g_signal_connect(m_playbin, "state-change",
>                      G_CALLBACK(gst_state_change_callback), this);
> #else
>
>     // GStreamer 0.10+ uses GstBus for this now, connect to the sync
>     // handler as well so we can set the X window id of our xoverlay
>     gst_bus_add_watch (gst_element_get_bus(m_playbin),
>                        (GstBusFunc) gst_bus_async_callback, this);
>     gst_bus_set_sync_handler(gst_element_get_bus(m_playbin),
>                              (GstBusSyncHandler) 
> gst_bus_sync_callback, this);
>     g_signal_connect(m_playbin, "notify::stream-info",
>                      G_CALLBACK(gst_notify_stream_info_callback), this);
> #endif
>
> #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
>     // Not on 0.10... called when video size changes
>     g_signal_connect(m_xoverlay, "desired-size-changed",
> G_CALLBACK(gst_desired_size_changed_callback), this);
> #endif
>     // Tell GStreamer which window to draw to in 0.8 - 0.10
>     // sometimes needs this too...
>     SetupXOverlay();
>     printf ("Control created.\n");
>
>     m_eventHandler = new wxGStreamerMediaEventHandler(this);
>     return true;
> }
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>



More information about the gstreamer-devel mailing list