ijkplayer 消息循環處理過程分析
- 簡介
- 一、消息隊列初始化
- 1、 initWithContentURLString函數
- 2、 ijkmp_ios_create函數
- 3、 ijkmp_create函數
- 二、消息隊列的消息循環處理函數啟動
- 1、prepareToPlay函數
- 2、ijkmp_prepare_async函數
- 3、ijkmp_prepare_async_l函數
- 4、ijkmp_msg_loop函數
- 三、消息循環處理
- 1、 media_player_msg_loop消息循環函數
- 2、 ijkmp_get_msg函數
- 3、 postEvent函數
簡介
ijkplayer是一個基于FFPlay二次開發的
輕量級Android/iOS視頻播放器,實現了跨平臺的功能
下面以ios平臺調用的過程來分析ijkplayer的消息隊列事件處理流程
基于版本k0.7.6
源碼地址:https://gitee.com/mirrors/ijkplayer
底層播放控制的C代碼 和 上層的ios平臺上操作控制的OC代碼通信都是通過這個消息隊列來交互的。所以搞清楚這個消息隊列的處理流程尤為重要。
消息隊列的事件定義在ijkplayer\ijkmedia\ijkplayer\ff_ffmsg.h
消息隊列的操作函數在ijkplayer\ijkmedia\ijkplayer\ff_ffmsg_queue.h
(與ffplay的PacketQueue類似,是由一個鏈表變化而成的一個隊列)
一、消息隊列初始化
1、 initWithContentURLString函數
在ijkplayer\ios\IJKMediaPlayer\IJKMediaPlayer\IJKFFMoviePlayerController.m
的中調用ijkmp_ios_create(media_player_msg_loop)函數初始化IjkMediaPlayer結構時傳入了一個消息循環函數指針
2、 ijkmp_ios_create函數
在ijkplayer\ios\IJKMediaPlayer\IJKMediaPlayer\ijkmedia\ijkplayer\ios\ijkplayer_ios.m
這個文件就是ios平臺下對ijkplaer.c的一個封裝
再調用ijkmp_create(msg_loop)
3、 ijkmp_create函數
在ijkplayer\ijkmedia\ijkplayer\ijkplayer.c這個文件中,
這個文件這一層就是底層播放控制的C代碼 和 上層的ios平臺上操作控制的OC代碼的中間層就是消息循環函數運行的這一層
創建IjkMediaPlayer結構對象后將msg_loop消息循環函數指針賦值保存到ijkMediaPlayer的msg_loop成員變量中。
msg_loop:保存oc層的消息循環函數
msg_thread:運行msg_loop這個消息循環函數的線程
ffplayer:底層播放控制結構,內部的msg_queue就是這個消息隊列
到這里事件處理的消息隊列初始化就完成了,但消息循環函數還沒跑起來的。
二、消息隊列的消息循環處理函數啟動
1、prepareToPlay函數
在ijkplayer\ios\IJKMediaPlayer\IJKMediaPlayer\IJKFFMoviePlayerController.m,
調用ijkmp_prepare_async(_mediaPlayer);
準備播放操作
2、ijkmp_prepare_async函數
在ijkplayer\ijkmedia\ijkplayer\ijkplayer.c
這個是進入加鎖操作的,再調用ijkmp_prepare_async_l(mp);
才是真正操作
3、ijkmp_prepare_async_l函數
在ijkplayer\ijkmedia\ijkplayer\ijkplayer.c
函數中調用
mp->msg_thread = SDL_CreateThreadEx(&mp->_msg_thread, ijkmp_msg_loop, mp, “ff_msg_loop”);
進行創建消息循環處理線程
4、ijkmp_msg_loop函數
在ijkplayer\ijkmedia\ijkplayer\ijkplayer.c
內部就是調用mp->msg_loop(arg);
此時消息循環處理函數就跑起來了。
三、消息循環處理
1、 media_player_msg_loop消息循環函數
在ijkplayer\ios\IJKMediaPlayer\IJKMediaPlayer\IJKFFMoviePlayerController.m
注意兩個函數調用:
ijkmp_get_msg(mp, &msg->_msg, 1) : 是播放底層需要處理的消息
[ffpController performSelectorOnMainThread:@selector(postEvent:) withObject:msg waitUntilDone:NO]:是oc層需要處理的消息
根據這個順序是ijkmp_get_msg從獲取消息隊列獲取出來消息,如果是播放底層需要處理的消息就處理。返回后,再將這個消息傳入oc層的postEvent處理。
2、 ijkmp_get_msg函數
在ijkplayer\ijkmedia\ijkplayer\ijkplayer.c文件中
部分截圖
3、 postEvent函數
在ijkplayer\ios\IJKMediaPlayer\IJKMediaPlayer\IJKFFMoviePlayerController.m文件中
部分截圖