【问题标题】:How to listen to oggdemux gstreamer failures?如何收听 oggdemux gstreamer 失败?
【发布时间】:2019-11-04 18:34:21
【问题描述】:

我编写了一个 gstreamer 应用程序来将作品音频转换为原始音频。如果我向管道提供错误的音频(只是随机字节),则管道会卡住并且 /i 不会在消息总线上收到错误消息。

我正在收听流经管道的错误消息,但没有收到指示失败的错误代码。 gstreamer 调试日志表明 demux 失败,但我可以在日志中看到以下内容:

0:00:00.021614679 22541       0xe5b190 WARN                oggdemux gstoggdemux.c:4609:gst_ogg_demux_send_event:<oggdemux0> No chain to forward event to
0:00:00.021656681 22541       0xe5b190 WARN                oggdemux gstoggdemux.c:2433:gst_ogg_demux_sink_event:<oggdemux0> EOS while trying to retrieve chain, seeking disabled

以下是我编写的应用示例:

#include <gst/gst.h>
#include <gst/gstbin.h>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappsink.h>
#include <stdio.h>
#include <string.h>

static GMainLoop *loop;

FILE *file = NULL;
size_t bytesRead = 0;

typedef struct _CustomData
{
  GstElement *pipeline;
  GstAppSrc *app_source;

  guint sourceid; /* To control the GSource */

} CustomData;

static gboolean push_data(CustomData *data)
{
  GstBuffer *gbuffer;
  GstFlowReturn ret;

  char buffer[1024];

  gbuffer = gst_buffer_new_and_alloc(sizeof(buffer));
  GstMapInfo info;

  bytesRead = fread(buffer, 1, sizeof(buffer), file);

  gst_buffer_map(gbuffer, &info, GST_MAP_WRITE);
  memcpy(info.data, buffer, bytesRead);
  gst_buffer_unmap(gbuffer, &info);

  if (bytesRead > 0)
  {
    //g_print("Pushing %d\n", (int)bytesRead);
    /* Push the buffer into the appsrc */
    g_signal_emit_by_name(data->app_source, "push-buffer", gbuffer, &ret);
    return TRUE;
  }
  else
  {
    g_print("file complete\n");
    gst_app_src_end_of_stream(data->app_source);
    return FALSE;
  }

  gst_buffer_unref(gbuffer);
}

static void stop_feed(GstElement *source, CustomData *data)
{
  if (data->sourceid != 0)
  {
    g_print("Stop feeding\n");
    g_source_remove(data->sourceid);
    data->sourceid = 0;
  }
}

static void start_feed(GstElement *source, guint size, CustomData *data)
{
  if (data->sourceid == 0)
  {
    g_print("Start feeding\n");
    data->sourceid = g_idle_add((GSourceFunc)push_data, data);
  }
}

static gboolean bus_call(GstBus * bus, GstMessage * msg, gpointer user_data)
{
  switch (GST_MESSAGE_TYPE(msg))
  {

  case GST_MESSAGE_EOS:
    g_print("End of stream\n");
    g_main_loop_quit(loop);
    break;

  case GST_MESSAGE_ERROR:
  {
    gchar *debug;
    GError *error;

    gst_message_parse_error(msg, &error, &debug);
    g_free(debug);

    g_printerr("Error: from %s %s\n", GST_OBJECT_NAME(msg->src), error->message);
    g_error_free(error);

    g_main_loop_quit(loop);
    break;
  }
  default:
    break;
  }

  return TRUE;
}

int main(int argc,
         char *argv[])
{
  CustomData data;
  memset(&data, 0, sizeof(data));
  GstBus *bus;
  guint bus_watch_id;

  /* Initialisation */
  gst_init(&argc, &argv);

  loop = g_main_loop_new(NULL, FALSE);

  GError *error = NULL;


  data.pipeline = gst_parse_launch("concat name=c ! filesink location=program.wav appsrc name=src_00 ! oggdemux ! opusdec ! audioconvert ! audioresample ! audio/x-raw,format=S16LE,channels=1,rate=16000 ! queue ! c.", &error); 

  if (!data.pipeline)
  {
    g_printerr("Pipeline could not be created. Exiting.\n");
    return -1;
  }

  data.app_source = (G_TYPE_CHECK_INSTANCE_CAST((gst_bin_get_by_name(GST_BIN(data.pipeline), "src_00")), GST_TYPE_APP_SRC, GstAppSrc));
  g_signal_connect(data.app_source, "need-data", G_CALLBACK(start_feed), &data);
  g_signal_connect(data.app_source, "enough-data", G_CALLBACK(stop_feed), &data);

  /* we add a message handler */
  bus = gst_pipeline_get_bus(GST_PIPELINE(data.pipeline));
  bus_watch_id = gst_bus_add_watch(bus, bus_call, NULL);
  gst_object_unref(bus);

  file = fopen("junk.wav", "rb");

  /* Set the pipeline to "playing" state*/
  g_print("Now playing");
  gst_element_set_state(data.pipeline, GST_STATE_PLAYING);

  /* Iterate */
  g_print("Running...\n");
  g_main_loop_run(loop);

  /* Out of the main loop, clean up nicely */
  g_print("Returned, stopping playback\n");
  gst_element_set_state(data.pipeline, GST_STATE_NULL);

  g_print("Deleting pipeline\n");
  gst_object_unref(GST_OBJECT(data.pipeline));
  g_source_remove(bus_watch_id);
  g_main_loop_unref(loop);
  return 0;
}

我原以为解复用失败会跟随消息总线,但事实并非如此。我怎样才能听到这样的错误?

我已尝试使用其他使用 decodebin 的管道,但我在消息总线上收到错误消息。以下管道按预期工作:

gst_parse_launch("concat name=c ! filesink location=program.wav appsrc name=src_00 ! decodebin ! audioconvert ! audioresample ! audio/x-raw,format=S16LE,channels=1,rate=16000 ! queue ! c.", &error);

GStreamer 版本:1.8.3 操作系统:Ubuntu 16.04

【问题讨论】:

    标签: gstreamer ogg opus gstreamer-1.0


    【解决方案1】:

    这个问题似乎在 Gstreamer 1.14 中得到解决。更新后,我现在在消息总线上收到一条错误消息:

    Message: Error: from oggdemux0 Could not demultiplex stream.
    Error Code: GST_STREAM_ERROR_DEMUX
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-28
      • 1970-01-01
      • 2017-04-04
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      • 2019-08-22
      • 2019-01-09
      相关资源
      最近更新 更多