Gstreamer基础教程13:Playback Speed

本文是Gstreamer基础教程的一部分,主要讲解如何使用Seek Events和Step Events来改变播放速度,包括快进、倒放、慢动作以及逐帧推进视频的操作。通过创建和发送事件到pipeline,实现播放速率的调整,同时讨论了不同速率事件对pipeline的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Goal

快进、倒放和慢动作都是所谓的技巧模式,它们都有修改正常播放速率的共同之处。本教程展示了如何实现这些效果,并在处理中添加frame-stepping。特别是,它显示

  • 如何改变播放速率,比正常速度快或慢,向前或向后
  • 如何逐帧推进视频

2.介绍

快进是一种以高于正常(预期)速度播放媒体的技术;而慢动作使用的速度低于预期的速度。反向回放做同样的事情,只是向后,从流的结尾到开始。
所有这些技术所做的就是改变播放速率,对于正常播放,它是一个等于1.0的变量,对于快速播放,它大于1.0(绝对值),对于慢速播放,它小于1.0(绝对值)。正向播放是正的,反向播放是负的。
Gstreamer提供了两种机制来更改回放速率:Step Events和Seek Events。Step Events除了更改后续的播放速率(仅为正值)也允许跳过给定数量的媒体。Seek Events允许跳到流中的任何位置,并设置正播放率和负播放率。
在基础教程4:时间管理搜索事件中,已经显示了时间,使用辅助函数来隐藏事件的复杂性。本教程将进一步说明如何使用这些事件。
Step Events是改变回放速率的一种更方便的方式,因此创建它们所需的参数数量减少了,然而,它们也有一些缺点,因此在本教程中使用Seek Events。Step Events只会影响sink(在pipeline的尾端),所以只有当pipeline的其余部分能够支持以不同的速度运行时。它们才会起作用,而Seek Events会贯穿整个pipeline,以便每个elements都能对它们做出反应。Step Events的好处是它们可以更快的采取行动。Step Events也无法更改回放的方向。
要使用这些事件,首先要创建它们,然后将它们传递到pipeline上,在pipeline中向上传播,直到到达可以处理它们的elements。如果一个事件被传递到像playbin这样的bin元素上,它将简单地将事件提供给所有sink,这将执行多个查找。常见的方法是通过video-sink或audio-sink检索playbin的sink,并将事件直接提供给sink。
Frame stepping是一种允许逐帧播放视频的技术。它是通过暂停pipeline来实现的,然后每次发送Step Events跳过一帧。

3. A Trick mode player

3.1 Compile

gcc basic-tutorial-13.c -o basic-tutorial-13 `pkg-config --cflags --libs gstreamer-1.0`

3.2 Code

#include <string.h>
#include <stdio.h>
#include <gst/gst.h>

typedef struct _CustomData
{
   
  GstElement *pipeline;
  GstElement *video_sink;
  GMainLoop *loop;

  gboolean playing;             /* Playing or Paused */
  gdouble rate;                 /* Current playback rate (can be negative) */
} CustomData;

/* Send seek event to change rate */
static void
send_seek_event (CustomData * data)
{
   
  gint64 position;
  GstEvent *seek_event;

  /* Obtain the current position, needed for the seek event */
  if (!gst_element_query_position (data->pipeline, GST_FORMAT_TIME, &position)) {
   
    g_printerr ("Unable to retrieve current position.\n");
    return;
  }

  /* Create the seek event */
  if (data->rate > 0) {
   
    seek_event =
        gst_event_new_seek (data->rate, GST_FORMAT_TIME,
        GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET,
        position, GST_SEEK_TYPE_END, 0);
  } else {
   
    seek_event =
        gst_event_new_seek (data->rate, GST_FORMAT_TIME,
        GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, 0,
        GST_SEEK_TYPE_SET, position);
  }

  if (data->video_sink == NULL) {
   
    /* If we have not done so, obtain the sink through which we will send the seek events */
    g_object_get (data->pipeline, "video-sink", &data->video_sink, NULL);
  }

  /* Send the event */
  gst_element_send_event (data->video_sink, seek_event);

  g_print ("Current rate: %g\n", data->rate);
}

/* Process keyboar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值