Guide for compiling and installing using gstreamer under ubuntu22.04

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