Android --- Ijkplayer源码阅读native层之自定义消息处理机制(四)

整章目录:Android------- IjkPlayer 源码学习目录

本篇主要介绍Ijkplayer 在native 自定义的消息处理机制,其原理于Android的handler相识。下图红色圈起部分:

native层的消息处理机制本命为message_loop,会在ijkplayer_jni->IjkMediaPlayer_native_setup中被设置到IjkMediaPlayer结构体中的msg_loop变量中。

如果不清楚 IjkMediaPlayer_native_setup的调用过程,请看Android ----- ijkplayer源码阅读Java层(二)

message_loop:

message_loop_n:

注意这里有一个死循环,不停的去队列中取消息。

这里预留一个空间A: post_event方法

ijkmp_get_msg:获取一个消息

这里第二个死循环

msg_queue_get:

/**
 *
 * @param q 消息队列
 * @param msg 存放放回的消息
 * @param block 如果消息队列为空,是否等待。 1为等待,0为不等待
 * @return  >0 表示获得消息成功,否则失败。
 */
/* return < 0 if aborted, 0 if no msg and > 0 if msg.  */
inline static int msg_queue_get(MessageQueue *q, AVMessage *msg, int block)
{
    AVMessage *msg1;
    int ret;
    // 获得操作锁,防止异步
    SDL_LockMutex(q->mutex);

    for (;;) {
        // 是否退出了,返回 -1
        if (q->abort_request) {
            ret = -1;
            break;
        }

        // 获得链表头节点,放入msg1
        msg1 = q->first_msg;

        // 如果存在
        if (msg1) {
            // 将链表头指向下一节点
            q->first_msg = msg1->next;

            if (!q->first_msg)
                q->last_msg = NULL;
            // 链表中的节点数减1
            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
            // 返回1
            ret = 1;
            break;
        } else if (!block) {
            // 不等待,直接返回0
            ret = 0;
            break;
        } else {
            // 等待
            SDL_CondWait(q->cond, q->mutex);
        }
    }
    
    // 释放锁
    SDL_UnlockMutex(q->mutex);
    return ret;
}

都加了注释,理解应该没啥问题。当拿到了一个消息后,会到前面的预留空间A-----调用post_event()将消息传回到Java层

定义了别名

void J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__postEventFromNative(JNIEnv *env, jobject weakThiz, jint what, jint arg1, jint arg2, jobject obj)
{
    (*env)->CallStaticVoidMethod(env, class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id, class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_postEventFromNative, weakThiz, what, arg1, arg2, obj);
}

class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id:调用的Java 类


class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_postEventFromNative: 调用的Java 类中的方法

 

上述操作即是调用IjkMediaPlayer.java 类中的postEventFromNative方法

然后回到Java层,将消息发送给mEventHandler 处理:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值