当前位置:网站首页>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而不造成死锁。在这样做的时候,必须注意在递归互斥被锁定的时候解锁它。
边栏推荐
- 手机股票开户安全吗?靠不靠谱啊?
- 【FAQ】华为帐号服务报错 907135701的常见原因总结和解决方法
- Ultrasonic ranging based on FPGA
- Password reset of MariaDB root user and ordinary user
- IBM has laid off 40 + year-old employees in a large area. Mastering these ten search skills will improve your work efficiency ten times
- Reflection and imagination on the notation like tool
- 【obs】QString的UTF-8中文转换到blog打印 UTF-8 char*
- Go语言 | 01 WSL+VSCode环境搭建避坑指南
- 集合
- Go语言 | 02 for循环及常用函数的使用
猜你喜欢
力扣 729. 我的日程安排表 I
完爆面试官,一线互联网企业高级Android工程师面试题大全
Mariadb root用户及普通用户的密码 重置
IFD-x 微型红外成像仪(模块)关于温度测量和成像精度的关系
大厂面试必备技能,2022Android不死我不倒
[OBS] qstring's UTF-8 Chinese conversion to blog printing UTF-8 char*
What is the core value of testing?
集合
使用 RepositoryProvider简化父子组件的传值
Notion 类生产力工具如何选择?Notion 、FlowUs 、Wolai 对比评测
随机推荐
[performance test] jmeter+grafana+influxdb deployment practice
Fuzor 2020软件安装包下载及安装教程
Decision tree and random forest
S7-200SMART利用V90 MODBUS通信控制库控制V90伺服的具体方法和步骤
不愧是大佬,字节大牛耗时八个月又一力作
That's awesome. It's enough to read this article
UWB超宽带定位技术,实时厘米级高精度定位应用,超宽带传输技术
Teach you to deal with JS reverse picture camouflage hand in hand
The problem of returning the longtext field in MySQL and its solution
Reflection and imagination on the notation like tool
Go语言 | 03 数组、指针、切片用法
详解SQL中Groupings Sets 语句的功能和底层实现逻辑
通过POI追加数据到excel中小案例
JAD的安装、配置及集成IDEA
Pandora IOT development board learning (HAL Library) - Experiment 8 timer interrupt experiment (learning notes)
Apprentissage du projet MMO I: préchauffage
#夏日挑战赛#数据库学霸笔记,考试/面试快速复习~
Fundamentals of shell programming (Chapter 9: loop)
国海证券在网上开户安全吗?
众昂矿业:2022年全球萤石行业市场供给现状分析