ffplay源码_read_thread线程分析(三)

前言

FFplay是 FFmpeg 官方提供的一个播放器的实现,支持快进快退,逐帧播放,滤镜等。本文是在VS2017的Debug x86模式下调试运行的,ffplay.c移植到VS2017工程可以参考
win10环境下msys2+vs2017编译ffmpeg(32位含ffplay移植)_ffmpeg3 vs2017编译-优快云博客

read_thread线程主要功能是从文件或网络流中读取数据,并根据音视频类型插入相应的PacketQueue队列中。

一、初始化相关

AVDictionaryEntry *t;
SDL_mutex *wait_mutex = SDL_CreateMutex();
int scan_all_pmts_set = 0;
int64_t pkt_ts;

if (!wait_mutex) {
    av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
    ret = AVERROR(ENOMEM);
    goto fail;
}

memset(st_index, -1, sizeof(st_index));
is->eof = 0;

pkt = av_packet_alloc();
if (!pkt) {
    av_log(NULL, AV_LOG_FATAL, "Could not allocate packet.\n");
    ret = AVERROR(ENOMEM);
    goto fail;
}

1、通过SDL_CreateMutex()创建wait_mutex锁

wait_mutex锁是配合SDL_CondWaitTimeout函数用的,调用SDL_CondWaitTimeout函数时,必须先调用SDL_LockMutex(wait_mutex)。作用是等待其他线程调用SDL_CondSignal函数发送信号。

2、媒体索引数组初始化

memset(st_index, -1, sizeof(st_index));
is->eof = 0;

初始化媒体索引数组为-1,并初始化文件末尾标志为0,代表未到文件末尾。

3、AVPacket和AVFormatContext分配内存

pkt = av_packet_alloc();
if (!pkt) {
    av_log(NULL, AV_LOG_FATAL, "Could not allocate packet.\n");
    ret = AVERROR(ENOMEM);
    goto fail;
}
ic = avformat_alloc_context();
if (!ic) {
    av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
    ret = AVERROR(ENOMEM);
    goto fail;
}

AVFormatContext 是封装上下文,描述了媒体文件或媒体流的构成和基本信息

通过av_packet_alloc()分配AVPacket的内存,通过avformat_alloc_context()分配AVFormatContext的内存。

4、指定中断的回调函数

ic->interrupt_callback.callback = decode_interrupt_cb;
ic->interrupt_callback.opaque = is;

创建AVFormatContext 对象后,在调用avformat_open_input函数打开文件前,需要设置中断回调函数,用于检查是否应该中断 IO 操作。

interrupt_callback用于ffmpeg内部在执行耗时操作时检查是否有退出请求,并提前中断IO操作,避免用户退出请求没有及时响应。中断函数如下:

static int decode_interr
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值