Gstreamer dev : custom source based on basesrc

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Gstreamer dev : custom source based on basesrc

Duchassin Frederic
Hello,


I try to make my own gstreamer source which take MPEG2-TS from Pcie.

I start from a template based on basesrc in order to create my source.

But now i have to understand the memory / buffer allocation in my source
code. I can't find any good example on the web...

Somebody can explain me the basic of these 3 function (example if
possible too) :


/* ask the subclass to create a buffer with offset and size, the default
  * implementation will call alloc and fill. */
static GstFlowReturn
gst_pciesrc_create (GstBaseSrc * src, guint64 offset, guint size,
     GstBuffer ** buf)
{
   GstPciesrc *pciesrc = GST_PCIESRC (src);

   GST_DEBUG_OBJECT (pciesrc, "create");

   return GST_FLOW_OK;
}

/* ask the subclass to allocate an output buffer. The default implementation
  * will use the negotiated allocator. */
static GstFlowReturn
gst_pciesrc_alloc (GstBaseSrc * src, guint64 offset, guint size,
     GstBuffer ** buf)
{
   GstPciesrc *pciesrc = GST_PCIESRC (src);

   GST_DEBUG_OBJECT (pciesrc, "alloc");

   return GST_FLOW_OK;
}

/* ask the subclass to fill the buffer with data from offset and size */
static GstFlowReturn
gst_pciesrc_fill (GstBaseSrc * src, guint64 offset, guint size,
GstBuffer * buf)
{
   GstPciesrc *pciesrc = GST_PCIESRC (src);

   GST_DEBUG_OBJECT (pciesrc, "fill");

   return GST_FLOW_OK;
}


Many thanks in advance.


Frederic

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Gstreamer dev : custom source based on basesrc

Edgar Thier
Hi,

Gstreamer Buffer management consists out of multiple parts:

- The GstBufferPool - It contains all buffers that will be used by your src. Unless you have a good
  reason to implement it, use the default implementation, like you already are.
- The single GstBuffer - consisting out of MetaData, timestamps and a pointer to GstMemory,
  aka you actual image.
- Your image buffer - This can be allocated be gstreamer or externally, depending on your setup.
  Most sources i have seen (usb/firewire/network) allocate buffers in their backend and give
  a pointer to the buffer to gstreamer.

As is documented
(https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstPushSrc.html)
default sources will call create, which implicitly calls alloc and then fill.
That means you do not have to overwrite all functions.
By overwriting create the default implementations for alloc/fill will not be called.
You will have to call them manually or implement their functionality in create itself.

Depending on your setup you can call `gst_buffer_new_wrapped_full` for your existing buffer.
This will use the GstBuffer from the GstBufferPool that you receive in create and use
the image pointer you provide for the pipeline.

Examples for this would be:

https://github.com/AravisProject/aravis/blob/master/gst/gstaravis.c#L351

https://github.com/TheImagingSource/tiscamera/blob/master/src/gstreamer-1.0/gsttcamsrc.cpp#L1351

Both execute extra steps that can be ignored. And both allocate their image buffer externally in
their backends.

The other way would be to have gstreamer allocate a buffer for you by calling alloc,
filling that buffer with an image and delivering that. I have not worked with this method as of yet,
so I cannot offer you details or examples.

If I got any details wrong, please feel free to correct me.

-Edgar

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Gstreamer dev : custom source based on basesrc

Duchassin Frederic
Hi,


Thanks for your good answer.

If I well understand, i just keep the "fill" function like that:

/* ask the subclass to fill the buffer with data from offset and size */
static GstFlowReturn
gst_pciesrc_fill (GstBaseSrc * src, guint64 offset, guint size,
GstBuffer * buf)
{
   GstPciesrc *pciesrc = GST_PCIESRC (src);

   GST_DEBUG_OBJECT (pciesrc, "fill");

   if(fd != -1)
   {
       GstMapInfo info;

     //Read the global device
     gst_buffer_map (buf, &info, GST_MAP_WRITE);

     int rc = read(fd, info.data, info.size);

     gst_buffer_unmap (buf, &info);

     GST_DEBUG_OBJECT (pciesrc, "info.size = %d", info.size);
     GST_DEBUG_OBJECT (pciesrc, "rc = %d", rc);
   }

   return GST_FLOW_OK;
}


