[Bug 677708] Shared Gst.Buffers make .Dispose() unusable

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Tue May 31 09:16:30 UTC 2016


https://bugzilla.gnome.org/show_bug.cgi?id=677708

blad <camera.geomatics at leica-geosystems.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |camera.geomatics at leica-geos
                   |                            |ystems.com

--- Comment #2 from blad <camera.geomatics at leica-geosystems.com> ---
I can confirm the problem using 1.x based bindings.

Reproducable with:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Gst;
using System.Runtime.InteropServices;

namespace AppSinkSample
{
    class Program
    {
        static Element VideoTestSource, VideoCaps, VideoSink, AppQueue;
        static Gst.App.AppSink AppSink;

        static GLib.MainLoop MainLoop; // GLib's Main Loop

        // The appsink has received a buffer
        static void NewSample(object sender, GLib.SignalArgs args)
        {
            var sink = (Gst.App.AppSink)sender;

            // Retrieve the buffer
            var sample = sink.PullSample();
            if (sample != null)
            {
                // The only thing we do in this example is print a * to
indicate a received buffer
                Console.Write("*");
                sample.Dispose();
            }
        }

        static void Main(string[] args)
        {
            // Initialize Gstreamer
            Gst.Application.Init(ref args);

            // Create the elements
            VideoTestSource = ElementFactory.Make("videotestsrc",
"videotestsrc0");
            VideoCaps = ElementFactory.Make("capsfilter", "capsfilter0");
            AppQueue = ElementFactory.Make("queue", "app_queue");
            AppSink = new Gst.App.AppSink("app_sink");

            // Create the empty pipeline
            var pipeline = new Pipeline("test-pipeline");

            if (VideoTestSource == null || VideoCaps == null || AppQueue ==
null || AppSink == null)
            {
                return;
            }

            // Configure videotestsrc
            VideoTestSource["pattern"] = "snow";
            VideoCaps["caps"] =
Gst.Caps.FromString("video/x-raw,width=640,height=480");

            // Configure appsink
            AppSink["emit-signals"] = true;
            AppSink.NewSample += NewSample;

            pipeline.Add(VideoTestSource, VideoCaps, AppQueue, AppSink);

            if (!Element.Link(VideoTestSource, VideoCaps) ||
!Element.Link(VideoCaps, AppQueue) || !Element.Link(AppQueue, AppSink))
            {
                return;
            }

            // Start playing the pipeline
            pipeline.SetState(State.Playing);

            // Create a GLib Main Loop and set it to run
            MainLoop = new GLib.MainLoop();
            MainLoop.Run();

            // Free resources
            pipeline.SetState(State.Playing);

        }
    }
}

Workaround is using native functions for appsink:


        [DllImport("libgstreamer-1.0-0.dll", CallingConvention =
CallingConvention.Cdecl)]
        static extern void gst_mini_object_unref(IntPtr raw);

        [DllImport("libgstapp-1.0-0.dll", CallingConvention =
CallingConvention.Cdecl)]
        static extern IntPtr gst_app_sink_pull_sample(IntPtr raw);

        [DllImport("libgstreamer-1.0-0.dll", CallingConvention =
CallingConvention.Cdecl)]
        static extern bool gst_buffer_map(IntPtr raw, IntPtr info, int flags);

        [DllImport("libgstreamer-1.0-0.dll", CallingConvention =
CallingConvention.Cdecl)]
        static extern void gst_buffer_unmap(IntPtr raw, IntPtr info);

        [DllImport("libgstreamer-1.0-0.dll", CallingConvention =
CallingConvention.Cdecl)]
        static extern IntPtr gst_sample_get_buffer(IntPtr raw);

        [DllImport("libgstreamer-1.0-0.dll", CallingConvention =
CallingConvention.Cdecl)]
        static extern IntPtr gst_sample_get_caps(IntPtr raw);


        private void GetSinkSampleImageAppSink(object sender, GLib.SignalArgs
args)
        {
            var sink = (Gst.App.AppSink)sender;

            IntPtr sampleNativePtr = gst_app_sink_pull_sample(sink.Handle);

            if (sampleNativePtr != null)
            {
                IntPtr capsNativePtr = gst_sample_get_caps(sampleNativePtr);

                Gst.Caps caps = capsNativePtr == IntPtr.Zero ? null :
(Gst.Caps)GLib.Opaque.GetOpaque(capsNativePtr, typeof(Gst.Caps), false);

                var wVal = caps[0].GetValue("width");
                var hVal = caps[0].GetValue("height");

                var height = (int)hVal.Val;
                var width = (int)wVal.Val;

                IntPtr bufferNativePtr =
gst_sample_get_buffer(sampleNativePtr);

                IntPtr mapInfoNativePtr =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Gst.MapInfo)));
                gst_buffer_map(bufferNativePtr, mapInfoNativePtr,
(int)MapFlags.Read);
                Gst.MapInfo mapInfo = Gst.MapInfo.New(mapInfoNativePtr);

                Bitmap bitmapSample = new Bitmap(width, height, width * 3,
PixelFormat.Format24bppRgb, mapInfo.DataPtr);

                gst_buffer_unmap(bufferNativePtr, mapInfoNativePtr);
                gst_mini_object_unref(sampleNativePtr);
            }
        }

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list