

1、引言
上篇博客 ijkplayer 源码分析(1):初始化流程 的 4.1.1 ijkmp_create() 的部分简要说明了下 ijkplayer 的消息处理机制,本文再根据源码进行详细分析,搞清楚其消息机制及处理流程。
播放器是一个较为复杂的多线程工程,如数据读取线程、音频解码线程、视频解码线程、视频播放线程等。各个线程都需要产生事件,如状态改变、出错等,需要传递给控制层和业务层去处理。因此需要一个消息处理机制来完成这些工作,把各个线程产生的事件转化成消息来处理。当然也可以通过接口回调的方式来处理,但样式繁多的事件会需要极其庞大复杂的接口,会很难维护和扩展。因此消息机制是一个很不错的方案。
通过分析 ijkplayer 源码会发现,ijkplayer 实现的消息处理机制和 Android 端的 Handler、Looper、Message、MessageQueue 的消息分发和处理机制很类似。下面我们就详细分析下 ijkplayer 的消息分发处理机制。
本文是基于 A4ijkplayer 项目进行 ijkplayer 源码分析,该项目是将 ijkplayer 改成基于 CMake 编译,可导入 Android Studio 编译运行,方便代码查找、函数跳转、单步调试、调用栈跟踪等。
2、消息分发处理机制
2.1 Android 的消息分发处理机制
我们先来回顾下 Android 端 Handler、Looper、Message、MessageQueue 的消息分发和处理机制,这有助于我们理解 ijkplayer 的消息处理机制。
Android 的消息分发处理机制如下:
-
通过 Handler 的 sendMessage() 方法发送一个消息
-
Looper 将该消息加入到消息队列 MessageQueue 中
-
Looper 所在线程循环遍历 MessageQueue 从中取出消息分发,如果没有消息则挂起等待
-
分发到 Handler 执行 handleMessage() 处理消息 以上就完成了消息的发送和处理流程

2.2 ijkplayer 的消息分发处理机制

如上图,ijkplayer 的消息分发处理机制和 Android 类似,采用的生产者---消费者模式。生产者(可以是多个)从任意线程生产消息,将其加入到消息队列中,消费者(只有一个)在一个独立的线程循环从消息队列取出消息进行分发处理,如果队列为空则等待。 ijkplayer 中的消息结构体为 AVMessage,消息队列结构体为 MessageQueue,均位于 ijkmedia/ijkplayer/ff_ffmsg_queue.h 文件中,结构如下,可以看到跟 Android 的 Message 很像。
typedef struct AVMessage {
int what;
int arg1;
int arg2;
void *obj;
void (*free_l)(void *obj);
struct AVMessage *next;
} AVMessage;
typedef struct MessageQueue {
AVMessage *first_msg, *last_msg;
int nb_messages;
int abort_request;
SDL_mutex *mutex;
SDL_cond *cond;
AVMessage *recycle_msg;
int recycle_count;
int alloc_count;
} MessageQueue;
2.2.1 Message 提

本文深入分析ijkplayer的消息分发处理机制,对比Android的Handler、Looper、Message、MessageQueue,探讨ijkplayer如何采用类似机制实现消息的生产与消费。通过源码解读,展示了ijkplayer从创建MessageQueue到启动消息处理线程的完整流程。
:消息分发处理机制&spm=1001.2101.3001.5002&articleId=130172955&d=1&t=3&u=a041533915684a21bce040e540f64181)
949

被折叠的 条评论
为什么被折叠?



