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