GStreamer插件实列rockchipmpp
尽管这些年arm发展取得了不少的进步,不过对于音视频的编解码仍然心有余力不足,好在芯片厂家在SOC里面提供了硬件加速能力。善于发挥出芯片的能力,才能打造出完美的应用.今天我们一起来探索一下rk3568上的为我们提供的多媒体加速能力-MPP,然后一起分析一下rk的gstreamer插件。
MPP
概述
- 视频解码
- 视频编码
- 视频处理
系统架构
![学新通 学新通](/static/whole/images/alert/data-load/load-15.gif)
- 硬件层 Hardware
- 内核驱动层 Kernel driver
- 操作系统层
- 应用层
MPI
![学新通 学新通](/static/whole/images/alert/data-load/load-15.gif)
![学新通 学新通](/static/whole/images/alert/data-load/load-15.gif)
rk gstreamer 插件
rockchipmpp是rk公司开发的一个在gstreamer插件,主要把自己的MPP和GStreamer,结合起来,我们在使用是可以直接把相关代码放到gstreamer源码中编译即可。
如下为它的源码
-
├── gstmppallocator.c
-
├── gstmppallocator.h
-
├── gstmppalphadecodebin.c
-
├── gstmppalphadecodebin.h
-
├── gstmpp.c
-
├── gstmppdec.c
-
├── gstmppdec.h
-
├── gstmppenc.c
-
├── gstmppenc.h
-
├── gstmpp.h
-
├── gstmpph264enc.c
-
├── gstmpph264enc.h
-
├── gstmpph265enc.c
-
├── gstmpph265enc.h
-
├── gstmppjpegdec.c
-
├── gstmppjpegdec.h
-
├── gstmppjpegenc.c
-
├── gstmppjpegenc.h
-
├── gstmppvideodec.c
-
├── gstmppvideodec.h
-
├── gstmppvp8enc.c
-
├── gstmppvp8enc.h
-
├── gstmppvpxalphadecodebin.c
-
├── gstmppvpxalphadecodebin.h
gstmpp.c为统一的入口文件,在它里面注册其他插件,gstmppjpegdec.c为jpeg的解码文件,我们能以他们为例子分析一下这个rockchip的mpp插件
gstreamer rkmpp 插件定义
如下为rkmpp的定义
-
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
-
GST_VERSION_MINOR,
-
rkmpp,
-
"Rockchip Mpp Video Plugin",
-
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
这个功能相当于面向对象语言的模板功能,由于C语言不支持模板功能,需要使用宏定义,来模拟模板功能,下面我们一起展开一下;
这个宏定义主要生成gst_plugin_desc结构和gst_plugin_rkmpp_get_desc,gst_plugin_rkmpp_register,来的分析,把部分宏找出来直接用gcc命令生产:
gcc -E -P gst-define.c > gst-define_m.c
大致代码如下
-
__attribute__ ((visibility ("default"))) const GstPluginDesc * gst_plugin_rkmpp_get_desc (void);
-
__attribute__ ((visibility ("default"))) void gst_plugin_rkmpp_register (void);
-
static const GstPluginDesc gst_plugin_desc = { GST_VERSION_MAJOR, GST_VERSION_MINOR, G_STRINGIFY(rkmpp), (gchar *) "Rockchip Mpp Video Plugin", plugin_init, VERSION, GST_LICENSE, PACKAGE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN, __GST_PACKAGE_RELEASE_DATETIME, GST_PADDING_INIT };
-
const GstPluginDesc * gst_plugin_rkmpp_get_desc (void)
-
{ return &gst_plugin_desc; }
-
void gst_plugin_rkmpp_register (void)
-
{ gst_plugin_register_static (GST_VERSION_MAJOR, GST_VERSION_MINOR, G_STRINGIFY(rkmpp), "Rockchip Mpp Video Plugin",
-
plugin_init, VERSION, GST_LICENSE, PACKAGE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
-
}
插件初始化
前奏
-
void
-
gst_init (int *argc, char **argv[])
-
{
-
GError *err = NULL;
-
-
if (!gst_init_check (argc, argv, &err)) {
-
g_print ("Could not initialize GStreamer: %s\n",
-
err ? err->message : "unknown error occurred");
-
if (err) {
-
g_error_free (err);
-
}
-
exit (1);
-
}
-
}
它的主要功能,
- 初始化GStreamer库
- 注册内部element
- 加载插件列表,扫描列表中及相应路径下的插件
- 解析并执行命令行参数
我们下面简单跟踪它的代码,重点看看怎么一步步加载插件的
gst_init
主要调用gst_init_check,这个函数如下所示
-
gboolean
-
gst_init_check (int *argc, char **argv[], GError ** err)
-
{
-
static GMutex init_lock;
-
#ifndef GST_DISABLE_OPTION_PARSING
-
GOptionGroup *group;
-
GOptionContext *ctx;
-
#endif
-
gboolean res;
-
-
g_mutex_lock (&init_lock);
-
-
if (gst_initialized) {
-
GST_DEBUG ("already initialized gst");
-
g_mutex_unlock (&init_lock);
-
return TRUE;
-
}
-
#ifndef GST_DISABLE_OPTION_PARSING
-
ctx = g_option_context_new ("- GStreamer initialization");
-
g_option_context_set_ignore_unknown_options (ctx, TRUE);
-
g_option_context_set_help_enabled (ctx, FALSE);
-
group = gst_init_get_option_group ();
-
g_option_context_add_group (ctx, group);
-
res = g_option_context_parse (ctx, argc, argv, err);
-
g_option_context_free (ctx);
-
#else
-
init_pre (NULL, NULL, NULL, NULL);
-
init_post (NULL, NULL, NULL, NULL);
-
res = TRUE;
-
#endif
-
-
gst_initialized = res;
-
-
g_mutex_unlock (&init_lock);
-
-
return res;
-
}
这个函数主要是先看看有没有初始化,没有的话,进行初始化。在初始化的时候也可以使用GOption来指定参数,之前已经提过,GOption数组来定义你的命令行选项将表与由gst_init_get_option_group函数返回的选项组一同传给GLib初始化函数。通过使用GOption表来初始化GSreamer,你的程序还可以解析除标准GStreamer选项以外的命令行选项。
这里重点是
-
group->pre_parse_func = pre_parse_func; init_pre
-
group->post_parse_func = post_parse_func; ///init_post
主要的工作是在init_post中完成,这里不准备详细介绍,着重说几点:
- 插件的加载并不是普通的动态库加载那样,而是形成一个plugin registry,这个registry主要记载插件的详细信息,在使用的时候方便调用
- 插件的加载使用父子进程方式,父进程收集和记录信息,子进程执行加载过程
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhiafgkg
-
微信小程序没声音怎么办
PHP中文网 06-15 -
excel图片置于文字下方的方法
PHP中文网 06-27 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
微信人名旁边有个图标有什么用
PHP中文网 03-11 -
微信提示登录环境异常是什么意思原因
PHP中文网 04-09 -
微信获取用户openid失败怎么办
PHP中文网 03-26 -
photoshop怎么把印章抠出并放在另一张图上
PHP中文网 06-15 -
EhViewer(E绅士)最新版_ehviewer白色版彩色版_Ehviewer显示网络错误怎么办?e站进不去了怎么办
Evanpatchouli 09-19 -
Excel筛选和排序是灰色的怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24