在gstreamer中做线程同步

在gstreamer中做线程同步,这里分别用到了C++ condition_variable和glib的GCond和GMutex做线程同步,C++代码用在外部代码,glib的用法用在pipeline的代码中。

C++ condition_variable的背景知识

使用条件变量condition_variable做线程同步,可用于阻止一个线程或同时阻止多个线程,直到另一个线程修改共享变量(condition),并通知condition_variable,才会继续执行。

当调用它的wait函数时,它使用一个mutex来锁定线程。使得该线程保持阻塞状态,直到被另一个线程调用同一个condition_variable对象上的notify函数才被唤醒。

condition_variable类型的对象必须使用unique_lock等待。

  • wait 阻塞当前线程,直到notify_all()或notify_one()被执行。
  • wait_for 阻塞当前线程,直到条件变量被唤醒或在指定的超时持续时间之后。
  • wait_until 阻塞当前线程,直到唤醒条件变量或到达指定的时间点。

condition_variable的代码实例

本例中,ctrl+c的时候退出程序,所以下面signal_andler回调时,执行notify_all()

注册signal_andler:

static std::mutex srv_mtx;
static std::condition_variable srv_cv;

struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = signal_andler;
sigfillset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);

notify_all:



void signal_andler(int sig) {
  std::unique_lock<std::mutex> lock(srv_mtx);
  server_exit = 1;
  srv_cv.notify_all();
}

wait的代码:

  std::unique_lock<std::mutex> lock(srv_mtx);
  while (!server_exit) {
    printf("waiting ...\n");
    srv_cv.wait(lock);
    printf("done.\n");
  }

gstreamer mainloop的同步

在gstreamer pipeline中,mainloop在执行了g_main_loop_quit()之后,mainloop就会退出,所以需要对mainloop线程进行同步,释放thread资源。

定义GCond和GMutex:

  GCond main_loop_cond;
  GMutex main_loop_mutex;

  g_mutex_init(&main_loop_mutex);
  g_cond_init(&main_loop_cond);

如下,在g_main_loop_run()之后,lock之后修改main_loop_,broadcast之后然后释放锁:

  g_main_loop_run(player->main_loop_);

  g_mutex_lock(&player->main_loop_mutex);
  g_main_context_unref(player->context_);
  g_main_loop_unref(player->main_loop_);
  player->context_ = nullptr;
  player->main_loop_ = nullptr;
  g_cond_broadcast(&player->main_loop_cond);
  g_mutex_unlock(&player->main_loop_mutex);

在主线程,等待main_loop_的状态变化:

  gint64 end_time = g_get_monotonic_time () + 10 * G_TIME_SPAN_MILLISECOND;
  g_mutex_lock(&main_loop_mutex);
  while (main_loop_) {
    g_cond_wait_until(&main_loop_cond, &main_loop_mutex, end_time);
  }
  g_mutex_unlock(&main_loop_mutex);

  g_thread_unref(thread_);
  thread_ = nullptr;

或者是g_cond_wait,不带超时:

  g_mutex_lock(&main_loop_mutex);
  while (main_loop_) {
    g_cond_wait(&main_loop_cond, &main_loop_mutex);
  }
  g_mutex_unlock(&main_loop_mutex);

  g_thread_unref(thread_);
  thread_ = nullptr;

参考

std::condition_variable::wait

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GStreamer 是一个开源的多媒体框架,可以在 Java 使用。以下是在 Java 使用 GStreamer 的步骤: 1. 安装 GStreamer 在安装 GStreamer 之前,需要先安装以下依赖库: - libgstreamer-plugins-base1.0-dev - libgstreamer1.0-dev - libgstreamer-plugins-good1.0-dev - libgstreamer-plugins-bad1.0-dev 安装完依赖库后,可以通过以下命令安装 GStreamer: ``` sudo apt-get install gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav ``` 2. 引入 GStreamer 的 Java 绑定库 GStreamer 的 Java 绑定库在 Maven 是可用的,可以在项目的 pom.xml 文件添加以下依赖项: ``` <dependency> <groupId>org.freedesktop.gstreamer</groupId> <artifactId>gstreamer-java</artifactId> <version>1.14.4</version> </dependency> ``` 3. 编写 GStreamer 的 Java 代码 以下是一个简单的 GStreamer Java 代码示例,它使用 GStreamer 播放一个视频: ``` import org.freedesktop.gstreamer.*; public class GStreamerExample { public static void main(String[] args) { Gst.init("VideoPlayer", args); Pipeline pipe = new Pipeline(); Element source = ElementFactory.make("filesrc", "source"); source.set("location", "/path/to/video.mp4"); Element decoder = ElementFactory.make("decodebin", "decoder"); Element convert = ElementFactory.make("videoconvert", "convert"); Element sink = ElementFactory.make("autovideosink", "sink"); pipe.addMany(source, decoder, convert, sink); Pipeline.linkMany(source, decoder); decoder.link(convert); convert.link(sink); pipe.play(); Gst.main(); } } ``` 以上代码使用 GStreamer 创建了一个管道(pipeline),其包含一个文件源(filesrc)、一个解码器(decodebin)、一个视频转换器(videoconvert)和一个视频输出端(autovideosink)。它将视频源(/path/to/video.mp4)连接到解码器,解码器连接到转换器,转换器连接到视频输出端。最后,它启动了管道并进入 GStreamer 的主循环。 以上就是在 Java 使用 GStreamer 的简单步骤和示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值