<div dir="ltr"><div dir="ltr"><div>Hi,</div><div><br></div><div>Thanks for the info. </div><div></div><div>Seems not easy at first glance, but I'm certain going to try this.</div><div><br></div><div><br></div><div><br></div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><br></div></div></div><br><div class="gmail_quote"><div class="gmail_attr" dir="ltr">Op di 4 feb. 2020 om 00:43 schreef jackBuffington <<a href="mailto:jbuffington@redzone.com">jbuffington@redzone.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">You could do it with custom element if you are up for it.  I'm timestamping<br>
my video using a custom element but am doing it with binary code as small as<br>
possible so that I can do machine vision stuff later.  In short I am working<br>
off of the GstBaseTransform template provide by:<br>
<a href="https://gstreamer.mazdermind.de/" target="_blank" rel="noreferrer">https://gstreamer.mazdermind.de/</a><br>
<br>
I've implemented a transform function rather than a transform_ip function. <br>
I think that it should be possible to use transform_ip but I couldn't get it<br>
to work.    I've attached some code.  It doesn't do exactly what you want<br>
but should be a good starting point.  <br>
<br>
<br>
<br>
<br>
// Here is where the input buffer is manipulated and copied to the output<br>
buffer(s) <br>
static GstFlowReturn gst_lfselement_transform (GstBaseTransform *trans,<br>
GstBuffer *inbuf, GstBuffer *outbuf)<br>
{<br>
<br>
        GstMapInfo inMap, outMap;<br>
        guint8 *dest;<br>
        guint8 *src;<br>
        static int frameCount = 0;<br>
        static int lastSeconds = 0;<br>
<br>
        gsize maxsize;<br>
        gsize inSize = gst_buffer_get_sizes (inbuf, NULL , &maxsize);<br>
        //~ g_print ( " In buf: \n " );<br>
        //~ g_print ( " In size:%lu " G_GSIZE_FORMAT " \n " , inSize);<br>
        //~ g_print ( " In maxsize:%lu " G_GSIZE_FORMAT " \n " , maxsize);<br>
        //~ g_print ( " In number of buffers: %u \n " , gst_buffer_n_memory<br>
(inbuf));<br>
<br>
<br>
        //~ gsize outSize = gst_buffer_get_sizes (outbuf, NULL , &maxsize);<br>
        //~ g_print ( " Out buf: \n " );<br>
        //~ g_print ( " Out size:%lu " G_GSIZE_FORMAT " \n " , outSize);<br>
        //~ g_print ( " Out maxsize:%lu " G_GSIZE_FORMAT " \n " , maxsize);<br>
        //~ g_print ( " Out number of buffers: %u \n " , gst_buffer_n_memory<br>
(outbuf));<br>
<br>
<br>
<br>
        // map the input buffer <br>
        if (!gst_buffer_map (inbuf, &inMap, GST_MAP_READ))<br>
        {<br>
                GST_WARNING_OBJECT (trans, "Could not map input buffer, skipping");<br>
                return GST_FLOW_OK;<br>
        }<br>
<br>
        // map the output buffer<br>
        if (!gst_buffer_map (outbuf, &outMap, GST_MAP_WRITE)) <br>
        {<br>
                gst_buffer_unmap (inbuf, &inMap);<br>
                GST_WARNING_OBJECT (trans, "Could not map output buffer, skipping");<br>
                return GST_FLOW_OK;<br>
        }<br>
<br>
        dest = outMap.data;<br>
        src = inMap.data;<br>
<br>
<br>
        // Here's the do-nothing part.  It simply copies the buffer.<br>
        copyBuffer(src, dest, inSize);<br>
<br>
<br>
<br>
        // Here is the do-something part.  <br>
        GstLfselement *lfselement = GST_LFSELEMENT (trans);<br>
<br>
<br>
        // encode some data onto the bottom of the screen.<br>
        time_t now = time(NULL);<br>
        struct tm currentTime = *localtime(&now);<br>
<br>
        struct timeval curTime;<br>
        gettimeofday(&curTime, NULL);<br>
        int milli = curTime.tv_usec / 1000;<br>
        uint8_t milliHigh = milli / 256;<br>
        uint8_t milliLow = milli % 256;<br>
<br>
        uint8_t timeStamp[5] = {currentTime.tm_hour, currentTime.tm_min,<br>
currentTime.tm_sec, milliHigh, milliLow};<br>
        encodeData(dest, 0, 478, lfselement->outInfo.width, timeStamp, 5);<br>
<br>
<br>
        // Tidy up<br>
        gst_buffer_unmap (outbuf, &outMap);<br>
        gst_buffer_unmap (inbuf, &inMap);<br>
        return GST_FLOW_OK;<br>
<br>
}<br>
<br>
<br>
<br>
static void copyBuffer(guint8 *inBuffer, guint8 *outBuffer, int bufferSize)<br>
{   <br>
  // Copies each byte from the input buffer into the output buffer <br>
  // TODO:  This could probably be faster by using 64-bit variables.  <br>
<br>
  guint8 *inPtr = (guint8*) inBuffer;<br>
  guint8 *inEnd = inPtr + (bufferSize);<br>
<br>
  do<br>
  {<br>
    *outBuffer++ = *inPtr++; <br>
  }<br>
  while (inPtr < inEnd - 1);<br>
}<br>
<br>
<br>
<br>
<br>
static void inline setPixel(guint8 *buffer, int X, int Y, int value, int<br>
width)<br>
{       /* Sets the pixel at that location to the given value <br>
        X and Y are the location of the pixel that I want to set. <br>
        width and height are the dimensions of the image.<br>
<br>
        UYVY data is formatted in groups of two pixels per UYVY grouping. <br>
        Think of it like this U (Y1) V (Y2)  where<br>
        Pixel 1 is Y1, U, V<br>
        Pixel 2 is Y2, U, V<br>
        U and V are sampled on every other column but are sampled on every row.<br>
<br>
        ### IT IS UP TO THE USER TO NOT SPECIFY A PIXEL LOCATION OUTSIDE OF     ###<br>
        ### THE BOUNDS OF THE BUFFER!                                                                                                   ###<br>
        */<br>
<br>
        // Calculate the location in the buffer where the pixel should be set<br>
        int rowOffset = Y * width * 2;<br>
        int blockOffset = (X/2) * 2;<br>
        int whichY = X % 2; // this is which Y in the block that this corresponds<br>
to<br>
<br>
        int offset = rowOffset + blockOffset; // this is the location of the<br>
beginning of the UYVY block<br>
<br>
        buffer += offset;<br>
        *buffer = 128;                  // U<br>
        *(buffer + 2) = 128;   // Y<br>
        if(whichY)<br>
                *(buffer + 3) = value;<br>
        else<br>
                *(buffer + 1) = value;<br>
}<br>
<br>
<br>
<br>
--<br>
Sent from: <a href="http://gstreamer-devel.966125.n4.nabble.com/" target="_blank" rel="noreferrer">http://gstreamer-devel.966125.n4.nabble.com/</a><br>
_______________________________________________<br>
gstreamer-devel mailing list<br>
<a href="mailto:gstreamer-devel@lists.freedesktop.org" target="_blank">gstreamer-devel@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel" target="_blank" rel="noreferrer">https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel</a><br>
</blockquote></div>