Environment preparation
The ubuntu release version 22.04 has built-in Gstreamer1.20.1, and the latest version of the gstreamer source code is 1.20.3, the gap is not big
Download gstreamer source code
Install git
<strong>sudo apt install -y git</strong> fuqiang@fuqiang-VivoBook:~/Workspace/gstreamer$ git --version git version 2.34.1
Download gstreamer
git clone https://gitlab.freedesktop.org/gstreamer/gstreamer.git git checkout --track -b 1.20 origin/1.20 --->1.20 is the current stable branch of the latest version, and the latest minor version number is 1.20.3
Prepare the compilation environment
Install meson
After gstreamer1.60 (excluding 1.60), use meson + ninja to build
<strong>sudo apt install -y meson</strong> fuqiang@fuqiang-VivoBook:~/Workspace/gstreamer$ meson --version <strong>0.61.2</strong>
Install glib
gstreamer is implemented based on glib-gobject
sudo apt install -y libglib2.0-dev
Install libsoup
sudo apt install -y libsoup2.4-dev
Install libunwind
1. Download package, http://download.savannah.nongnu.org/releases/libunwind/ 2. ./configure 3. make 4.sudo make install
Install libdw
sudo apt install -y libdw-dev
Install g-ir-scanner
Search for g-ir-scanner in the system, then copy it to /usr/lib/, and give execution permission
Install gobject-introspection-1.0
sudo apt-get install -y libgirepository1.0-dev
Install gtk+-3.0
sudo apt-get install -y libgtk-3-dev
Install hotdoc
<code>sudo apt-get install -y libjson-glib-dev</code>sudo apt install -y cmake python3-pip sudo pip3 install hotdoc
Install xgettext
Search for xgettext in the system, copy it to /usr/bin/, and give execution permission
Install alsa
sudo apt-get install -y libasound2-dev
Install cdda_paranoia
sudo apt install -y <em>cdparanoia</em>
Not yet, comment out cdparanoia first
Install libvisual-0.4
sudo apt install libvisual-0.4-dev
Install xv
Open the terminal and enter sudo snap install xv --edge
, if the installation fails, follow the prompts and enter sudo snap install xv --edge --devmode
to install successfully
Install SDL2
sudo apt-get install -y libsdl2-2.0 libsdl2-dev libsdl2-mixer-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-gfx-dev
Install qt5
sudo apt-get install -y clang qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools qtcreator sudo apt-get install -y qt5*
Install bz2
sudo apt install -y libbz2-dev
Install nasm/yasm
sudo apt install -y nasm yasm
Install gettext
sudo apt-get install -y gettext
Compile and install
Create out directory
cd gstreamer mkdir out
Compile
meson out cd out ninja sudo ninja install
Special compilation
meson --reconfigure -Dauto_features=enabled -Dgst-plugins-base:opus=disabled -Dgst-plugins-base:ogg=disabled out
Exception handling
Exception 1
subprojects/gstreamer/gst/parse/meson.build:7:0: ERROR: Program 'flex win_flex' not found or not executable
solution:
sudo apt install -y flex
Exception 2
subprojects/gstreamer/gst/parse/meson.build:34:0: ERROR: Program 'bison win_bison' not found or not executable
solution:
sudo apt install -y bison
Exception 3
fuqiang@fuqiang-VivoBook:~/Workspace/gstreamer/gstreamer/out$ninja ninja: error: 'subprojects/gst-plugins-bad/gst-libs/gst/transcoder/transcoder-enumtypes.h', needed by 'subprojects/gst-devtools/validate/tools/gst-validate-transcoding- 1.0.p/gst-validate-transcoding.c.o', missing and no known rule to make it
solution:
meson --reconfigure
Exception 4
fuqiang@ubuntu:~/workspace/gstreamer$ meson out The Meson build system Source dir: /home/fuqiang/workspace/gstreamer Build dir: /home/fuqiang/workspace/gstreamer/out Build type: native build meson.build:81:15: ERROR: lexer ['gstreamer', {'build-hotdoc': true}],
Solution: Update the meson version, this problem will occur in ubuntu18.04, the reason is that the meson version is too low, use pip3 to install meson
sudo pip3 install meson
If the version is still low, there may be the original meson in /usr/bin, and the newly installed meson in /usr/local/bin, just copy the content under /usr/local/bin to /usr/bin
Exception 5
msgfmt: command not found
solution:
sudo apt-get -y install gettext
Test command
Basic virtual test
gst-launch-1.0 videotestsrc ! autovideosink gst-launch-1.0 -v videotestsrc pattern=ball name=left ! autovideosink gst-launch-1.0 audiotestsrc ! autoaudiosink
Black hole fakesink
gst-launch-1.0 videotestsrc ! fakesink
Audio playback
gst-launch-1.0 filesrc location='/home/fuqiang/music/audio.mp3' ! decodebin ! audioconvert ! audioresample ! autoaudiosink
Video playback
gst-launch-1.0 filesrc location='/home/fuqiang/video/1080P.mov' ! decodebin ! autovideosink
Separate MP4 audio and video and play them separately
GST-LAUNCH-1.0 Filesrc Location = \ '/Home/Fuqiang/Video/1080p.mov '! QTDEMUX NAME = DEMUX DEMUX.AUDIO_0! Queue! AudioConvert! AU dioresample! AutoAudiosink Demux.video_0! Queue! Decodebin ! videoconvert ! videoscale ! autovideosink gst-launch-1.0 filesrc location='/home/fuqiang/video/1080P.mov' ! qtdemux name=demux demux.video_0 ! queue ! decodebin ! videoconvert ! videoscale ! autovideosink
Play video and set videobox
gst-launch-1.0 filesrc location='/home/fuqiang/video/1080P.mov' ! qtdemux name=demux demux.video_0 ! decodebin ! videoscale ! video/x-raw,width=100,height= 100 ! videobox border-alpha=0 top=-70 bottom=-70 right=-220 ! videoconvert ! autovideosink
Camera capture and playback (encoding output file)
gst-launch-1.0 v4l2src ! videoconvert ! autovideosink gst-launch-1.0 v4l2src ! videoconvert ! x264enc ! filesink location='/home/fuqiang/video/xx.mp4' gst-launch-1.0 v4l2src ! video/x-raw,width=1280,height=720 ! videoconvert ! openh264enc ! h264parse ! flvmux ! filesink location=aaa.flv
Collect audio to file
gst-launch-1.0 alsasrc ! audioresample ! audioconvert ! wavenc ! filesink location=/home/fuqiang/Videos/xx.wav
mp3 transcoding ogg
gst-launch-1.0 filesrc location='/home/fuqiang/music/audio.mp3' ! decodebin ! audioconvert ! vorbisenc ! oggmux ! filesink location='/home/fuqiang/music/audio.ogg\ '
timeoverlay
gst-launch-1.0 videotestsrc ! timeoverlay ! xvimagesink
Implement a simple plugin
Implementation Framework
Add the directory structure as follows:
fuqiang@fuqiang-VivoBook:~/workspace/gstreamer/subprojects/gst-plugins-bad/gst/myfilter$ tree . ├── meson.build ├── myfilter.c └── myfilter.h
Implement meson.build:
myfilter_sources = [ 'myfilter.c', ] gstmyfilter = library('gstmyfilter', myfilter_sources, c_args : gst_plugins_bad_args, include_directories : [configinc], dependencies : [gstbase_dep, gsttag_dep], install : true, install_dir : plugins_install_dir, ) pkgconfig.generate(gstmyfilter, install_dir : plugins_pkgconfig_install_dir) plugins += [gstmyfilter]
Add compilation related configuration:
fuqiang@fuqiang-VivoBook:~/workspace/gstreamer/subprojects/gst-plugins-bad$ git diff diff --git a/subprojects/gst-plugins-bad/gst/meson.build b/subprojects/gst-plugins-bad/gst/meson.build index 9cf62db983..063fff3aef 100644 --- a/subprojects/gst-plugins-bad/gst/meson.build + + + b/subprojects/gst-plugins-bad/gst/meson.build @@ -12,7 + 12,7 @@ foreach plugin : ['accurip', 'adpcmdec', 'adpcmenc', 'aiff', 'asfmux', 'segmentclip', 'siren', 'smooth', 'speed', 'subenc', 'switchbin', 'timecode', 'transcode', 'videofilters', 'videoframe_audiolevel', 'videoparsers', 'videosignal', <strong>- 'vmnc', 'y4m']</strong> <strong> + 'vmnc', 'y4m', 'myfilter']</strong> if not get_option(plugin).disabled() subdir(plugin) endif diff --git a/subprojects/gst-plugins-bad/meson_options.txt b/subprojects/gst-plugins-bad/meson_options.txt index b347dcb27b..320e4182c1 100644 --- a/subprojects/gst-plugins-bad/meson_options.txt + + + b/subprojects/gst-plugins-bad/meson_options.txt @@ -134,6 + 134,7 @@ option('onnx', type : 'feature', value : 'auto', description : 'ONNX neural netw option('openal', type : 'feature', value : 'auto', description : 'OpenAL plugin') option('openexr', type : 'feature', value : 'auto', description : 'OpenEXR plugin') option('openh264', type : 'feature', value : 'auto', description : 'H.264 video codec plugin') + option('myfilter', type : 'feature', value : 'auto', description : 'test filter') option('openjpeg', type : 'feature', value : 'auto', description : 'JPEG2000 image codec plugin') option('openmpt', type : 'feature', value : 'auto', description : 'OpenMPT module music library plugin') option('openni2', type : 'feature', value : 'auto', description : 'OpenNI2 library plugin')
Implement the h header file
#pragma once //Instruct the compiler to compile only once #include <gst/gst.h> #define VERSION "1.0" #define PACKAGE "myfilter" G_BEGIN_DECLS //property id enum { PROP_0, //id = 0 PROP_SILENT, //1 //PROP_A, //2 //PROP_B //3 PROP_CNT //4 }; //instance struct, every instance has one typedef struct _GstMyFilter { GstElement element; //parent class //pads GstPad* srcpad; //src pad //send port GstPad* sinkpad; //sink pad //receiving port gboolean silent; }GstMyFilter; //class struct, all instance shared content typedef struct _GstMyFilterClass { GstElementClass parent_class; //parent class }GstMyFilterClass; /* Standard macros for defining types for this element. */ #define GST_TYPE_MY_FILTER (gst_my_filter_get_type()) #define GST_MY_FILTER(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MY_FILTER,GstMyFilter)) #define GST_MY_FILTER_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MY_FILTER,GstMyFilterClass)) #define GST_IS_MY_FILTER(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MY_FILTER)) #define GST_IS_MY_FILTER_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MY_FILTER)) /* Standard function returning type information. */ GType gst_my_filter_get_type(void); G_END_DECLS //GST_ELEMENT_REGISTER_DECLARE (my_filter)
Realize the c file
#include "myfilter.h" #include <gst/gstelement.h> #include <gst/audio/audio-format.h> #include <gst/gstpad.h> #include <gst/gstplugin.h> #include <gst/gstconfig.h> #include <gobject/gparam.h> G_DEFINE_TYPE(GstMyFilter, gst_my_filter, GST_TYPE_ELEMENT); //GST_ELEMENT_REGISTER_DEFINE(my_filter, "my-filter", GST_RANK_NONE, GST_TYPE_MY_FILTER); //pad template preparation, describe the pad, then register sink_factory and src_factory in _class_init, and then create an instance in _init //sink pad static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE( "sink", //short name of pad GST_PAD_SINK, //pad direction-sink-input GST_PAD_ALWAYS, //existence-always GST_STATIC_CAPS("ANY") //support data type - any ); static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE( "src", //short name of pad GST_PAD_SRC, //pad direction - src - output GST_PAD_ALWAYS, //existence-always GST_STATIC_CAPS("ANY") //support data type - any ); static GstStaticPadTemplate sink_factory_1 = GST_STATIC_PAD_TEMPLATE(/sink_factory "sink_%u", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS( "audio/x-raw, " "format = (string) " GST_AUDIO_NE(S16) ", " "channels = (int) { 1, 2 }, " "rate = (int) [ 8000, 96000 ]" ) ); // ================= inner function start ================= // ================= inner function start ================= // ================= inner function start ================= static GstBuffer *gst_my_filter_process_data(GstMyFilter* filter, GstBuffer* buf) { //Request new memory //Process buf // Obtain new data and write to new memory \t//return return NULL; } static gboolean gst_my_filter_stop_processing(GstMyFilter* filter) { // Let the current element stop working return TRUE; } static gboolean gst_my_filter_allocate_memory(GstMyFilter* filter) { //Request the necessary memory //Load the necessary run-time lib return TRUE; } static gboolean gst_my_filter_free_memory(GstMyFilter* filter) { // release memory //Uninstall run-time lib return TRUE; } // ================= inner function end ================= // ================= inner function end ================= // ================= inner function end ================= //(!!!) sink pad routine data processing function static GstFlowReturn gst_my_filter_chain(GstPad* pad/*pad reveive buffer*/ , GstObject *parent, GstBuffer *buf/*to be processed*/) { GstMyFilter *filter = GST_MY_FILTER(parent); //It can be understood as getting this pointer GstBuffer *outbuf; outbuf = gst_my_filter_process_data(filter, buf); gst_buffer_unref(buf); if (!outbuf) { /* something went wrong - signal an error */ GST_ELEMENT_ERROR(GST_ELEMENT(filter), STREAM, FAILED, (NULL), (NULL)); return GST_FLOW_ERROR; } return gst_pad_push(filter->srcpad, outbuf); } //(!!!) sink pad event data processing static gboolean gst_my_filter_event(GstPad* pad/*pad reveive event*/, GstObject *parent, GstEvent *event/*to be preocessed*/) { gboolean ret; GstMyFilter *filter = GST_MY_FILTER(parent); //It can be understood as getting this pointer \t switch (GST_EVENT_TYPE(event)) { case GST_EVENT_CAPS: ret = gst_pad_push_event(filter->srcpad, event); /* push the event downstream */ break; case GST_EVENT_EOS: gst_my_filter_stop_processing(filter); ret = gst_pad_event_default(pad, parent, event); //Currently only GST_EVENT_CAPS has default action break; default: ret = gst_pad_event_default(pad, parent, event); //Currently only GST_EVENT_CAPS has default action break; } return ret; } //(!!!) query object processing static gboolean gst_my_filter_src_query(GstPad* pad, GstObject* parent, GstQuery* query) { gboolean ret; GstMyFilter *filter = GST_MY_FILTER(parent); switch (GST_QUERY_TYPE(query)) { case GST_QUERY_POSITION: /* we should report the current position */ break; case GST_QUERY_DURATION: /* we should report the duration here */ break; case GST_QUERY_CAPS: /* we should report the supported caps here */ break; default: /* just call the default handler */ ret = gst_pad_query_default(pad, parent, query); //default handler break; } return ret; } //(!!!) state changed handler function static GstStateChangeReturn gst_my_filter_change_state(GstElement *element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstMyFilter *filter = GST_MY_FILTER(element); \t /* Note that upwards (NULL=>READY, READY=>PAUSED, PAUSED=>PLAYING) and downwards (PLAYING=>PAUSED, PAUSED=>READY, READY=>NULL) state changes are handled in two separate blocks with the downwards state change handled only after we have chained up to the parent class's state change function. This is necessary in order to safely handle concurrent access by multiple threads. */ //process upwards state change switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!gst_my_filter_allocate_memory(filter)) //apply for resources return GST_STATE_CHANGE_FAILURE; break; case GST_STATE_CHANGE_READY_TO_PAUSED: //dosomething break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: //dosomething break; default: break; } //Evoke the state change handler of the parent class //ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); ret = GST_ELEMENT_CLASS(GST_ELEMENT_GET_CLASS(element))->change_state(element, transition); if (ret == GST_STATE_CHANGE_FAILURE) return ret; //process downwards state change switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: //dosomething break; case GST_STATE_CHANGE_PAUSED_TO_READY: //dosomething break; case GST_STATE_CHANGE_READY_TO_NULL: gst_my_filter_free_memory(filter); break; default: break; } return ret; } //(!!!) property read and write processing function static void gst_my_filter_set_property(GObject* object, guint prop_id, const GValue * value, GParamSpec *pspec) { GstMyFilter* filter = GST_MY_FILTER(object); switch(prop_id) { case PROP_SILENT: filter->silent = g_value_get_boolean(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void gst_my_filter_get_property(GObject* object, guint prop_id, GValue * value, GParamSpec *pspec) { GstMyFilter *filter = GST_MY_FILTER(object); switch(prop_id) { case PROP_SILENT: g_value_set_boolean(value, filter->silent); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } // class initialization function (class constructor) static void gst_my_filter_class_init(GstMyFilterClass *klass) { GstElementClass *element_class = GST_ELEMENT_CLASS(klass); //for others GObjectClass *object_class = G_OBJECT_CLASS(klass); //for property setter and getter, because the function of glib is used, it is converted to gobjectclass //meta data gst_element_class_set_static_metadata(element_class, "obentul example plugin", "Example/FirstExample", "Shows the basic structure of a plugin", "fuqiang <[email protected]>"); //register state change function element_class->change_state = gst_my_filter_change_state; //register property setter and getter object_class->set_property = gst_my_filter_set_property; object_class->get_property = gst_my_filter_get_property; //[todo] reigster properties //silent //g_object_class_install_property( // object_class, // PROP_SILENT, // g_param_spec_boolean("property-name: silent", "description", "test property, no specific function", FALSE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)) //); //register pads gst_element_class_add_pad_template(element_class, gst_static_pad_template_get( &src_factory)); gst_element_class_add_pad_template(element_class, gst_static_pad_template_get( & sink_factory)); } //Instance initialization function (instance constructor) static void gst_my_filter_init(GstMyFilter *filter) { //instantiates and assigns pads filter->srcpad = gst_pad_new_from_static_template( & amp;src_factory,"src_%u"); // Does %u mean there can be more than one? filter->sinkpad = gst_pad_new_from_static_template( & amp;sink_factory, "sink_%u"); //add pads to element gst_element_add_pad(GST_ELEMENT(filter), filter->srcpad); gst_element_add_pad(GST_ELEMENT(filter), filter->sinkpad); //set chain function for sink pad gst_pad_set_chain_function(filter->sinkpad, gst_my_filter_chain); //set event function gst_pad_set_event_function(filter->sinkpad, gst_my_filter_event); //set query function gst_pad_set_query_function(filter->srcpad, gst_my_filter_src_query); //All attributes are currently unavailable filter->silent = FALSE; } //Function to be called when the plugin is loaded gboolean plugin_init(GstPlugin* myfilter) { return gst_element_register(myfilter, "myfilter", GST_RANK_MARGINAL, GST_TYPE_MY_FILTER); } //Plugin description information GST_PLUGIN_DEFINE( GST_VERSION_MAJOR, GST_VERSION_MINOR, myfilter, "My filter plugin", plugin_init, VERSION, "LGPL", "GStreamer template Plug-ins", "http://gstreamer.net/" )
build compile install
meson --reconfigure -Dgst-plugins-bad:myfilter=enabled out cd out ninja sudo ninja install
View plugin status
fuqiang@fuqiang-VivoBook:~/workspace/gstreamer/subprojects/gst-plugins-bad/gst/myfilter$ gst-inspect-1.0 myfilter Factory Details: Rank marginal (64) Long-name obentul example plugin Klass Example/First Example Description Shows the basic structure of a plugin Author obentul <[email protected]> Plugin Details: Name myfilter Description My filter plugin Filename /usr/local/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmyfilter.so Version 1.0 License LGPL Source module myfilter Binary package GStreamer template Plug-ins Origin URL http://gstreamer.net/ GObject +----GInitiallyUnowned + ----GstObject +----GstElement +----GstMyFilter Pad Templates: SINK template: 'sink' Availability: Always Capabilities: ANY SRC template: 'src' Availability: Always Capabilities: ANY Element has no clocking capabilities. Element has no URI handling capabilities. Pads: SRC: 'src_%u' Pad Template: 'src' SINK: 'sink_%u' Pad Template: 'sink' Element Properties: name : The name of the object flags: readable, writable, 0x2000 String. Default: "myfilter0" parent : The parent of the object flags: readable, writable, 0x2000 Object of type "GstObject
Currently the plugin does nothing and cannot be used normally
gst-launch-1.0 videotestsrc ! autovideosink //can play normally gst-launch-1.0 videotestsrc ! myfilter ! autovideosink //Cannot play normally
Next, we will open the plug-in to let the data pass through
Code debugging method
Add printing
#define GST_ERROR(...) GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_ERROR, NULL, __VA_ARGS__) #define GST_WARNING(...) GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_WARNING, NULL, __VA_ARGS__) #define GST_INFO(...) GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_INFO, NULL, __VA_ARGS__) #define GST_DEBUG(...) GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_DEBUG, NULL, __VA_ARGS__) #define GST_LOG(...) GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_LOG, NULL, __VA_ARGS__) #define GST_FIXME(...) GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_FIXME, NULL, __VA_ARGS__) #define GST_TRACE(...) GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_TRACE, NULL, __VA_ARGS__)
gdb
Make sure the core file size limit is lifted
fuqiang@fuqiang-VivoBook:/usr/lib/x86_64-linux-gnu$ <strong>ulimit -a</strong> real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) <strong>0</strong> data segment size (kbytes, -d) unlimited scheduling priority (-e) 0 ... fuqiang@fuqiang-VivoBook:/usr/lib/x86_64-linux-gnu$<strong>ulimit -c unlimited</strong> fuqiang@fuqiang-VivoBook:/usr/lib/x86_64-linux-gnu$ <strong>ulimit -a</strong> real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) <strong>unlimited</strong> data segment size (kbytes, -d) unlimited scheduling priority (-e) 0 ...
Confirm the location of the core file
sudo service apport stop cat /proc/sys/kernel/core_pattern echo core > /proc/sys/kernel/core_pattern
manufacturing crash
static void gst_mydecoder_init (Gstmydecoder * filter) { GST_ERROR("gst_mydecoder_init"); <strong> char *str = NULL; str[0] = 0;</strong> filter->sinkpad = gst_pad_new_from_static_template ( & amp;sink_factory, "sink");
implement
fuqiang@fuqiang-VivoBook:~/workspace/gstreamer$ gst-launch-1.0 --gst-debug=3 videotestsrc ! mydecoder ! autovideosink (gst-launch-1.0:911980): GStreamer-CRITICAL **: 18:18:11.516: gst_debug_log_valist: assertion 'category != NULL' failed 0:00:00.016936571 911980 0x558ab0cca100 ERROR mydecoder gstmydecoder.c:123:gst_mydecoder_class_init: gst_mydecoder_class_init 0:00:00.016957593 911980 0x558ab0cca100 ERROR mydecoder gstmydecoder.c:158:gst_mydecoder_init: gst_mydecoder_init Caught SIGSEGV Spinning. Please run 'gdb gst-launch-1.0 911980' to continue debugging, Ctrl-C to quit, or Ctrl-\ to dump core
Generate a core dump file after executing CTRL-\
fuqiang@fuqiang-VivoBook:~/workspace/gstreamer$ ls -al Total usage 4380 drwxrwxr-x 13 fuqiang fuqiang 4096 July 20 18:18 . drwxrwxr-x 6 fuqiang fuqiang 4096 July 19 14:58 .. drwxrwxr-x 8 fuqiang fuqiang 4096 Jul 18 08:57 ci <strong>-rw------- 1 fuqiang fuqiang 4599808 July 20 18:18 core.911980</strong> drwxrwxr-x 5 fuqiang fuqiang 4096 July 16 20:51 data -rw-rw-r-- 1 fuqiang fuqiang 131 Jul 18 08:57 .editorconfig drwxrwxr-x 8 fuqiang fuqiang 4096 Jul 20 16:44 .git -rw-rw-r-- 1 fuqiang fuqiang 1064 Jul 16 20:51 .gitignore drwxrwxr-x 3 fuqiang fuqiang 4096 Jul 16 20:51 .gitlab ...
gdb debugging
fuqiang@fuqiang-VivoBook:~/workspace/gstreamer$ <strong>gdb gst-launch-1.0 core.911980</strong> GNU gdb (Ubuntu 12.0.90-0ubuntu1) 12.0.90 Copyright (C) 2022 Free Software Foundation, Inc. License GPLv3 + : GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from gst-launch-1.0... [New LWP 911980] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `gst-launch-1.0 --gst-debug=3 videotestsrc ! mydecoder ! autovideosink'. <strong>Program terminated with signal SIGQUIT, Quit.</strong> #0 0x00007fdda845b7fa in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=0x7ffeed177940, rem=0x7ffeed177930) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78 78 ../sysdeps/unix/sysv/linux/clock_nanosleep.c: No such file or directory. (gdb)
After bt calls out the stack, you can check the problem
gst_mydecoder_init (filter=<optimized out>) at ../subprojects/gst-plugins-bad/gst/mydecoder/<strong>gstmydecoder.c:160</strong>
Pay attention to the problem:
sudo service apport stop , you need to shut down the service of the system through this command
The size of the core is 0: 1. Ulimit modification 2. The core must be generated in the local partition, and cannot be mounted on the partition, such as a U disk
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledgeGit skill treeHome pageOverview 5288 people are studying systematically