一、簡介
要移植gstreamer到qnx系統,除了本身的libgstreamer之外,還需要編譯相關的插件庫,比如編解碼庫,比如各種音視頻容器庫。
二、 編譯plugin base 庫
這裏筆者一開始使用的和libgstreamer庫一樣,使用configure的方式,寫一個myconfig.sh來編譯,但是發現編譯出來的plugin library會帶有rpath的硬依賴路徑,因此這裏嘗試了另一種方式, 和編譯glib一樣,使用meson交叉編譯,寫一個qnx_arm.txt的 cross file文件,其內容如下:
[host_machine]
system = 'qnx'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'
[binaries]
c = 'arm-unknown-nto-qnx6.6.0eabi-gcc'
cpp = 'arm-unknown-nto-qnx6.6.0eabi-g++'
ar = 'arm-unknown-nto-qnx6.6.0eabi-ar'
strip = 'arm-unknown-nto-qnx6.6.0eabi-strip'
pkgconfig = 'pkg-config'
[properties]
c_args = ['-D_QNX_SOURCE=1']
c_link_args = ['-lsocket', '-L/media/guwen/workspace/project/gstreamer/out/lib',
'-lgobject-2.0', '-lgio-2.0', '-lgmodule-2.0', '-lffi']
cpp_args = ['-D_QNX_SOURCE=1']
cpp_link_args = ['-lsocket', '-L/media/guwen/workspace/project/gstreamer/out/lib',
'-lgobject-2.0', '-lgio-2.0', '-lgmodule-2.0', '-lffi']
[paths]
prefix = '/media/guwen/workspace/project/gstreamer/out'
除了cross file文件之外,還需要修改 meson.build文件,其修改部分如下:
default_options : [ 'warning_level=1',
'buildtype=release', # 修改編譯類型爲release
'gtk_doc=disabled', # 禁用gtk_doc
'alsa=disabled', # 禁用alsa
'x11=disabled', # 禁用x11
'pango=disabled', # 禁用pango
'orc=disabled' # 禁用orc
])
另外,還需要設置pkg config 的路徑:
export PKG_CONFIG_LIBDIR=/media/guwen/workspace/project/gstreamer/out/lib/pkgconfig
注: 若果設置成了
export PKG_CONFIG_PATH=/media/guwen/workspace/project/gstreamer/out/lib/pkgconfig
就必須要在再設置PKG_CONFIG_LIBDIR, 因爲如果只設置了PKG_CONFIG_PATH路徑, pkg-config在這個路徑搜索之後,再到PKG_CONFIG_LIBDIR(這個就會是寄主系統默認路徑,Ubuntu的/usr/lib/pkgconfig等等)這個路徑搜索, 因此一定要設置PKG_CONFIG_LIBDIR變量,以防止pkg-config到系統默認路徑去搜索。
接下來也就是配置,編譯,安裝:
mkdir build
cd build
meson .. --cross-file ../qnx_arm.txt
ninja
ninja install
三、編譯plugin good 庫
plugin good庫也是使用meson進行編譯的,首先是qnx_arm.txt這個cross file的編寫,其內容如下:
[host_machine]
system = 'qnx'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'
[binaries]
c = 'arm-unknown-nto-qnx6.6.0eabi-gcc'
cpp = 'arm-unknown-nto-qnx6.6.0eabi-g++'
ar = 'arm-unknown-nto-qnx6.6.0eabi-ar'
strip = 'arm-unknown-nto-qnx6.6.0eabi-strip'
pkgconfig = 'pkg-config'
[properties]
c_args = ['-D_QNX_SOURCE=1']
c_link_args = ['-lsocket', '-L/media/guwen/workspace/project/gstreamer/out/lib',
'-lgobject-2.0', '-lgio-2.0', '-lgmodule-2.0', '-lglib-2.0', '-lintl',
'-lffi']
cpp_args = ['-D_QNX_SOURCE=1']
cpp_link_args = ['-lsocket', '-L/media/guwen/workspace/project/gstreamer/out/lib',
'-lgobject-2.0', '-lgio-2.0', '-lgmodule-2.0', '-lglib-2.0', '-lintl',
'-lffi']
[paths]
prefix = '/media/guwen/workspace/project/gstreamer/out'
然後是meson.build修改:
default_options : [ 'warning_level=1',
'buildtype=release', #修改編譯類型爲release
'c_std=gnu99', #修改c語言標準爲99標準
'mpg123=enabled' #使能mp3 audio decoder
])
3.1 編譯mpg123
首下載mpg123庫源碼 http://www.mpg123.de/download/mpg123-1.25.13.tar.bz2 ,這裏使用的是最新的1.25.13版本。
mpg123使用的也是configure,make的方式。 因此爲了方便,先編寫myconfig.sh腳本文件,其內容如下:
./configure --prefix=/media/guwen/workspace/project/gstreamer/out \
--build=i686-linux --host=arm-unknown-nto-qnx6.6.0eabi
接下來就是編譯和安裝:
make
make install
3.2 修改編譯錯誤
- 修改源文件gst/flx/gstflxdec.c
/** 原始版本 882行 */
if (!flx_decode_chunks (flxdec, n_chunks, &chunks, &writer)) {
GST_ELEMENT_ERROR (flxdec, STREAM, DECODE,
("%s", "Could not decode chunk"), NULL);
goto unmap_input_error;
}
/////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
if (!flx_decode_chunks (flxdec, n_chunks, &chunks, &writer)) {
GST_ELEMENT_ERROR (flxdec, STREAM, DECODE,
("%s", "Could not decode chunk"), (NULL));
goto unmap_input_error;
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/** 原始版本 894行 */
out = gst_buffer_new_and_alloc (flxdec->size * 4);
if (!gst_buffer_map (out, &map, GST_MAP_WRITE)) {
GST_ELEMENT_ERROR (flxdec, STREAM, DECODE,
("%s", "Could not map output buffer"), NULL);
gst_buffer_unref (out);
goto unmap_input_error;
}
/////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
out = gst_buffer_new_and_alloc (flxdec->size * 4);
if (!gst_buffer_map (out, &map, GST_MAP_WRITE)) {
GST_ELEMENT_ERROR (flxdec, STREAM, DECODE,
("%s", "Could not map output buffer"), (NULL));
gst_buffer_unref (out);
goto unmap_input_error;
}
- 修改文件 gst/multifile/gstsplitmuxsink.c
/** 原始版本 1564行 */
GST_ELEMENT_ERROR (splitmux, RESOURCE, SETTINGS,
("Could not create the new muxer/sink"), NULL);
}
/////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
GST_ELEMENT_ERROR (splitmux, RESOURCE, SETTINGS,
("Could not create the new muxer/sink"), (NULL));
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
/** 原始版本 1753行 */
GST_ELEMENT_ERROR (splitmux, RESOURCE, SETTINGS,
("Could not create the new muxer/sink"), NULL);
}
/////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
GST_ELEMENT_ERROR (splitmux, RESOURCE, SETTINGS,
("Could not create the new muxer/sink"), (NULL));
}
- 修改文件gst/rtp/gstrtpj2kdepay.c
/** 原始版本 211行 */
GST_ELEMENT_WARNING (depayload, STREAM, DEMUX, NULL,
("Non-compliant stream: sampling field missing. Frames my appear incorrect"));
/////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
GST_ELEMENT_WARNING (depayload, STREAM, DEMUX, (NULL),
("Non-compliant stream: sampling field missing. Frames my appear incorrect"));
3.3 編譯
和前面一樣,流程是一樣的:
export PKG_CONFIG_LIBDIR=/media/guwen/workspace/project/gstreamer/out/lib/pkgconfig
mkdir build
cd build
meson .. --cross-file ../qnx_arm.txt
ninja
ninja install
四、編譯plugin bad庫
qnx_arm.txt這個cross file的內容如下:
[host_machine]
system = 'qnx'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'
[binaries]
c = 'arm-unknown-nto-qnx6.6.0eabi-gcc'
cpp = 'arm-unknown-nto-qnx6.6.0eabi-g++'
ar = 'arm-unknown-nto-qnx6.6.0eabi-ar'
strip = 'arm-unknown-nto-qnx6.6.0eabi-strip'
pkgconfig = 'pkg-config'
[properties]
c_args = ['-D_QNX_SOURCE=1']
c_link_args = ['-lsocket', '-L/media/guwen/workspace/project/gstreamer/out/lib',
'-lgobject-2.0', '-lgio-2.0', '-lgmodule-2.0','-lgstrtp-1.0',
'-lffi']
cpp_args = ['-D_QNX_SOURCE=1']
cpp_link_args = ['-lsocket', '-L/media/guwen/workspace/project/gstreamer/out/lib',
'-lgobject-2.0', '-lgio-2.0', '-lgmodule-2.0','-lgstrtp-1.0',
'-lffi']
[paths]
prefix = '/media/guwen/workspace/project/gstreamer/out'
meson.build 文件修改:
default_options : [ 'warning_level=1',
'buildtype=release' ]) #修改編譯類型爲release
4.1 修改編譯錯誤
和plugin good一樣,配置完成之後,編譯會有錯誤需要修正。
- 修改文件gst/timecode/gstavwait.c
/** 原始版本 1128行 */
GST_ELEMENT_ERROR (self, CORE, FAILED,
("Failed to clip audio: it should have ended before the current segment"),
NULL);
/////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
GST_ELEMENT_ERROR (self, CORE, FAILED,
("Failed to clip audio: it should have ended before the current segment"),
(NULL));
- 修改文件 gst/videoparsers/gstjpeg2000parse.c
/** 原始版本 354行 */
if (j2c_box_id_offset == -1) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Missing contiguous code stream box for j2c stream"));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
if (j2c_box_id_offset == -1) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, (NULL),
("Missing contiguous code stream box for j2c stream"));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/** 原始版本 383行 */
if (j2c_box_id_offset + GST_JPEG2000_JP2_SIZE_OF_BOX_ID != magic_offset) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Corrupt contiguous code stream box for j2c stream"));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
if (j2c_box_id_offset + GST_JPEG2000_JP2_SIZE_OF_BOX_ID != magic_offset) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, (NULL),
("Corrupt contiguous code stream box for j2c stream"));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/** 原始版本 421行 */
if ((profile > GST_JPEG2000_PARSE_PROFILE_CINEMA_LTS)
&& !gst_jpeg2000_parse_is_broadcast (profile)
&& !gst_jpeg2000_parse_is_imf (profile)) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Unrecognized JPEG 2000 profile %d", profile));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
if ((profile > GST_JPEG2000_PARSE_PROFILE_CINEMA_LTS)
&& !gst_jpeg2000_parse_is_broadcast (profile)
&& !gst_jpeg2000_parse_is_imf (profile)) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, (NULL),
("Unrecognized JPEG 2000 profile %d", profile));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/** 原始版本 434行 */
if (sub_level > 9) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Sub level %d is invalid", sub_level));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
if (sub_level > 9) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, (NULL),
("Sub level %d is invalid", sub_level));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/** 原始版本 441行 */
if (validate_main_level && main_level > 11) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Main level %d is invalid", main_level));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
if (validate_main_level && main_level > 11) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, (NULL),
("Main level %d is invalid", main_level));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/** 原始版本 464行 */
/* sanity check on image dimensions */
if (x1 < x0 || y1 < y0) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Nonsensical image dimensions %d,%d,%d,%d", x0, y0, x1, y1));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
if (x1 < x0 || y1 < y0) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, (NULL),
("Nonsensical image dimensions %d,%d,%d,%d", x0, y0, x1, y1));
ret = GST_FLOW_ERROR;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/** 原始版本 484行 */
if (numcomps == 0 || numcomps > GST_JPEG2000_PARSE_MAX_SUPPORTED_COMPONENTS) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL,
("Unsupported number of components %d", numcomps));
ret = GST_FLOW_NOT_NEGOTIATED;
goto beach;
}
////////////////////////////////////////////////////////////////////////////////////
/** 修改之後的版本 */
if (numcomps == 0 || numcomps > GST_JPEG2000_PARSE_MAX_SUPPORTED_COMPONENTS) {
GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, (NULL),
("Unsupported number of components %d", numcomps));
ret = GST_FLOW_NOT_NEGOTIATED;
goto beach;
}
4.2 編譯 fdk-aac 庫
不知道怎麼回事,gstreamer的libav插件好多decoder都不能正常使用,這裏我驗證用的mkv文件裏面音頻是aac格式的,結果用libav就匹配不了, 因此只能使用開源的fdk-acc庫,首先是配置的腳本文件:
./configure --prefix=/media/guwen/workspace/project/gstreamer/out \
--host=arm-unknown-nto-qnx6.6.0eabi --disable-static
然後再進行編譯安裝
make -j4
make install
4.3 編譯
和前面一樣,其過程如下:
export PKG_CONFIG_LIBDIR=/media/guwen/workspace/project/gstreamer/out/lib/pkgconfig
mkdir build
cd build
meson .. --cross-file ../qnx_arm.txt
ninja
ninja install
五、編譯gst-libav 庫
5.1 編譯FFmpeg
首先是交叉編譯FFmpeg庫,第一步,編寫進行配置用的shell腳本文件myconfig.sh,其內容如下:
./configure --prefix=/media/guwen/workspace/project/gstreamer/out \
--cross-prefix=arm-unknown-nto-qnx6.6.0eabi- \
--enable-cross-compile \
--pkg-config=pkg-config \
--target-os=qnx \
--cc=arm-unknown-nto-qnx6.6.0eabi-gcc \
--arch=arm \
--enable-shared \
--disable-static \
--enable-gpl \
--enable-nonfree \
--disable-armv5te \
--disable-armv6 \
--disable-armv6t2 \
--disable-debug \
--enable-neon \
--extra-cflags="-std=gnu99 -fPIC" \
--disable-programs \
--disable-encoders \
--disable-devices \
--disable-muxers \
--disable-decoders \
--disable-demuxers \
--disable-avdevice \
--disable-bsfs \
--disable-filters \
--disable-doc \
--enable-decoder=h264 \
--enable-decoder=aac \
--enable-decoder=ac3 \
--enable-demuxer=mov \
--enable-demuxer=mp3 \
--enable-demuxer=matroska
這裏只enable了 h264 aac ac3 , mov, mp3, matroska 等幾個解碼器和容器,這樣既可以加快編譯速度,也可以減少生成lib的大小。
- 修改編譯錯誤,文件libavformat/sctp.c
這個文件的錯誤主要是因爲CMSG_SPACE這個宏來計算recvmsg和sendmsg的buffer size, 其錯誤原因,將這個計算出來的size,作爲一個數組的size,但CMSG_SPACE這個宏的實現裏面有一個是獲取align大小的函數__cmsg_alignbytes,因此就會報這樣的錯誤:
libavformat/sctp.c: In function ‘ff_sctp_recvmsg’:
libavformat/sctp.c:80:17: error: variable length array ‘incmsg’ is used [-Werror=vla]
libavformat/sctp.c: In function ‘ff_sctp_send’:
libavformat/sctp.c:131:22: error: variable length array ‘outcmsg’ is used [-Werror=vla]
因此這裏需要自己實現CMSG_SPACE這個宏,在qnx的toolchain中,其定義如下:
/*
* Alignment requirement for CMSG struct manipulation.
* This basically behaves the same as ALIGN() ARCH/include/param.h.
* We declare it separately for two reasons:
* (1) avoid dependency between machine/param.h, and (2) to sync with kernel's
* idea of ALIGNBYTES at runtime.
* without (2), we can't guarantee binary compatibility in case of future
* changes in ALIGNBYTES.
*/
#define __CMSG_ALIGN(n) (((n) + __cmsg_alignbytes()) & ~__cmsg_alignbytes())
#define CMSG_SPACE(l) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(l))
出現錯誤的原因就是因爲這裏的__cmsg_alignbytes是一個函數,其作用是獲取cmsg是按幾個字節對齊的,經過測試,這個函數的返回值爲7, 因此這裏實現的的宏如下所示:
/**爲了預防衝突,將CMSG_SPACE 修改爲 MY_CMSG_SPACE */
#define __MY_CMSG_ALIGN(n) (((n) + 7) & ~7)
#define MY_CMSG_SPACE(l) \
(__MY_CMSG_ALIGN(sizeof(struct cmsghdr)) + __MY_CMSG_ALIGN(l))
- 修改運行錯誤,文件libavutil/mem.c
變了了FFMpeg4.2.1之後,在運行的時候發現在libavutil/eval.c文件的av_expr_parse_and_eval這個函數裏面調用av_expr_free這個函數時,會在最後av_freep(&e);這句的時候發生錯誤(併產生coredump), 一開始我以爲是發生了內存越界,但是通過在這段內存的前後都加上16字節的空餘空間,在av_freep(&e);這句之前打印是否存在內存越界,結果是,並沒有發生內存越界,更奇妙的是,這樣做之後也不會發生錯誤了。 在網上搜索了一下,發現qnx下的posix_memalign 和memalign這兩個函數似乎有問題, 因此這裏需要修改一下av_malloc函數的實現:
void *av_malloc(size_t size)
{
void *ptr = NULL;
/* let's disallow possibly ambiguous cases */
if (size > (max_alloc_size - 32))
return NULL;
#if 0 /** 註釋掉原本的實現 */
#if HAVE_POSIX_MEMALIGN
if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
if (posix_memalign(&ptr, ALIGN, size))
ptr = NULL;
#elif HAVE_ALIGNED_MALLOC
ptr = _aligned_malloc(size, ALIGN);
#elif HAVE_MEMALIGN
#ifndef __DJGPP__
ptr = memalign(ALIGN, size);
#else
ptr = memalign(size, ALIGN);
#endif
/* Why 64?
* Indeed, we should align it:
* on 4 for 386
* on 16 for 486
* on 32 for 586, PPro - K6-III
* on 64 for K7 (maybe for P3 too).
* Because L1 and L2 caches are aligned on those values.
* But I don't want to code such logic here!
*/
/* Why 32?
* For AVX ASM. SSE / NEON needs only 16.
* Why not larger? Because I did not see a difference in benchmarks ...
*/
/* benchmarks with P3
* memalign(64) + 1 3071, 3051, 3032
* memalign(64) + 2 3051, 3032, 3041
* memalign(64) + 4 2911, 2896, 2915
* memalign(64) + 8 2545, 2554, 2550
* memalign(64) + 16 2543, 2572, 2563
* memalign(64) + 32 2546, 2545, 2571
* memalign(64) + 64 2570, 2533, 2558
*
* BTW, malloc seems to do 8-byte alignment by default here.
*/
#else
ptr = malloc(size);
#endif
#else /**使用普通的malloc來替代posix_memalign 或 memalign函數 */
ptr = malloc(size);
#endif /** */
if(!ptr && !size) {
size = 1;
ptr= av_malloc(1);
}
#if CONFIG_MEMORY_POISONING
if (ptr)
memset(ptr, FF_MEMORY_POISON, size);
#endif
return ptr;
-
編譯過程
make make install
5.2 準備gst-libav庫編譯腳本
- 編寫meson的cross file 文件qnx_arm.txt
[host_machine]
system = 'qnx'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'
[binaries]
c = 'arm-unknown-nto-qnx6.6.0eabi-gcc'
cpp = 'arm-unknown-nto-qnx6.6.0eabi-g++'
ar = 'arm-unknown-nto-qnx6.6.0eabi-ar'
strip = 'arm-unknown-nto-qnx6.6.0eabi-strip'
pkgconfig = 'pkg-config'
[properties]
c_args = ['-D_QNX_SOURCE=1']
c_link_args = ['-lsocket', '-L/media/guwen/workspace/project/gstreamer/out/lib',
'-lgobject-2.0', '-lgio-2.0', '-lgmodule-2.0', '-lffi']
cpp_args = ['-D_QNX_SOURCE=1']
cpp_link_args = ['-lsocket', '-L/media/guwen/workspace/project/gstreamer/out/lib',
'-lgobject-2.0', '-lgio-2.0', '-lgmodule-2.0', '-lffi']
[paths]
prefix = '/media/guwen/workspace/project/gstreamer/out'
- 修改meson.build文件
default_options : [ 'warning_level=1',
'buildtype=release' ]) #編譯 release版本
- 新增mp3 demuxer支持
我完成了所有編譯移植之後,原本想那個常見的音樂格式mp3文件進行測試,但發現,卻沒有找到支持mp3 格式的demuxer插件或元件。因此需要在gst-libav目錄裏面把對於mp3格式的支持放開。
- 新增mkv demuxer支持,
同樣,在進行視頻播放測試的時候,準備使用mkv格式的視頻進行播放,發現libgstmatroska.so這個插件,並不能支持我用於測試的常見的mkv文件,不知道爲什麼,於是就準備使用libav這個插件來進行支持。
最終對gstavdemux.c文件中的的 gboolean gst_ffmpegdemux_register (GstPlugin * plugin)函數的修改內容如下所示:
/* Don't use the typefind functions of formats for which we already have
* better typefind functions */
if (!strcmp (in_plugin->name, "mov,mp4,m4a,3gp,3g2,mj2") ||
!strcmp (in_plugin->name, "ass") ||
!strcmp (in_plugin->name, "avi") ||
!strcmp (in_plugin->name, "asf") ||
!strcmp (in_plugin->name, "mpegvideo") ||
/*!strcmp (in_plugin->name, "mp3") ||
!strcmp (in_plugin->name, "matroska") ||
!strcmp (in_plugin->name, "matroska_webm") ||
!strcmp (in_plugin->name, "matroska,webm") ||*/ //修改部分,放開mp3和mkv容器的限制
!strcmp (in_plugin->name, "mpeg") ||
!strcmp (in_plugin->name, "wav") ||
/////////////////////////////////////////////////////////////////////
!strcmp (in_plugin->name, "brstm") ||
!strcmp (in_plugin->name, "bfstm") ||
!strcmp (in_plugin->name, "gif") ||
!strcmp (in_plugin->name, "mp3") || /**新增mp3容器支持 */
!strcmp (in_plugin->name, "matroska") || /**新增mkv容器支持 */
!strcmp (in_plugin->name, "matroska_webm") || /**新增mkv容器支持 */
!strcmp (in_plugin->name, "matroska,webm") || /**新增mkv容器支持 */
!strcmp (in_plugin->name, "dsf") ||
!strcmp (in_plugin->name, "iff"))
- 另外,修正一個gstavdemux.c文件中的錯誤
準確的說應該是完善, 在gstavdemux.c文件中gst_ffmpegdemux_type_find函數中需要通過plugin name作爲fromat名稱,來生成對應的sink pad的 caps信息, 但是在使用libav中的mkv容器時, 其形式爲 “matroska,webm”, 這樣gst_ffmpeg_formatid_to_caps中生成的caps就會將這個名稱看出兩個字段 “matroska” 和“webm", 也爲了避免這個問題,需要像其他地方一樣使用 g_strdelimit來將 ‘,’ 之類的符號替換爲’_’。 其具體修改如下所示:
/** 原始代碼 */
sinkcaps = gst_ffmpeg_formatid_to_caps (in_plugin->name);
GST_LOG ("libav typefinder '%s' suggests %" GST_PTR_FORMAT ", p=%u%%",
in_plugin->name, sinkcaps, res);
gst_type_find_suggest (tf, res, sinkcaps);
gst_caps_unref (sinkcaps);
////////////////////////////////////////////////////////////////////////////
/** 修改後的代碼 */
gchar* format_name = g_strdup(in_plugin->name); /** dup一份plugin的名稱 */
g_strdelimit (format_name, ".,|-<> ", '_'); /** 將字符串中的 ',' 替換爲'_' */
sinkcaps = gst_ffmpeg_formatid_to_caps (format_name); /** 生成sink caps */
GST_LOG ("libav typefinder '%s' suggests %" GST_PTR_FORMAT ", p=%u%%",
in_plugin->name, sinkcaps, res);
gst_type_find_suggest (tf, res, sinkcaps);
gst_caps_unref (sinkcaps);
g_free(format_name); /** 使用完之後,釋放掉dup來的字符串 */
5.3 編譯
export PKG_CONFIG_LIBDIR=/media/guwen/workspace/project/gstreamer/out/lib/pkgconfig
mkdir build
cd build
meson .. --cross-file ../qnx_arm.txt
ninja
ninja install
六、總結
其實編譯出來的不少插件,這裏都是沒有用到的,如果要精細編譯的話,就需要針對這些插件庫進行細緻的配置,明確的指定enable項。
另外 對於meson編譯方式,其實原則上不應該去修改 meson.build文件, 應該視同meson -Dxxx=xxx的方式, 這裏其實可以使用和configure編譯方式一樣的做法, 將運行meson 命令相關的內容寫到一個shell腳本文件裏面去。這樣每個項目就只需要新增qnx_arm.txt 和一個類似myconfig.sh的shell腳本。