一、環境
i.MX6平臺+gstreamer。
二、實現
封裝3個函數,play_fast_forward、play_fast_reverse、play_normal_speed
分別對應快進、快退、正常播放。
gstreamer使用playbin管道。
1、play_fast_forward
void play_fast_forward(GstElement *playbin_em)
{
int64_t pos = 0;
gboolean ret = gst_element_query_position(playbin_em,GST_FORMAT_TIME,&pos);
if (0 == ret)
{
printf("gst_element_query_position fail\n");
return;
}
printf("get pos=%lld\n",pos);
gint64 duration = 0;
ret = gst_element_query_duration(playbin_em,GST_FORMAT_TIME,&duration);
if (0 == ret)
{
printf("gst_element_query_duration fail\n");
return;
}
printf("get duration=%lld\n",duration);
ret = gst_element_seek(playbin_em,4.0,GST_FORMAT_TIME,
GST_SEEK_FLAG_FLUSH |GST_SEEK_FLAG_KEY_UNIT,
GST_SEEK_TYPE_SET,
pos,
GST_SEEK_TYPE_SET,
duration);
if (0 == ret)
{
printf("play_fast_forward fail\n");
}
else
{
printf("play_fast_forward succ\n");
}
}
2、play_fast_reverse
void play_fast_reverse(GstElement *playbin_em)
{
gint64 pos = 0;
gboolean ret = gst_element_query_position(playbin_em,GST_FORMAT_TIME,&pos);
if (0 == ret)
{
printf("gst_element_query_position fail\n");
return;
}
printf("get pos=%lld\n",pos);
ret = gst_element_seek(playbin_em,-4.0,GST_FORMAT_TIME,
GST_SEEK_FLAG_FLUSH |GST_SEEK_FLAG_KEY_UNIT,
GST_SEEK_TYPE_SET,
0*GST_SECOND,
GST_SEEK_TYPE_SET,
pos);
if (0 == ret)
{
printf("play_fast_reverse fail\n");
}
else
{
printf("play_fast_reverse succ\n");
}
}
3、 play_normal_speed
void play_normal_speed(GstElement *playbin_em)
{
gint64 pos = 0;
gboolean ret = gst_element_query_position(playbin_em,GST_FORMAT_TIME,&pos);
if (0 == ret)
{
printf("gst_element_query_position fail\n");
return;
}
printf("get pos=%lld\n",pos);
gint64 duration = 0;
ret = gst_element_query_duration(playbin_em,GST_FORMAT_TIME,&duration);
if (0 == ret)
{
printf("gst_element_query_duration fail\n");
return;
}
printf("get duration=%lld\n",duration);
ret = gst_element_seek(playbin_em,1.0,GST_FORMAT_TIME,
GST_SEEK_FLAG_FLUSH |GST_SEEK_FLAG_KEY_UNIT,
GST_SEEK_TYPE_SET,
pos,
GST_SEEK_TYPE_SET,
duration);
if (0 == ret)
{
printf("play_normal_speed fail\n");
}
else
{
printf("play_normal_speed succ\n");
}
}
三、原理
使用gstreamer的事件機制。
gst_element_query_position和gst_element_query_duration可以得到當前播放的位置以及視頻的總時長,單位秒。
gst_element_seek是實現倍速播放的關鍵,我們看下函數聲明,
gboolean gst_element_seek (GstElement *element, gdouble rate,
GstFormat format, GstSeekFlags flags,
GstSeekType start_type, gint64 start,
GstSeekType stop_type, gint64 stop);
rate是播放速率,1.0是1倍速,即正常播放,4.0是4倍速,-4.0是快退4倍速。
start_type和stop_type是指後面緊跟的start和stop採用相對時間還是絕對時間,我們使用絕對時間GST_SEEK_TYPE_SET。
/**
* GstSeekType:
* @GST_SEEK_TYPE_NONE: no change in position is required
* @GST_SEEK_TYPE_SET: absolute position is requested
* @GST_SEEK_TYPE_END: relative position to duration is requested
*
* The different types of seek events. When constructing a seek event with
* gst_event_new_seek() or when doing gst_segment_do_seek ().
*/
typedef enum {
/* one of these */
GST_SEEK_TYPE_NONE = 0,
GST_SEEK_TYPE_SET = 1,
GST_SEEK_TYPE_END = 2
} GstSeekType;
start和stop永遠遵守start<stop的原則,這點在快退播放時也是如此。