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