'How should I interpret the gstreamer multifilesink timestamp property?
I am using a multifilesink element in C. multifilesink creates file names with an index, but I need file names with a timestamp. Conveniently, multifilesink sends a bus message after every file is written, and in the message data, it supplies a glib structure containing the file name and a timestamp. I have set up code to watch for the message and call a function to rename each file like this:
"file-01.jpg" becomes "file-DDMMYYYY_HHMMSS.sss.jpg"
I can successfully receive the message and call my function every time a file is written.
The problem is that I do not understand the value of the timestamp. It does not appear to be a unix epoch time, it is not monotonic, and often, the value is negative or zero.
// My function to handle multifilesink messages
static gboolean HandleElementMessages( GstMessage *MessagePtr )
{
const GstStructure* MessageStructurePtr;
gboolean success = TRUE;
MessageStructurePtr = gst_message_get_structure( MessagePtr );
g_print( "Received an element message from an element of type \"%s\" at time %ld\n",
gst_structure_get_name( MessageStructurePtr ),
GST_MESSAGE_TIMESTAMP( MessageStructurePtr )
);
return success;
} // End of HandleElementMessages()
I expect that GST_MESSAGE_TIMESTAMP() should return a monotonically increasing value that is related to the epoch or some starting point that I can understand. Instead, I see results like this:
Received an element message from an element of type "GstMultiFileSink" at time 3282
Received an element message from an element of type "GstMultiFileSink" at time 0
Received an element message from an element of type "GstMultiFileSink" at time 2
Received an element message from an element of type "GstMultiFileSink" at time 0
Received an element message from an element of type "GstMultiFileSink" at time 0
Received an element message from an element of type "GstMultiFileSink" at time 140662536522192
Received an element message from an element of type "GstMultiFileSink" at time -3543839906708188932
...
Solution 1:[1]
Here is the code what structure is being send to the bus:
s = gst_structure_new ("GstMultiFileSink",
"filename", G_TYPE_STRING, filename,
"index", G_TYPE_INT, multifilesink->index,
"timestamp", G_TYPE_UINT64, timestamp,
"stream-time", G_TYPE_UINT64, stream_time,
"running-time", G_TYPE_UINT64, running_time,
"duration", G_TYPE_UINT64, duration,
"offset", G_TYPE_UINT64, offset,
"offset-end", G_TYPE_UINT64, offset_end, NULL);
So when you get your structure you should use some of the GstStructure
functions to obtain data you are interested in:
guint64 timestamp;
gst_structure_get_uint64(MessageStructurePtr, "timestamp", ×tamp);
Solution 2:[2]
You can use a function to periodically (e.g. every 60s) udpate the (wall clock time <-> gstreamer pts timestamp) pair in multifilesink's sink pad probe. Then in your "HandleElementMessages" function, it will be convenient to calculate wall clock time when the file was processing, and can endure long time-duration.
Solution 3:[3]
I can get a file containing the current time with the following code.
static long gst_multi_file_sink_get_timestamp(void)
{
long millesec=0;
struct timespec tms;
clock_gettime(CLOCK_REALTIME,&tms);
// get micro second
/*
long micros=0;
micros = tms.tv_sec * 1000000;
micros += tms.tv_nsec/1000;
if (tms.tv_nsec % 1000 >= 500) {
++micros;
}
millesec = (long)(micros/1000);
GST_DEBUG("Millesecond: %lu\n",millesec);
*/
// get mille second
millesec = tms.tv_sec * 1000;
millesec += tms.tv_nsec/1000000;
if (tms.tv_nsec % 1000000 >= 500) {
++millesec;
}
return millesec;
}
And call the function from where you create the file name.
// filename = g_strdup_printf (multifilesink->filename,
// multifilesink->index);
filename = g_strdup_printf (multifilesink->filename,
gst_multi_file_sink_get_timestamp());
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Florian Zwoch |
Solution 2 | Horace He |
Solution 3 | ??? |