由于图像文件导致的分割错误

segmentation fault due to an image file

我尝试将 gstreamer c 代码与 ZXing-cpp 集成 https://github.com/nu-book/zxing-cpp

这是我的代码

#include "core/ReadBarcode.h"
#include "core/TextUtfEncoding.h"

#include <algorithm>
#include <cctype>
#include <cstring>
#include <iostream>
#include <string>
#include <deque>

#include <gst/gst.h>
#include <gst/app/gstappsink.h>
#include <stdlib.h>

using namespace ZXing;

std::deque<ImageView> frameQueue;

GstFlowReturn
new_preroll(GstAppSink *appsink, gpointer data) {
  g_print ("Got preroll!\n");
  return GST_FLOW_OK;
}

GstFlowReturn
new_sample(GstAppSink *appsink, gpointer data) {
  static int framecount = 0;
  framecount++;

  GstSample *sample = gst_app_sink_pull_sample(appsink);
  GstCaps *caps = gst_sample_get_caps(sample);
  GstBuffer *buffer = gst_sample_get_buffer(sample);
  const GstStructure *info = gst_sample_get_info(sample);

  // ---- Read frame and convert to ImageView format ---------------
  GstMapInfo map;
  gst_buffer_map (buffer, &map, GST_MAP_READ);

  g_print("Processing new data \n");

   ImageView frame( (unsigned char *)map.data, 720, 480,ImageFormat::RGBX);
   frameQueue.push_back(frame);

   gst_buffer_unmap(buffer, &map);

  // ------------------------------------------------------------
  // show caps on first frame
  if (framecount == 1) {
    g_print ("%s\n", gst_caps_to_string(caps));
  }
  gst_sample_unref (sample);

  return GST_FLOW_OK;
}

static gboolean
my_bus_callback (GstBus *bus, GstMessage *message, gpointer data) {
  g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR: {
      GError *err;
      gchar *debug;

      gst_message_parse_error (message, &err, &debug);
      g_print ("Error: %s\n", err->message);
      g_error_free (err);
      g_free (debug);
      break;
    }
    case GST_MESSAGE_EOS:
      g_print ("End of Stream \n ");
      // end-of-stream
      break;
    case GST_MESSAGE_STATE_CHANGED:
      // state has changed
      break;
    default:
      // unhandled message
      g_print ("Unknown Error \n ");
      break;
  }
  /* we want to be notified again the next time there is a message
   * on the bus, so returning TRUE (FALSE means we want to stop watching
   * for messages on the bus and our callback should not be called again)
   */
  return TRUE;
}

int main (int argc, char *argv[])
{
  GError *error = NULL;

  gst_init (&argc, &argv);

  gchar *descr = g_strdup(
    "v4l2src ! "
    "videorate ! "
    "video/x-raw,width=720,height=480 ! "
    "tee name=qr  "
    "qr. ! queue ! "
    "timeoverlay ! "
    "autovideosink  "
    "qr. ! queue ! "
    "appsink name=qrsink sync=true "
  );

  g_print("launching pipeline \n");
  GstElement *pipeline = gst_parse_launch (descr, &error);

  if (error != NULL) {
    g_print ("could not construct pipeline: %s\n", error->message);
    g_error_free (error);
    exit (-1);
  }

  /* get sink */
  GstElement *sink = gst_bin_get_by_name (GST_BIN (pipeline), "qrsink");

  gst_app_sink_set_emit_signals((GstAppSink*)sink, true);
  gst_app_sink_set_drop((GstAppSink*)sink, true);
  gst_app_sink_set_max_buffers((GstAppSink*)sink, 1);
  GstAppSinkCallbacks callbacks = { NULL, new_preroll, new_sample };
  gst_app_sink_set_callbacks (GST_APP_SINK(sink), &callbacks, NULL, NULL);

  GstBus *bus;
  guint bus_watch_id;
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  bus_watch_id = gst_bus_add_watch (bus, my_bus_callback, NULL);
  gst_object_unref (bus);

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  while(1) {
    // g_main_iteration(false);
    g_main_context_iteration(NULL, false);

    DecodeHints hints;
    bool haveResult;

    if (frameQueue.size() > 0) {
        g_print("Outputting image  \n");
        ImageView subject = frameQueue.front();
        g_print("Begin Image Processing \n");
        auto result = ReadBarcode(subject, hints);
    }
  }

  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (pipeline));

  return 0;
}

现在我遇到以下错误

Segmentation fault: (Core dumped)

我已经将错误缩小到这一行

auto result = ReadBarcode(subject, hints);

以某种方式内存访问图像对象(主题是 objectType ImageView,其定义可以在 ZXing-cpp github 站点 ReadBarCode.h/cpp 中找到)是不允许的。请问是什么问题

或者想知道错误会不会是在将 gstreamer 缓冲区分配给队列时出现的

ImageView frame( (unsigned char *)map.data, 720, 480,ImageFormat::RGBX);
frameQueue.push_back(frame);

感谢您的帮助

对代码进行了以下更改。我没有使用 ImageView(事实证明它是对象的视图而不是保存内存),而是使用 std::array frame 作为缓冲区的持有者并将其用于进入队列

  std::array<unsigned char, FRAME_HEIGHT * FRAME_WIDTH> frame;
  std::memcpy (frame.data(), buf, FRAME_HEIGHT * FRAME_WIDTH);

  frameQueue.push_back(frame);

在另一个尺寸上,我排在队列的前面

auto result = ReadBarcode( { (frameQueue.front()).data(), FRAME_WIDTH, FRAME_HEIGHT, ImageFormat::Lum}, hints);

并且当操作结束时

frameQueue.pop_front()

这个实现有什么问题吗?

此致