尽管这些年arm发展取得了不少的进步,不过对于音视频的编解码仍然心有余力不足,好在芯片厂家在SOC里面提供了硬件加速能力。善于发挥出芯片的能力,才能打造出完美的应用.今天我们一起来探索一下rk3568上的为我们提供的多媒体加速能力-MPP,然后一起分析一下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插件
如下为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语言不支持模板功能,需要使用宏定义,来模拟模板功能,下面我们一起展开一下;
#ifdef __cplusplus
#define G_BEGIN_DECLS extern "C" {
#define G_END_DECLS }
#else
#define G_BEGIN_DECLS
#define G_END_DECLS
#endif
#if (0 || defined(_MSC_VER)) && !defined(GST_STATIC_COMPILATION)
# define GST_PLUGIN_EXPORT __declspec(dllexport)
# ifdef GST_EXPORTS
# define GST_EXPORT __declspec(dllexport)
# else
# define GST_EXPORT __declspec(dllimport) extern
# endif
#else
# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define GST_PLUGIN_EXPORT __attribute__ ((visibility ("default")))
# define GST_EXPORT extern __attribute__ ((visibility ("default")))
# else
# define GST_PLUGIN_EXPORT
# define GST_EXPORT extern
# endif
#endif
#define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2
#define G_PASTE(identifier1,identifier2) G_PASTE_ARGS (identifier1, identifier2)
#define GST_PLUGIN_DEFINE(major,minor,name,description,init,version,license,package,origin) \
G_BEGIN_DECLS \
GST_PLUGIN_EXPORT const GstPluginDesc * G_PASTE(gst_plugin_, G_PASTE(name, _get_desc)) (void); \
GST_PLUGIN_EXPORT void G_PASTE(gst_plugin_, G_PASTE(name, _register)) (void); \
\
static const GstPluginDesc gst_plugin_desc = { \
major, \
minor, \
G_STRINGIFY(name), \
(gchar *) description, \
init, \
version, \
license, \
PACKAGE, \
package, \
origin, \
__GST_PACKAGE_RELEASE_DATETIME, \
GST_PADDING_INIT \
}; \
\
const GstPluginDesc * \
G_PASTE(gst_plugin_, G_PASTE(name, _get_desc)) (void) \
{ \
return &gst_plugin_desc; \
} \
\
void \
G_PASTE(gst_plugin_, G_PASTE(name, _register)) (void) \
{ \
gst_plugin_register_static (major, minor, G_STRINGIFY(name), \
description, init, version, license, \
PACKAGE, package, origin); \
} \
G_END_DECLS
这个宏定义主要生成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);
}
我们在编写一个GStreamer应用_专注&突破的博客-CSDN博客开始的时候说过编写gstreamer应用首先使用gst_init 初始化
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);
}
}
它的主要功能,
我们下面简单跟踪它的代码,重点看看怎么一步步加载插件的
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中完成,这里不准备详细介绍,着重说几点:
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
您认为可以作为插件很好地存在于您的Rails应用程序中必须实现的哪些行为?您过去曾搜索过哪些插件功能但找不到?哪些现有的Rails插件可以改进或扩展,如何改进或扩展? 最佳答案 我希望在管理界面中看到一个引擎插件,它提供了应用程序中所有模型的仪表板摘要,以及可配置的事件图表。 关于ruby-on-rails-您希望看到哪些Rails插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questio
我们正在使用Vagrant进行部署,我们最终希望将此集群部署在Rackspace上。vagrant-rackspace插件是一个自然的选择,但它有一些错误,这些错误未包含在最新的0.1.1版本中(notablythatvagrantprovisiondoesn'twork)。我已经在我的personalfork中解决了这个问题通过合并其他人的工作来对存储库进行改造。是否可以从github安装vagrant插件?显而易见的事情没有奏效:[unix]$vagrantplugininstallvagrant-rackspace--plugin-sourcehttps://github.com
前言我们习惯用idea编写、调试代码,在LeetCode上刷题时,如果能够在IDEA编写代码,并且做好代码管理,是一件事半功倍的事情。对于后续复习题目,做笔记也会非常便利。本文目的在于介绍LeetCodeEditor的使用,以及配置工具类,最终目录结构如下:note:放置笔记src:放置代码leetcode.editor.cn:插件LeetCodeEditor自动生成utils:自定义的工具包,可用于自动化输入测试用例,定义题目需要的类(结构体)out:运行测试时自动生成LeetCodeEditorGitHub:https://github.com/shuzijun/leetcode-edit
多年来,Perl一直是我首选的编程语言工具之一。Perl6语法看起来像是一个很棒的语言特性。我想知道是否有人开始为Ruby做这样的事情。 最佳答案 如果您想在Ruby中使用实际的Perl6语法,最好的选择是Cardinal,Parrot上的ruby编译器。它目前尚未完成并且非常缓慢,但我非常希望它最终成为一个可行的ruby实现。它目前大部分处于非事件状态,等待Parrot中的一些基础架构更改以支持改进的解析速度和其他功能。 关于regex-Ruby是否有类似于Perl6语法的插件
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion我正在为Rails3/ActiveRecord项目寻找一个相对简单的状态机插件。我做了一些研究并提出了以下插件:转换:https://github.com/qoobaa/transitions从旧的ActiveRecord状态机库中提取
我在引擎样式插件中有一些代码,其中包含一些模型。在我的应用程序中,我想扩展其中一个模型。通过在初始值设定项中包含一个模块,我已经设法将实例和类方法添加到相关模型中。但是我似乎无法添加关联、回调等。我收到“找不到方法”错误。/libs/qwerty/core.rbmoduleQwertymoduleCoremoduleExtensionsmoduleUser#InstanceMethodsGoHere#ClassMethodsmoduleClassMethodshas_many:hits,:uniq=>true#nomethodfoundbefore_validation_on_crea
是否有一个SASS扩展可以采用SASS样式表,找到中性属性(例如border-radius)并为其输出所有特定于供应商的属性(例如-webkit-border-radius等)自动?我真的不想手动创建所有混入,也不想手动编写代码。我确定一定有这样的扩展名,但我找不到它。帮忙? 最佳答案 有一个非常好的gem可以满足您的需求。它叫做Bourbon它不会用特定于供应商的css替换您的css,因为它可以像SASS一样工作。它基本上是一个正确生成跨浏览器css的mixin集合。 关于ruby-用
我使用vim编辑ruby文件,但是当我输入“.”时它崩溃了。我发现它是由AutoComplPop插件引起的。我该怎么办? 最佳答案 我找到了一种使用autocomplpop和filetype=ruby来防止vim崩溃的方法。将以下行放入您的.vimrcletg:acp_behaviorRubyOmniMethodLength=-1这将防止在您键入“.”时触发autocomplpop。(期间)这不是解决办法。(我不是vim插件程序员)祝你好运! 关于ruby-vim使用AutoComp