六、基于FFmpeg和SDL的视频播放器(快进和暂停)

快进功能的实现主要通过使用av_seek_frame函数来实现快进的功能

一、函数原型

int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
                  int flags);

二、参数解释

AVFormatContext *s        解码的格式上下文
int stream_index          对应的数据流
int64_t timestamp         时间戳,单位为TIMEBASE(需要手动转换)
int flags                 标志位
/***********标志位参数************/
AVSEEK_FLAG_BACKWARD = 1 往后找
AVSEEK_FLAG_BYTE = 2  按照字节来移动位置
AVSEEK_FLAG_ANY = 4 针对frame来说的,就跳转那一帧,不找关键帧
AVSEEK_FLAG_FRAME = 8 表示往后找,找到关键帧
flags是二进制表示的,可以同时取2个,用或来操作。‘|’

三、代码实现

void VideoPlayer::seek(double T)
{
	av_seek_frame(pFormatCtx, indexAudio, (T + ptsAudio / 1000) / av_q2d(pAudioCodeCtx->time_base), AVSEEK_FLAG_BACKWARD);
}

只需一行代码就可以实现我们想要的功能了,但是由于我们使用了缓存,导致视频的调转并不是立即执行的,它会先显示完缓存中packet包后才开始跳转,所以我们需要清除队列中缓存

四、清除队列

void PacketQueue::initQueue()
{
	AVPacketList *pkt, *pkt1;

	SDL_LockMutex(mutex);
	if (nb_packets == capacity)
	{
		SDL_CondSignal(full);
	}
	for (pkt = first_pkt; pkt != NULL; pkt = pkt1) {
		pkt1 = pkt->next;
		av_free_packet(&pkt->pkt);
		av_freep(&pkt);
	}
	last_pkt = NULL;
	first_pkt = NULL;
	nb_packets = 0;
	size = 0;
	SDL_UnlockMutex(mutex);
}

由于清除队列的时候会存在,队列中继续读取数据与插入数据的情况,所以我们需要设置标记,还暂停那些对队列的操作

void VideoPlayer::seek(double T)
{
	bStop = TRUE;
	SDL_PauseAudio(1);
	qAudio->initQueue();
	qVideo->initQueue();
	av_seek_frame(pFormatCtx, indexAudio, (T + ptsAudio / 1000) / av_q2d(pAudioCodeCtx->time_base), AVSEEK_FLAG_BACKWARD);
	bStop = FALSE;
	SDL_PauseAudio(0);
}


五、视频暂停

通过上述的标志位实现读取,显示线程的暂停

注意:需要暂停音频SDL_PauseAudio(1);

void VideoPlayer::stop()
{
	bStop = !bStop;
	if (bStop)
	{
		SDL_PauseAudio(1);
	}
	else
	{
		SDL_PauseAudio(0);
	}
}

参考代码:https://github.com/ZhouHanyu18/SimplePlayer

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值