<div dir="ltr"><br><div class="gmail_extra"><div class="gmail_quote">On Wed, May 21, 2014 at 10:17 AM, Andrew Spielvogel <span dir="ltr"><<a href="mailto:andrews@harvestai.com" target="_blank">andrews@harvestai.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>Hi,<br><br>I am new to writing plugins and am trying to write a source for an IDS camera.  After looking around, it seems that I should use GstBaseSrc::start to start the camera and GstBaseSrc::stop to stop the camera.  What should I use to retrieve a frame from the camera and push the the frame to the source? GstBaseSrc::create?  Does anyone have any advice or examples for how to write a source?<br>
</div></div></div></blockquote><div><br></div><div>I suggest reading the source of a similar element to the one you're trying to create, in order to help figure out what you have to do. In your case, I'd probably end up reading the sources for GstBaseSrc, GstPushSrc and GstV4L2Src, as its often difficult to understand what an element is doing without an understanding of what its parent elements are all about.<br>
<br></div><div>I don't know if it will help at all, but I'm going to attach my notes about my understanding of GstBaseSrc and GstPushSrc from when I recently had to write a new push element. Naturally these are just my best guesses and may very well contain errors:<br>
<br></div><div><span style="font-family:courier new,monospace">--- START ---<br></span></div><div><span style="font-family:courier new,monospace"><br>Notes on using GstPushSrc<br>-------------------------<br><br>GstPushSrc has 4 virtual functions: 'create', 'alloc', 'fill' and 'query'. The<br>
default for 'create' is to call 'alloc' to allocate a buffer and 'fill' to<br>fill it with data. I'm going to override alloc (because the default fails to<br>allocate buffers of the size I need) and fill, because you HAVE to, as it<br>
actually fills the buffer with a frame of data. 'query' intercepts any<br>incoming QUERY events to the element, but for now we're happy with the default<br>handling of those events.<br><br>In general we want to override the most-derived routines that we can in order<br>
to do our work, leaving as much processing as possible to the default element<br>code. Thus we override the alloc and fill routines in the GstPushSrcClass,<br>while overriding other elements in the parent GstBaseSrcClass, as needed.<br>
<br>GstPushSrc is a subclass of GstBaseSrc<br><br>GstBaseSrcClass has a large number of virtual functions, and I've yet to<br>figure out what most of them are actually for (the documentation leaves much<br>to be desired.) As far as I can tell, we need to override several, but the<br>
list keeps changing as I find out new things about the model of how an element<br>works (something else that should be explicitly documented somewhere, but<br>isn't). This is my current best guess at what is what.<br>
<br>GstBaseSrc Virtual Methods:<br><br>* get_caps - get caps from subclass<br><br>get_caps is called by BaseSrc in response to receiving a GST_QUERY_CAPS. The<br>result we return is again returned as the result of the query. We start with<br>
the basic CAPS from our source pad template, and then fixate any fields that<br>the user has requested specific values for.<br><br>* negotiate - decide on caps<br><br>This routine implements standard caps negotiations. Since we don't have any<br>
special caps that need taking care of, we went with the default implementation.<br><br>* fixate - called if, in negotiation, caps need fixating<br><br>fixate is called if the pipeline has agreed on a common set of caps, but it<br>
still has ranges and options in it. Our job is to set each range and option to<br>our preferred value, so the caps are fixed, and return the result. Note that<br>by this point any user preferred settings have already been negotiated so all<br>
we have left to do is set values to our defaults.<br><br>* set_caps - notify the subclass of new caps<br><br>set_caps is called by BaseSrc after negotiation has arrived at fixed<br>caps. These negotiated caps need to be acknowledged and remembered. I believe<br>
we return true if we are able to accept an end to negotiation at this time, or<br>false if later negotiation will be required.<br><br>NOTE: We would only ever return false if we had been negotiating with<br>preliminary caps because we're waiting for information from a source device<br>
in order to provide our final caps, and we hadn't yet done that. Since we<br>have no source device to talk to, this never happens in our case.<br><br>* decide_allocation - setup allocation query<br><br>I believe this routine negotiates which allocation system and/or buffer pool<br>
is going to be used as the source of buffers for this element. Not knowing<br>anything about how this works, I'm just using the default.<br><br>* start - start processing<br>* stop  - stop processing<br><br>These methods are called to mark the start and end of frame output from the<br>
source. 'start' usually does such tasks as opening devices for reading, and<br>resetting the clock, while 'stop' does such tasks as cleaning up after 'start'<br>(such as closing devices and freeing data structures allocated by 'start'.)<br>
<br>* get_times - return start and stop times when a buffer should be pushed.<br><br>This is a very confusing method as its description here would suggest that its<br>job is to simply generate the correct timestamp and duration for the current<br>
buffer and return them, but every example in the source I can find does<br>something far more complex. Often, implementations of this routine read these<br>values out of the very buffer they are supposed to be setting values for...<br>
<br>For now we just naively generate a buffer duration equal to the reciprocal of<br>the frame rate, and generate each new timestamp by adding that duration to the<br>last timestamp. This *seems* to work.<br><br>* get_size - get the total size of the resource in bytes<br>
<br>This routine is supposed to return the size, in the set GstFormat for the <br>source, of the entire source output. I'm assuming this routine is never<br>actually called for live sources, so I've just left it at the default.<br>
<br>* is_seekable - check if the resource is seekable<br><br>Simply returns TRUE or FALSE depending on if the source is random access or not.<br><br>* prepare_seek_segment - Prepare to perform do_seek(), using current GstFormat.<br>
<br>Not entirely sure what this does, but as I'm not implementing a seekable<br>source, I left this as its default.<br><br>* do_seek - notify subclasses of a seek<br><br>I think this actually does a seek in the source stream, but as I am not<br>
implementing a seekable source, I've left this at the default.<br><br>* unlock - unlock any pending access to the resource<br><br>Text for this method says "subclasses should unlock any function ASAP". Not<br>
really clear what is required, but as I lock access to my frame source during<br>a fairly lengthy rendering process, I interpreted calls on this method to mean<br>I should abort the rendering and unlock the source.<br><br>
* unlock_stop - Clear any pending unlock request, as we succeeded in unlocking<br><br>Again, not really sure what this is all about, as it seems to imply that it<br>may NOT be necessary to actually unlock when asked to unlock. In any case, we<br>
currently leave this method at its default. Once you ask us to unlock, we<br>unlock.<br><br>* query - notify subclasses of a query<br><br>This method allows the subclass to override the standard handling of one or<br>more types of incoming queries. We're happy with the default query handling,<br>
so we left this alone.<br><br>* event - notify subclasses of an event<br><br>This method allows the subclass to override the standard handling of one or<br>more types of event. In our case we are happy with everything but navigation<br>
events, which we have to handle ourselves. So we check for navigation events<br>here and handle them if so (returning TRUE to say its taken care of). For<br>other events we just call into our superclass's event method and return<br>
whatever it returns. ie:<br><br>    if( GST_EVENT_TYPE(event) != GST_EVENT_NAVIGATION )<br>      return GST_BASE_SRC_CLASS(gst_mysrc_parent_class)->event(base,event);<br><br>* create - ask the subclass to create a buffer with offset and size.<br>
<br>The default implementation of this method will call the alloc and fill methods<br>listed below, so typically one either overrides this method, or overrides one<br>or both of alloc and fill, but not all three.<br><br>* alloc - ask the subclass to allocate an empty output buffer. <br>
<br>The default implementation will use the negotiated allocator, however I found<br>that it was allocating *empty* buffers that I couldn't store frames in. No<br>idea why. In the end I overrode this routine with one that checks for a custom<br>
buffer pool or custom allocator and uses them if found. It allocates empty<br>buffers of the correct size for storing video frames in the current format. I<br>made extensive use of the gst_video_ routines to manage this.<br>
<br>* fill - ask the subclass to fill the buffer with data from offset and size<br><br>As I'm implementing a live source, the offset and size parameters are to be<br>ignored, and I simply render the next frame of video output into the given<br>
buffer.<br><br></span></div><div><span style="font-family:courier new,monospace">--- END ---<br></span></div><div><span style="font-family:courier new,monospace"><br></span></div></div><span style="font-family:courier new,monospace"><br clear="all">
<br>-- <br>Stirling Westrup<br>Programmer, Entrepreneur.<br><a href="https://www.linkedin.com/e/fpf/77228" target="_blank">https://www.linkedin.com/e/fpf/77228</a><br><a href="http://www.linkedin.com/in/swestrup" target="_blank">http://www.linkedin.com/in/swestrup</a><br>
<a href="http://technaut.livejournal.com" target="_blank">http://technaut.livejournal.com</a><br></span><a href="http://sourceforge.net/users/stirlingwestrup" target="_blank">http://sourceforge.net/users/stirlingwestrup</a>
</div></div>