ijkplayer message_loop

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;
}

可以看到,正常情况下,如果MessageQueuefirst_msg字段为空,那么线程就会阻塞

using clock_type = std::chrono::system_clock; struct message { clock_type::time_point when; std::function<void()> callback; std::string param; }; class message_loop { public: message_loop(): _stop(false) { // } message_loop(const message_loop&) = delete; message_loop& operator=(const message_loop&) = delete; void run() { while (!_stop) { auto msg = wait_one(); msg.callback(); } } void quit() { post({clock_type::now(), this{ _stop = true; } }); } void post(std::function<void()> callable) { post({clock_type::now(), std::move(callable)}); } void post(std::function<void()> callable, std::chrono::milliseconds delay) { post({clock_type::now() + delay, std::move(callable)}); } private: struct msg_prio_comp { inline bool operator() (const message& a, const message& b) { return a.when > b.when; } }; using queue_type = std::priority_queue<message, std::vector<message>, msg_prio_comp>; std::mutex _mtx; std::condition_variable _cv; queue_type _msgs; bool _stop; void post(message msg) { auto lck = acquire_lock(); _msgs.emplace(std::move(msg)); _cv.notify_one(); } std::unique_lockstd::mutex acquire_lock() { return std::unique_lockstd::mutex(_mtx); } bool idle() const { return _msgs.empty(); } const message& top() const { return _msgs.top(); } message pop() { auto msg = top(); _msgs.pop(); return msg; } message wait_one() { while (true) { auto lck = acquire_lock(); if (idle()) _cv.wait(lck); else if (top().when <= clock_type::now()) return pop(); else { _cv.wait_until(lck, top().when); // 可能是新消息到达,再循环一次看看 } } } }; int main(int argc, char *argv[]) { using namespace std; using namespace std::chrono; message_loop *pLoop = new message_loop; thread th(pLoop{ pLoop->run(); }); cout << "POST 1"<<endl;; pLoop->post({ cout << "1"<<endl; }); cout << "POST 2"<<endl;; pLoop->post({ cout << "2"<<endl; }, milliseconds(500)); cout << "POST 3"<<endl;; pLoop->post({ cout << "3"<<endl; }); cout << "POST 4"<<endl;; pLoop->post({ cout << "4"<<endl; }, milliseconds(1000)); this_thread::sleep_for(milliseconds(1500)); // pLoop->quit(); cout << "Quit"<<endl; th.join(); cout << "here"<<endl; } 请优化一下,可以传参
05-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值