But i get many errors :

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_mini_object_ref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_caps_can_intersect:
assertion 'GST_IS_CAPS (caps2)' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_mini_object_unref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_mini_object_ref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_pad_template_new:
assertion 'caps != NULL' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_mini_object_unref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **:
gst_element_request_compatible_pad: assertion 'GST_IS_PAD_TEMPLATE
(templ)' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_object_unref:
assertion 'object != NULL' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_mini_object_ref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_caps_can_intersect:
assertion 'GST_IS_CAPS (caps1)' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_mini_object_unref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3616): GStreamer-CRITICAL **: gst_mini_object_ref:
assertion 'mini_object != NULL' failed
WARNING: erroneous pipeline: could not link pciesrc0 to d
root@cl-som-imx8:~# export GST_DEBUG=pciesrc*:5
root@cl-som-imx8:~# gst-launch-1.0 pciesrc ! decodebin name=d d. ! queue
! kmssink d. ! queue ! audioconvert ! alsasink
0:00:00.101927543  3618       0x674ca0 DEBUG pciesrc
gstpciesrc.c:409:gst_pciesrc_query:<pciesrc0> query

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_mini_object_ref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_caps_can_intersect:
assertion 'GST_IS_CAPS (caps2)' failed

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_mini_object_unref:
assertion 'mini_object != NULL' failed
0:00:00.103476261  3618       0x674ca0 DEBUG pciesrc
gstpciesrc.c:409:gst_pciesrc_query:<pciesrc0> query

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_mini_object_ref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_pad_template_new:
assertion 'caps != NULL' failed

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_mini_object_unref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3618): GStreamer-CRITICAL **:
gst_element_request_compatible_pad: assertion 'GST_IS_PAD_TEMPLATE
(templ)' failed

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_object_unref:
assertion 'object != NULL' failed
0:00:00.103686021  3618       0x674ca0 DEBUG pciesrc
gstpciesrc.c:409:gst_pciesrc_query:<pciesrc0> query

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_mini_object_ref:
assertion 'mini_object != NULL' failed

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_caps_can_intersect:
assertion 'GST_IS_CAPS (caps1)' failed

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_mini_object_unref:
assertion 'mini_object != NULL' failed
0:00:00.103875861  3618       0x674ca0 DEBUG pciesrc
gstpciesrc.c:409:gst_pciesrc_query:<pciesrc0> query

(gst-launch-1.0:3618): GStreamer-CRITICAL **: gst_mini_object_ref:
assertion 'mini_object != NULL' failed
WARNING: erroneous pipeline: could not link pciesrc0 to d
root@cl-som-imx8:~#

BR


Frédéric




Le 22/01/2019 à 11:01, Edgar Thier a écrit :

> Hi,
>
> Gstreamer Buffer management consists out of multiple parts:
>
> - The GstBufferPool - It contains all buffers that will be used by your src. Unless you have a good
>    reason to implement it, use the default implementation, like you already are.
> - The single GstBuffer - consisting out of MetaData, timestamps and a pointer to GstMemory,
>    aka you actual image.
> - Your image buffer - This can be allocated be gstreamer or externally, depending on your setup.
>    Most sources i have seen (usb/firewire/network) allocate buffers in their backend and give
>    a pointer to the buffer to gstreamer.
>
> As is documented
> (https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstPushSrc.html)
> default sources will call create, which implicitly calls alloc and then fill.
> That means you do not have to overwrite all functions.
> By overwriting create the default implementations for alloc/fill will not be called.
> You will have to call them manually or implement their functionality in create itself.
>
> Depending on your setup you can call `gst_buffer_new_wrapped_full` for your existing buffer.
> This will use the GstBuffer from the GstBufferPool that you receive in create and use
> the image pointer you provide for the pipeline.
>
> Examples for this would be:
>
> https://github.com/AravisProject/aravis/blob/master/gst/gstaravis.c#L351
>
> https://github.com/TheImagingSource/tiscamera/blob/master/src/gstreamer-1.0/gsttcamsrc.cpp#L1351
>
> Both execute extra steps that can be ignored. And both allocate their image buffer externally in
> their backends.
>
> The other way would be to have gstreamer allocate a buffer for you by calling alloc,
> filling that buffer with an image and delivering that. I have not worked with this method as of yet,
> so I cannot offer you details or examples.
>
> If I got any details wrong, please feel free to correct me.
>
> -Edgar
>
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Gstreamer dev : custom source based on basesrc

Geek-Gst
Duchassin,

This asserts are due to padtemplate. Check your stats pad registry once.

Some corrections in gst_pciesrc_fill. Specify what is the size to be read
from read() and in the end set the buffer size.

gst_pciesrc_fill (GstBaseSrc * src, guint64 offset, guint size,
GstBuffer * buf)
{
   GstPciesrc *pciesrc = GST_PCIESRC (src);

   GST_DEBUG_OBJECT (pciesrc, "fill");

   if(fd != -1)
   {
       GstMapInfo info;

     //Read the global device
     gst_buffer_map (buf, &info, GST_MAP_WRITE);
     info.size = size;
     int rc = read(fd, info.data, info.size);

     gst_buffer_unmap (buf, &info);
     gst_buffer_resize (buf, 0, size);
     GST_DEBUG_OBJECT (pciesrc, "info.size = %d", info.size);
     GST_DEBUG_OBJECT (pciesrc, "rc = %d", rc);
   }

   return GST_FLOW_OK;
}




--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Gstreamer dev : custom source based on basesrc

Duchassin Frederic
Hello,


It's strange...

The fill function should give me in parameter the size of the buffer
mapped, isn't ?

so info-> size should always equal size (parameter).

 From my size, it's possible that there no enough data in device.

So correct me if I'm wrong but the fill would be :


gst_pciesrc_fill (GstBaseSrc * src, guint64 offset, guint size,
GstBuffer * buf)
{
    GstPciesrc *pciesrc = GST_PCIESRC (src);

    GST_DEBUG_OBJECT (pciesrc, "fill");

    if(fd != -1)
    {
        GstMapInfo info;

      //Read the global device
      gst_buffer_map (buf, &info, GST_MAP_WRITE);

      int rc = read(fd, info.data, info.size);

      gst_buffer_unmap (buf, &info);
      gst_buffer_resize (buf, 0, rc);
    }

    return GST_FLOW_OK;
}

BR


Frédéric




Le 23/01/2019 à 07:05, Geek-Gst a écrit :

> Duchassin,
>
> This asserts are due to padtemplate. Check your stats pad registry once.
>
> Some corrections in gst_pciesrc_fill. Specify what is the size to be read
> from read() and in the end set the buffer size.
>
> gst_pciesrc_fill (GstBaseSrc * src, guint64 offset, guint size,
> GstBuffer * buf)
> {
>     GstPciesrc *pciesrc = GST_PCIESRC (src);
>
>     GST_DEBUG_OBJECT (pciesrc, "fill");
>
>     if(fd != -1)
>     {
>         GstMapInfo info;
>
>       //Read the global device
>       gst_buffer_map (buf, &info, GST_MAP_WRITE);
>       info.size = size;
>       int rc = read(fd, info.data, info.size);
>
>       gst_buffer_unmap (buf, &info);
>       gst_buffer_resize (buf, 0, size);
>       GST_DEBUG_OBJECT (pciesrc, "info.size = %d", info.size);
>       GST_DEBUG_OBJECT (pciesrc, "rc = %d", rc);
>     }
>
>     return GST_FLOW_OK;
> }
>
>
>
>
> --
> Sent from: http://gstreamer-devel.966125.n4.nabble.com/
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel