Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MACBOOK码流多次断开与派送的流程,会导致MPP数据送不进去也取不出来的问题且一经出现不能恢复 #50

Closed
wshyu opened this issue Aug 16, 2018 · 10 comments

Comments

@wshyu
Copy link

wshyu commented Aug 16, 2018

mpp_dec_parser_thread的线程堆栈:
#0 0x0000007b3ad3ccec in syscall () from target:/system/lib64/libc.so
#1 0x0000007b3ad88e7c in pthread_cond_wait () from target:/system/lib64/libc.so
#2 0x0000007b3af851e8 in Condition::wait(Mutex&) () from target:/system/lib64/libmpp.so
#3 0x0000007b3af85210 in MppMutexCond::wait() () from target:/system/lib64/libmpp.so
#4 0x0000007b3af852f4 in MppThread::wait(MppThreadSignal_e) () from target:/system/lib64/libmpp.so
#5 0x0000007b3af88a80 in mpp_dec_parser_thread () from target:/system/lib64/libmpp.so
#6 0x0000007b3ad8974c in __pthread_start(void*) () from target:/system/lib64/libc.so
#7 0x0000007b3ad3ea80 in __start_thread () from target:/system/lib64/libc.so
#8 0x0000000000000000 in ?? ()

mpp_dec_hal_thread的堆栈:
#0 0x0000007b3ad3ccec in syscall () from target:/system/lib64/libc.so
#1 0x0000007b3ad88e7c in pthread_cond_wait () from target:/system/lib64/libc.so
#2 0x0000007b3af851e8 in Condition::wait(Mutex&) () from target:/system/lib64/libmpp.so
#3 0x0000007b3af85210 in MppMutexCond::wait() () from target:/system/lib64/libmpp.so
#4 0x0000007b3af852f4 in MppThread::wait(MppThreadSignal_e) () from target:/system/lib64/libmpp.so
#5 0x0000007b3af88d78 in mpp_dec_hal_thread () from target:/system/lib64/libmpp.so
#6 0x0000007b3ad8974c in __pthread_start(void*) () from target:/system/lib64/libc.so
#7 0x0000007b3ad3ea80 in __start_thread () from target:/system/lib64/libc.so
#8 0x0000000000000000 in ?? ()
送码流的线程日志信息:
01-01 16:02:08.261 7257 7258 D Player.Binder.Server.WFD: PlayerBinderServerWFD::onTransact(2) 16
01-01 16:02:08.261 7257 7258 I Player.Binder.Server.WFD: m_nATimestamp:3068719077885, m_nVTimestamp:3068719078185, , m_nLastFrameTimestamp:57728224, nCurTimestamp:57728261, m_nTimestampBase:3068719078185
01-01 16:02:08.261 7257 7258 I Player.Binder.Server.WFD: emMediaCodecID:2, emMediaSource:1, emMediaType:0, emStreamID:12,uPresentTimestamp:87210045, uReserve:0
01-01 16:02:08.261 7257 7258 D Player.Binder.Server.WFD: device/ruijie/player/./Player_Binder_Server.cpp:1506, uFrameLen:A8E-2702
01-01 16:02:08.261 7257 7258 I Player.Binder.Server.WFD: 00
01-01 16:02:08.261 7257 7258 I Player.Binder.Server.WFD: 00
01-01 16:02:08.261 7257 7258 I Player.Binder.Server.WFD: 01
01-01 16:02:08.261 7257 7258 I Player.Binder.Server.WFD: 21
01-01 16:02:08.261 7257 7258 I Player.Binder.Server.WFD: E4
01-01 16:02:08.261 7257 7258 E Player.Binder.Server.WFD: device/ruijie/player/./Player_Binder_Server.cpp:1698, it failed to get video time statistics node
01-01 16:02:08.261 7257 7258 I Player.Binder.Server.WFD: device/ruijie/player/./Player_Binder_Server.cpp:1713, nIsSPSorPPS:0, uPresentTimestamp:(before conversion:87210045-after conversion:3068719078236)
01-01 16:02:08.276 7257 7258 E VIDEO CODEC: device/ruijie/player/./Player_Video_Codec.cpp:937 it fail to put packet to mpp decoder(error code = -1012)
01-01 16:02:08.276 7257 7258 E Player.Binder.Server.WFD: device/ruijie/player/./Player_Binder_Server.cpp:1737, video decoder put Packet(seq:13782) fail

获取码流线程的日志提示信息:
01-01 15:49:35.442 7257 7271 D Player.Binder.Server.WFD: device/ruijie/player/./Player_Binder_Server.cpp:303, stLastMppFrame(0x0)
01-01 15:49:35.509 7257 7271 D VIDEO CODEC: decode_get_frame failed too much time
01-01 15:49:35.509 7257 7271 E VIDEO CODEC: decode_get_frame failed ret -8
01-01 15:49:35.509 7257 7271 D Player.Binder.Server.WFD: device/ruijie/player/./Player_Binder_Server.cpp:303, stLastMppFrame(0x0)
01-01 15:49:35.575 7257 7271 D VIDEO CODEC: decode_get_frame failed too much time
01-01 15:49:35.575 7257 7271 E VIDEO CODEC: decode_get_frame failed ret -8
01-01 15:49:35.575 7257 7271 D Player.Binder.Server.WFD: device/ruijie/player/./Player_Binder_Server.cpp:303, stLastMppFrame(0x0)

1、设置输出超时时
pParam = &nBlockTimeout;
stRet = m_pMppApi->control(m_stMppCtx, MPP_SET_OUTPUT_BLOCK_TIMEOUT, pParam);
if (MPP_OK != stRet) {
ALOGE("%s:%d it failed to set blocking mode on MPI (code = %d)\n",
FILE, LINE, stRet);
goto ERROR_EXIT;
}
发现:mpp_dec_parser_thread在等待一个消息:
if (check_task_wait(dec, &task)) {
mpp_timer_start(dec->timers[DEC_PRS_WAIT]);
parser->wait();
mpp_timer_pause(dec->timers[DEC_PRS_WAIT]);
}

mpp_dec_parser_thread不工作时,check_task_wait,里面的相关参数(十进制):
notify:2279178328;last_wait:135, curr_wait:1, wait_chg:0

2、不设置输出超时时
check_task_wait的最后一条打印消息:
Line 15096: 0x7d24ae6100 last_wait:00000000 -> curr_wait:00004000 [wait_chg:00000000] notify 00000080 -> wait
mpp_dec_notify的状态打印:
Line 15101: 0x7d24ae6100 status 00004000 notify 00000000 signal, old_flag:00000000
Line 15106: 0x7d24ae6100 status 00004000 notify 00000001 signal, old_flag:00000001
Line 15117: 0x7d24ae6100 status 00004000 notify 00000001 signal, old_flag:00000001
Line 15128: 0x7d24ae6100 status 00004000 notify 00000001 signal, old_flag:00000001
Line 15139: 0x7d24ae6100 status 00004000 notify 00000001 signal, old_flag:00000001
Line 15150: 0x7d24ae6100 status 00004000 notify 00000001 signal, old_flag:00000001
Line 15164: 0x7d24ae6100 status 00004000 notify 00000001 signal, old_flag:00000001
Line 15175: 0x7d24ae6100 status 00004000 notify 00000001 signal, old_flag:00000001

@HermanChen
Copy link
Collaborator

signal 为 1 表示一直有码流在尝试输入
但这个 status 为 0x4000 表示在等待 slot index

/* 7.3 wait for a unused slot index for decoder parse operation */
task->wait.dec_slot_idx = (mpp_slots_get_unused_count(frame_slots)) ? (0) : (1);
if (task->wait.dec_slot_idx)
    return MPP_ERR_BUFFER_FULL;

估计是异常码流把 mpp 里的 slot 耗尽了,可以打开 butslot 的打印看下

@wshyu
Copy link
Author

wshyu commented Aug 17, 2018

butslot 的打印要怎么打开?

@HermanChen
Copy link
Collaborator

setprop buf_slot_debug 0x10
可选的选项:
#define BUF_SLOT_DBG_FUNCTION (0x00000001)
#define BUF_SLOT_DBG_SETUP (0x00000002)
#define BUF_SLOT_DBG_INFO_CHANGE (0x00000004)
#define BUF_SLOT_DBG_OPS_RUNTIME (0x00000010)
#define BUF_SLOT_DBG_BUFFER (0x00000100)
#define BUF_SLOT_DBG_FRAME (0x00000200)
#define BUF_SLOT_DBG_BUF_UESD (0x00000400)
#define BUF_SLOT_DBG_OPS_HISTORY (0x10000000)
#define BUF_SLOT_DBG_ALL (0x10000011)

@wshyu
Copy link
Author

wshyu commented Aug 17, 2018

这个是从正常到异常的最后几行日志输出 (logcat | grep mpp_buf_slot)
01-02 19:04:38.933 8881 8887 I mpp_buf_slot: slot 2 index 30 op: clr hal input arg 0x00000000 status in 000c2011 out 000c2001
01-02 19:04:38.933 8881 8887 I mpp_buf_slot: slot 2 index 31 op: clr hal input arg 0x00000000 status in 000c2015 out 000c2005
01-02 19:04:38.933 8881 8887 I mpp_buf_slot: slot 2 index 32 op: clr hal input arg 0x00000000 status in 000c0015 out 000c0005
01-02 19:04:38.933 8881 8887 I mpp_buf_slot: slot 2 index 33 op: clr hal input arg 0x00000000 status in 000c0015 out 000c0005
01-02 19:04:39.045 8881 8886 I mpp_buf_slot: slot 3 index 0 op: set on use arg 0x00000000 status in 00000000 out 00000001
01-02 19:04:39.045 8881 8886 I mpp_buf_slot: slot 3 index 0 op: set not ready arg 0x00000000 status in 00000001 out 00000003
01-02 19:04:39.045 8881 8886 I mpp_buf_slot: slot 3 index 0 op: set buffer arg 0x7010213c80 status in 00000003 out 00040003
01-02 19:04:39.045 8881 8886 I mpp_buf_slot: slot 3 index 0 op: set codec ready arg 0x00000000 status in 00040003 out 00040001
01-02 19:04:39.045 8881 8886 I mpp_buf_slot: slot 3 index 0 op: set hal input arg 0x00000000 status in 00040001 out 00040011

@HermanChen
Copy link
Collaborator

index 已经到 33 了,的确是中间有 slot 一直在被占用没释放
最好需要录下来能产生问题的码流,给 mpp 来复现下问题

@HermanChen
Copy link
Collaborator

有没有完整log发一下?

@wshyu
Copy link
Author

wshyu commented Aug 17, 2018

https://pan.baidu.com/s/1sAI9okunpzCMRFfW_3_Uzw
可以通过上面的链接下载哈

@wshyu
Copy link
Author

wshyu commented Aug 17, 2018

码流跟log邮件上也发了哈

@HermanChen
Copy link
Collaborator

收到,但是测试过了并不能复现问题……
我想想看还有啥办法。

@wshyu wshyu closed this as completed Aug 20, 2018
@wshyu
Copy link
Author

wshyu commented Aug 20, 2018

修订的patch
From 8a4f77c3421125ea3d6c3e79a083552a662527bd Mon Sep 17 00:00:00 2001
From: Ding Wei [email protected]
Date: Mon, 20 Aug 2018 11:01:45 +0800
Subject: [PATCH] [h264d]: add ref_err flag in task->flags

tips: when parse error, enable had_error; when dpb ref error,
enable ref_error. Go ahead to hal thread and loop all.

Change-Id: I639248dbf4499a8ed473b9f44f1e1332409c5c22
Signed-off-by: Ding Wei [email protected]

diff --git a/mpp/codec/dec/h264/h264d_api.c b/mpp/codec/dec/h264/h264d_api.c
index 5ddc24f..d8ba049 100644
--- a/mpp/codec/dec/h264/h264d_api.c
+++ b/mpp/codec/dec/h264/h264d_api.c
@@ -587,67 +587,38 @@
MPP_RET h264d_parse(void *decoder, HalDecTask *in_task)
{
MPP_RET ret = MPP_ERR_UNKNOW;

  • H264dErrCtx_t *p_err = NULL;
    H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
  • H264dErrCtx_t *p_err = &p_Dec->errctx;
  • INP_CHECK(ret, !decoder && !in_task);
  • p_err = &p_Dec->errctx;
  • in_task->valid = 0; // prepare end flag
  • in_task->valid = 0;
    p_Dec->in_task = in_task;
    p_err->cur_err_flag = 0;
    p_err->used_ref_flag = 0;
    p_Dec->is_parser_end = 0;
  • FUN_CHECK(ret = parse_loop(p_Dec));
  • ret = parse_loop(p_Dec);

  • if (ret) {

  •    in_task->flags.had_error = 1;
    
  • }

    if (p_Dec->is_parser_end) {
    p_Dec->is_parser_end = 0;
    p_Dec->p_Vid->g_framecnt++;
    ret = update_dpb(p_Dec);

  •    if (ret) {
    
  •        in_task->flags.ref_error = 1;
    
  •    }
       if (in_task->flags.eos) {
           h264d_flush_dpb_eos(p_Dec);
       }
    
  •    if (ret) {
    
  •        goto __FAILED;
    
  •    }
    
  •    in_task->valid = 1; // register valid flag
    
  • }
  • in_task->valid = 1;
  • if (!in_task->flags.had_error) {
    in_task->syntax.number = p_Dec->dxva_ctx->syn.num;
    in_task->syntax.data = (void *)p_Dec->dxva_ctx->syn.buf;
    in_task->flags.used_for_ref = p_err->used_ref_flag;
  •    in_task->flags.had_error = (!p_Dec->disable_error
    
  •                                && (p_err->dpb_err_flag | p_err->cur_err_flag)) ? 1 : 0;
    
  • }
    -__RETURN:
  • return ret = MPP_OK;

-__FAILED: {

  •    H264_StorePic_t *dec_pic = p_Dec->p_Vid->dec_pic;
    
  •    in_task->flags.had_error = 1;
    
  •    if (dec_pic) {
    
  •        H264D_WARNNING("[h264d_parse] h264d_parse failed.\n");
    
  •        if (dec_pic->mem_mark
    
  •            && dec_pic->mem_mark->out_flag
    
  •            && (dec_pic->mem_mark->slot_idx >= 0)) {
    
  •            MppFrame mframe = NULL;
    
  •            mpp_buf_slot_get_prop(p_Dec->frame_slots, dec_pic->mem_mark->slot_idx, SLOT_FRAME_PTR, &mframe);
    
  •            if (mframe) {
    
  •                if (p_err->used_ref_flag) {
    
  •                    mpp_frame_set_errinfo(mframe, MPP_FRAME_ERR_UNKNOW);
    
  •                } else {
    
  •                    mpp_frame_set_discard(mframe, MPP_FRAME_ERR_UNKNOW);
    
  •                }
    
  •            }
    
  •            mpp_buf_slot_set_flag(p_Dec->frame_slots, dec_pic->mem_mark->slot_idx, SLOT_QUEUE_USE);
    
  •            mpp_buf_slot_enqueue(p_Dec->frame_slots, dec_pic->mem_mark->slot_idx, QUEUE_DISPLAY);
    
  •            mpp_buf_slot_clr_flag(p_Dec->frame_slots, dec_pic->mem_mark->slot_idx, SLOT_CODEC_USE);
    
  •        }
    
  •        reset_dpb_mark(dec_pic->mem_mark);
    
  •        dec_pic->mem_mark = NULL;
    
  •        MPP_FREE(dec_pic);
    
  •        p_Dec->p_Vid->dec_pic = NULL;
    
  •    }
    
  •    in_task->flags.ref_error |= (!p_Dec->disable_error
    
  •                                 && (p_err->dpb_err_flag | p_err->cur_err_flag)) ? 1 : 0;
    

    }

    return ret;
    @@ -680,7 +651,8 @@

       mpp_buf_slot_get_prop(p_Dec->frame_slots, task_dec->output, SLOT_FRAME_PTR, &mframe);
       if (mframe) {
    
  •        if (ctx->hard_err || task_dec->flags.had_error) {
    
  •        RK_U32 task_err = task_dec->flags.had_error || task_dec->flags.ref_error;
    
  •        if (ctx->hard_err || task_err) {
               if (task_dec->flags.used_for_ref) {
                   mpp_frame_set_errinfo(mframe, MPP_FRAME_ERR_UNKNOW);
               } else {
    

@@ -688,7 +660,7 @@
}
}
H264D_DBG(H264D_DBG_CALLBACK, "[CALLBACK] g_no=%d, out_idx=%d, dpberr=%d, harderr=%d, ref_flag=%d, errinfo=%d, discard=%d\n",

  •                  p_Dec->p_Vid->g_framecnt, task_dec->output, task_dec->flags.had_error, ctx->hard_err, task_dec->flags.used_for_ref,
    
  •                  p_Dec->p_Vid->g_framecnt, task_dec->output, task_err, ctx->hard_err, task_dec->flags.used_for_ref,
                     mpp_frame_get_errinfo(mframe), mpp_frame_get_discard(mframe));
    
           if (ctx->device_id == HAL_RKVDEC) {
    

diff --git a/mpp/hal/inc/hal_task.h b/mpp/hal/inc/hal_task.h
index 4fff817..dd07fb4 100644
--- a/mpp/hal/inc/hal_task.h
+++ b/mpp/hal/inc/hal_task.h
@@ -100,6 +100,7 @@
RK_U32 eos : 1;
RK_U32 info_change : 1;
RK_U32 had_error : 1;

  •    RK_U32      ref_error        : 1;
       RK_U32      used_for_ref     : 1;
       RK_U32      wait_done        : 1;
    

    };
    diff --git a/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c b/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c
    index 2f67f9d..5b96ab0 100644
    --- a/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c
    +++ b/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c
    @@ -628,7 +628,7 @@

    INP_CHECK(ret, NULL == p_hal);

  • if (task->dec.flags.had_error) {
  • if (task->dec.flags.had_error || task->dec.flags.ref_error) {
    goto __RETURN;
    }
    H264dRkvRegCtx_t *reg_ctx = (H264dRkvRegCtx_t *)p_hal->reg_ctx;
    @@ -686,7 +686,7 @@

    INP_CHECK(ret, NULL == p_hal);

  • if (task->dec.flags.had_error) {
  • if (task->dec.flags.had_error || task->dec.flags.ref_error) {
    goto __RETURN;
    }

@@ -729,7 +729,7 @@
H264dRkvRegCtx_t *reg_ctx = (H264dRkvRegCtx_t *)p_hal->reg_ctx;
H264dRkvRegs_t *p_regs = reg_ctx->regs;

  • if (task->dec.flags.had_error) {
  • if (task->dec.flags.had_error || task->dec.flags.ref_error) {
    goto __SKIP_HARD;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants