message_loop
在native_setup
过程中
// ijkplayer_jni.c
static void
IjkMediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
MPTRACE("%s\n", __func__);
IjkMediaPlayer *mp = ijkmp_android_create(message_loop);
......
}
// ijkplayer_android.c
IjkMediaPlayer *ijkmp_android_create(int(*msg_loop)(void*))
{
IjkMediaPlayer *mp = ijkmp_create(msg_loop);
......
}
// ijkplayer.c
IjkMediaPlayer *ijkmp_create(int (*msg_loop)(void*))
{
......
mp->msg_loop = msg_loop;
......
}
所以,msg_loop
对应的是
// ijkplayer_jni.c
static int message_loop(void *arg)
{
......
IjkMediaPlayer *mp = (IjkMediaPlayer*) arg;
JNI_CHECK_GOTO(mp, env, NULL, "mpjni: native_message_loop: null mp", LABEL_RETURN);
message_loop_n(env, mp);
......
}
static void message_loop_n(JNIEnv *env, IjkMediaPlayer *mp)
{
jobject weak_thiz = (jobject) ijkmp_get_weak_thiz(mp);
JNI_CHECK_GOTO(weak_thiz, env, NULL, "mpjni: message_loop_n: null weak_thiz", LABEL_RETURN);
while (1) {
AVMessage msg;
int retval = ijkmp_get_msg(mp, &msg, 1);
if (retval < 0)
break;
// block-get should never return 0
assert(retval > 0);
switch (msg.what) {
......
}
msg_free_res(&msg);
}
LABEL_RETURN:
;
}
// ijkplayer.c
int ijkmp_get_msg(IjkMediaPlayer *mp, AVMessage *msg, int block)
{
assert(mp);
while (1) {
int continue_wait_next_msg = 0;
int retval = msg_queue_get(&mp->ffplayer->msg_queue, msg, block);
if (retval <= 0)
return retval;
switch (msg->what) {
......
}
if (continue_wait_next_msg) {
msg_free_res(msg);
continue;
}
return retval;
}
return -1;
}
// ff_ffmsg_queue.h
inline static int msg_queue_get(MessageQueue *q, AVMessage *msg, int block)
{
AVMessage *msg1;
int ret;
SDL_LockMutex(q->mutex);
for (;;) {
if (q->abort_request) {
ret = -1;
break;
}
msg1 = q->first_msg;
if (msg1) {
q->first_msg = msg1->next;
if (!q->first_msg)
q->last_msg = NULL;
q->nb_messages--;
*msg = *msg1;
msg1->obj = NULL;
#ifdef FFP_MERGE
av_free(msg1);
#else
msg1->next = q->recycle_msg;
q->recycle_msg = msg1;
#endif
ret = 1;
break;
} else if (!block) {
ret = 0;
break;
} else {
SDL_CondWait(q->cond, q->mutex);
}
}
SDL_UnlockMutex(q->mutex);
return ret;
}
可以看到,正常情况下,如果MessageQueue
的first_msg
字段为空,那么线程就会阻塞