【问题标题】:How should I interpret the gstreamer multifilesink timestamp property?我应该如何解释 gstreamer multifilesink 时间戳属性?
【发布时间】:2019-04-01 20:14:21
【问题描述】:

我在 C 中使用 multifilesink 元素。multifilesink 创建带有索引的文件名,但我需要带有时间戳的文件名。方便的是,multifilesink 在每个文件写入后发送一条总线消息,并在消息数据中提供一个包含文件名和时间戳的 glib 结构。我已经设置了代码来监视消息并调用一个函数来重命名每个文件,如下所示:

“file-01.jpg”变成“file-DDMMYYYY_HHMMSS.sss.jpg”

每次写入文件时,我都可以成功接收消息并调用我的函数。

问题是我不明白时间戳的值。它似乎不是一个 unix 纪元时间,它不是单调的,而且该值通常是负数或零。

// 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()

我希望 GST_MESSAGE_TIMESTAMP() 应该返回一个与纪元或我能理解的某个起点相关的单调递增值。相反,我看到这样的结果:

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
...

【问题讨论】:

  • GST_MESSAGE_TIMESTAMP() 需要一个 GstMessage* 参数,您似乎提供了一个 GstStructure* ?
  • 感谢您指出这一点。当我解决这个问题时,它总是返回 -1。

标签: c timestamp gstreamer glib


【解决方案1】:

这是发送到总线的结构的代码:

  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);

所以当你得到你的结构时,你应该使用一些GstStructure 函数来获取你感兴趣的数据:

guint64 timestamp;

gst_structure_get_uint64(MessageStructurePtr, "timestamp", &timestamp);

【讨论】:

  • 感谢您的回答。这确实返回了一个“合理”的值。令人失望的是,这是自开始以来经过的时间,而不是绝对时间。我当然可以通过其他方式获得绝对时间,但它总是不准确的,因为它是在收到消息时生成的,而不是在发送时生成的。尽管这似乎是一个微小的差异,但对于我的应用程序来说,这很重要。我认为这是我可以期待的最好的,除非我修改 multifilesink 本身。
  • 我的解决方案是在第一个文件上记录一个挂钟 Tzero,然后在处理后续帧时为其添加时间戳值。这仍然会记录消息处理的时间,而不是原始时间,并且在长时间处理时容易漂移,但它现在只是一个创可贴。
【解决方案2】:

您可以使用函数定期(例如每 60 秒)更新 multifilesink 的接收器垫探测器中的(挂钟时间 gstreamer pts 时间戳)对。然后在您的“HandleElementMessages”函数中,可以方便地计算文件处理时的挂钟时间,并且可以忍受很长时间。

【讨论】:

    猜你喜欢
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    相关资源
    最近更新 更多