当前位置:网站首页>Gstreamer中的task
Gstreamer中的task
2022-07-05 19:34:00 【HUI的技術筆記】
在gstreamer中,可以在需要的时候方便的创建一个task作为独立线程,task可以是普通的task,也可以是pad task,这个需要根据具体需求来定,下面先看下v4l2和avdemux里面task的代码。
task的创建
gst-plugins-good/sys/v4l2/gstv4l2videodec.c
通过gst_pad_start_task开始一个pad task
,task函数是gst_v4l2_video_dec_loop。作用是启动v4l2的解码task,并且当task退出时,将禁用输入处理以在drain时unlock输入,防止阻塞:
/* start task */
if (!gst_pad_start_task (decoder->srcpad, (GstTaskFunction) gst_v4l2_video_dec_loop, self, NULL))
goto start_task_failed;
gst-libav/ext/libav/gstavdemux.c
创建一个demux->task,task函数是gst_ffmpegdemux_loop,gst_task_init会通过gst_task_new间接调用,在init函数中调用ensure_klass_pool确保_global_task_pool
的线程池可用,start_task的时候将task通过gst_task_pool_push放到task的线程池里面,下面gst_pad_start_task的调用栈就可以看到。
/* static GstTaskPool *_global_task_pool = NULL; */
/* new task */
demux->task = gst_task_new ((GstTaskFunction) gst_ffmpegdemux_loop, demux, NULL);
g_rec_mutex_init (&demux->task_lock);
/* set lock */
gst_task_set_lock (demux->task, &demux->task_lock);
gst_ffmpegdemux_loop和gst_v4l2_video_dec_loop两个函数是task的loop函数,在gstreamer中,task不像pthread的中的task,需要有一个循环来保证常驻task一直存在。而是通过前面的线程池来运行。
task的运行
看gst_pad_start_task的代码和栈就可以清楚的看到task的new,init,start都是在gst_pad_start_task里面实现的,这些在如果不是通过gst_pad_start_task启动的task,都需要手动调用。
1 gst_task_init gsttask.c 249 0x7ffff7b49fa3
2 g_type_create_instance 0x7ffff75559c5
4 g_object_new_with_properties 0x7ffff7537ee5
5 g_object_new 0x7ffff7538961
6 gst_task_new gsttask.c 482 0x7ffff7b4a5ad
7 gst_pad_start_task gstpad.c 6287 0x7ffff7b1d7fe
调用start_task的栈:
1 gst_task_pool_push gsttaskpool.c 252 0x7ffff7b4b820
2 start_task gsttask.c 712 0x7ffff7b49f19
3 gst_task_set_state_unlocked gsttask.c 744 0x7ffff7b4ad3e
4 gst_task_set_state gsttask.c 792 0x7ffff7b4ad3e
7 gst_pad_start_task gstpad.c 6287 0x7ffff7b1d7fe
gst_task_pool_push
是在start_task函数中调用的,将task放到线程池里面,指定taskpool函数为gst_task_func
:
/* push on the thread pool, we remember the original pool because the user * could change it later on and then we join to the wrong pool. */
priv->pool_id = gst_object_ref (priv->pool);
priv->id =
gst_task_pool_push (priv->pool_id, (GstTaskPoolFunction) gst_task_func,
task, &error);
gst_task_pool_push中继续调用GstTaskPoolClass的push函数default_push
,在default_push函数中会调用g_thread_pool_push函数放到g_thread_pool里面,后面task的运行就是GLib的g_thread_pool相关的实现了。
gpointer
gst_task_pool_push (GstTaskPool * pool, GstTaskPoolFunction func,
gpointer user_data, GError ** error)
{
GstTaskPoolClass *klass;
g_return_val_if_fail (GST_IS_TASK_POOL (pool), NULL);
klass = GST_TASK_POOL_GET_CLASS (pool);
if (klass->push == NULL)
goto not_supported;
/* gsttaskpool_class->push = default_push; */
return klass->push (pool, func, user_data, error);
}
注意:task不允许没有lock而使用,否则会报错:
task without a lock can't be set to state 0
通过gst_task_set_lock函数原型可以看到,这里task需要的lock是GRecMutex类型。
下面代码是curlhttpsrc的代码,可以有个初步的认识:
subprojects/gst-plugins-bad/ext/curl/gstcurlhttpsrc.c
/* init RecMutex */
g_rec_mutex_init (&klass->multi_task_context.task_rec_mutex);
klass->multi_task_context.state = GSTCURL_MULTI_LOOP_STATE_RUNNING;
/* new task */
klass->multi_task_context.task = gst_task_new (
(GstTaskFunction) gst_curl_http_src_curl_multi_loop,
(gpointer) & klass->multi_task_context, NULL);
/* set lock */
gst_task_set_lock (klass->multi_task_context.task,
&klass->multi_task_context.task_rec_mutex);
/* start task */
if (gst_task_start (klass->multi_task_context.task) == FALSE) {
GSTCURL_ERROR_PRINT ("Couldn't start curl_multi task! Aborting.");
abort ();
}
GMutex
GMutex结构是一个不透明的数据结构,代表一个互斥量(mutex),它可以用来保护数据免受共享访问。
GRecMutex
GRecMutex结构是一个不透明的数据结构,代表一个递归互斥。它类似于GMutex,不同的是,它可以在同一线程中多次锁定GRecMutex而不造成死锁。在这样做的时候,必须注意在递归互斥被锁定的时候解锁它。
边栏推荐
- Common - Hero Minesweeper
- 测试外包公司怎么样?
- Oracle故障处理:Ora-10873:file * needs to be either taken out of backup or media recovered
- 【obs】libobs-winrt :CreateDispatcherQueueController
- The basic grammatical structure of C language
- 软件测试是干什么的?学习有啥要求?
- UWB ultra wideband positioning technology, real-time centimeter level high-precision positioning application, ultra wideband transmission technology
- PG basics -- Logical Structure Management (user and permission management)
- How about testing outsourcing companies?
- Advanced application of C # language
猜你喜欢
测试的核心价值到底是什么?
acm入门day1
[Collection - industry solutions] how to build a high-performance data acceleration and data editing platform
How to convert word into PDF? Word to PDF simple way to share!
【FAQ】华为帐号服务报错 907135701的常见原因总结和解决方法
The problem of returning the longtext field in MySQL and its solution
Summer Challenge database Xueba notes, quick review of exams / interviews~
UWB超宽带定位技术,实时厘米级高精度定位应用,超宽带传输技术
完爆面试官,一线互联网企业高级Android工程师面试题大全
Millimeter wave radar human body sensor, intelligent perception of static presence, human presence detection application
随机推荐
【AI 框架基础技术】自动求导机制 (Autograd)
IBM大面积辞退40岁+的员工,掌握这十个搜索技巧让你的工作效率至上提高十倍
The binary string mode is displayed after the value with the field type of longtext in MySQL is exported
测试的核心价值到底是什么?
MMO項目學習一:預熱
[FAQ] summary of common causes and solutions of Huawei account service error 907135701
aggregate
力扣 1200. 最小绝对差
How to apply smart contracts more wisely in 2022?
2022 the latest big company Android interview real problem analysis, Android development will be able to technology
Decision tree and random forest
C#应用程序界面开发基础——窗体控制(5)——分组类控件
如何在2022年更明智地应用智能合约?
[AI framework basic technology] automatic derivation mechanism (autograd)
Mysql如何对json数据进行查询及修改
Postman core function analysis - parameterization and test report
软件测试工程师是做什么的?待遇前景怎么样?
HiEngine:可媲美本地的云原生内存数据库引擎
vagrant2.2.6支持virtualbox6.1版本
Go语言 | 01 WSL+VSCode环境搭建避坑指南