Hi Gstreamer Guys, Is there a way to specify the start absolute timestamp which has to be overlay while playing video from file. I already did take a look with ClockOverlay, TimeOverlay and TextOverlay, but this doesn’t allow me start date time to use, or I missed something I presume that this can be done somehow via a probe and add the date time on every frame while recording or playing the video. But I presume that there are more easier ways to establish this. Thanks for any tips. _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
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 [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
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 <[hidden email]>: You could do it with custom element if you are up for it. I'm timestamping _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |