c++ - Gstreamer appsrc : odd behaviour of need-data callback

标签 c++ c audio callback gstreamer

我正在使用 appsrc 使用我自己的数据源实现 gstreamer 媒体播放器。一切正常,除了一件事:
当流到达它的末尾时,回调发出 "end-of-stream" 信号。信号发送函数
g_signal_emit_by_name(appsrc, "end-of-stream", &ret)
返回 GstFlowReturnGST_FLOW_OK .但随后它再次调用 need-data 我的回调,因此它再次返回 "end-of-stream" 信号。这次 GstFlowReturn 值为 (-3),即 GST_FLOW UNEXPECTED。我假设它在已经收到一个信号时不期望 "end-of-stream" 信号,但为什么它请求的数据比?可能是因为我没有设置steam的size值?

Gstreamer 版本为 0.10。
回调函数代码(appsrc type is seekable btw):

static void cb_need_data (GstElement *appsrc, guint size, gpointer user_data)
{
    GstBuffer *buffer;
    GstFlowReturn ret;
    AppsrcData* data = static_cast<AppsrcData*>(user_data);
    buffer = gst_buffer_new_and_alloc(size);

    int read = fread(GST_BUFFER_DATA(buffer), 1, size, data->file);
    GST_BUFFER_SIZE(buffer) = read;

    g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);

    if (ret != GST_FLOW_OK) {
        /* something wrong, stop pushing */
       g_printerr("GST_FLOW != OK, return value is %d\n", ret);
       g_main_loop_quit (data->loop);
    }

    if(feof(data->file) || read == 0)
    {
        g_signal_emit_by_name(appsrc, "end-of-stream", &ret);
        if (ret != GST_FLOW_OK) {
           g_printerr("EOF reached, GST_FLOW != OK, return value is %d\nAborting...", ret);
           g_main_loop_quit (data->loop);
        }
    }
}

最佳答案

您应该对您的代码进行一些更正(如果它们还不存在的话),以缓解您的问题并帮助整个应用程序:

  1. 切勿在未先检查缓冲区是否确实有数据的情况下尝试发送缓冲区。因此,只需检查缓冲区数据和长度以确保数据不为 NULL 且长度为 >0
  2. 您可以在您的 user_data 中标记流已结束。当您发送您的 EOS 时,在您的用户数据中设置一个项目以指示它已被发送,如果 appsrc 请求更多数据,只需检查它是否已被发送,然后不要向缓冲区发送任何其他内容。
  3. 在您的管道总线上监听 EOS,以便它可以销毁流并在处理 EOS 消息时关闭循环,这样您就可以确定您的 mediasink 已收到 EOS,并且您可以安全地处理管道和循环而不会丢失任何数据。

关于c++ - Gstreamer appsrc : odd behaviour of need-data callback,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27020163/

相关文章:

c - 具有多个父节点和子节点的链表

ios - 在iOS设备上更改HTML5音频标题

c# - Windows 8 Metro 录制音频(过滤噪音、改变音调)

c++ - 用另一个类成员 C++ 初始化一个类成员

c++ - 默认创建类 `final`还是给它们一个虚拟的析构函数?

c++ - 文件写入,插入运算符和写入功能的区别?

c++ - 当 operator< 在所有路径上递归时,Visual Studio 2008 运行时堆栈溢出警告

c - 为什么一元 * 运算符没有约束 "the operand shall not be a pointer to void"?

c - 在不知道文件大小且数据类型顺序不一致的情况下如何从文件中读取数据

java - 将音频流转换为 PCM