由于图像文件导致的分割错误
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()
这个实现有什么问题吗?
此致
我尝试将 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
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()
这个实现有什么问题吗?
此致