FFplay退出分析

FFmpeg 的社群来了,想加入微信社群的朋友请购买《FFmpeg原理》VIP版 电子书,里有更高级的内容与答疑服务。


当 FFplay播放器播放完一个 mp4 文件的时候,画面就会停止在最后一帧,并不会自动退出,如下:

有两种方式可以退出 FFplay 播放器。

1,在命令行使用 autoexit 参数,这是一个布尔参数,是没有值的,使用如下:

ffplay -autoexit -i juren.mp4

当指定了 autoexit 的时候,播放到结尾,FFplay 会自动退出。 如果不想自动退出,可以前面加上 no 前缀,如下:

ffplay -noautoexit -i juren.mp4

其实使不使用 noautoexit 参数都是一样的,因为这是默认值,默认不会自动退出。

这是 FFmpeg 整个项目布尔参数的习惯,如果要取反,就在前面加个 no

ffmpeg.exeffplay.exe ,ffprobe.exe 这些可执行文件的命令行布尔参数都是这样的。


还有另一种方法可以退出 FFplay 播放器,那就是按 Q 键,

先来看一下处理 Q 键 的代码,如下:

do_exit() 函数的实现如下:

do_exit() 函数实际上只有 两部分,调 stream_close() 跟 释放数据。后面的都是释放各种数据结构。流程图如下:

do_exit() 里面有两个变量的使用是特别重要的,会连环影响几个地方的逻辑。

1,is->abort_request

2,q->abort_request

q->abort_request 跟 is->abort_request 其实是一样的,都是会在退出播放器的时候置为1,只是为了方便调用,所以在 PacketQueue 里面也加了同样的字段 abort_request 。


先来看一下用到 is->abort_request 的地方,如下:

可以看到,当 is->abort_request 为 1 的时候,就会跳出 for 死循环,然后 read_thread 线程自然就结束了。

还有一个地方也会用到 is->abort_request ,那就是 decode_interrupt_cb() ,这个是封装层的回调函数。

static int decode_interrupt_cb(void *ctx)
{
    VideoState *is = ctx;
    return is->abort_request;
}

在播放网络流的时候,网络卡顿,av_read_frame() 可能要 8 秒才能返回,这时候如果想关闭播放器,就需要 av_read_frame() 尽快地返回,不要再阻塞了。这时候,就需要 interrupt_callback 了,因为在 8 秒 内,av_read_frame() 内部也会定时执行 interrupt_callback(),只要 interrupt_callback() 返回 1,av_read_frame() 就会不再阻塞,立即返回。

提醒:播放网络流的时候,avformat_find_stream_info() 可能会跟 av_read_frame() 一样阻塞很久。


接下来看一下用到 q->abort_request 的地方,如下:

可以看到有 11 个地方用到这个 q->abort_request 。

这 11 个地方比较繁琐,主要的作用就是让解码线程跳出死循环循环,然后退出。


stream_component_close() 里面的 decoder_abort() 函数也比较重要,就是把 q->abort_request 设置为 1,然后通过 cond 唤醒各个线程,各个线程发现 q->abort_request 为 1,就会自觉退出。

static void decoder_abort(Decoder *d, FrameQueue *fq)
{
    packet_queue_abort(d->queue);
    frame_queue_signal(fq);
    SDL_WaitThread(d->decoder_tid, NULL);
    d->decoder_tid = NULL;
    packet_queue_flush(d->queue);
}

FFplay 播放器退出处理分析完毕。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loken2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值