You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
385 lines
12 KiB
385 lines
12 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
|
|
* Description: decoder
|
|
* Author: Hisilicon
|
|
* Create: 2020-11-11
|
|
*/
|
|
#include "avplay_fc.h"
|
|
#include <sys/prctl.h>
|
|
#include "dft_event.h"
|
|
#include "avplay_common.h"
|
|
|
|
#define AVPLAY_FC_ERROR_ID 955291001
|
|
#define AVPLAY_FC_ID_VDEC_SPEED_ERR 20
|
|
#define AVPLAY_FC_ID_ADEC_SPEED_ERR 21
|
|
#define AVPLAY_FC_ID_EOS_FAIL 22
|
|
#define AVPLAY_FC_ID_PTS_NORMAL_LOOP_ERR 23
|
|
|
|
#define AVPLAY_FC_EOS_CHECK_TIMEOUT 20000
|
|
|
|
volatile td_bool g_adec_speed_inject = TD_FALSE;
|
|
__attribute__((optnone)) void adec_speed_inject_fault()
|
|
{
|
|
g_adec_speed_inject = TD_TRUE;
|
|
ext_info_avplay("g_adec_speed_inject:%d\n", g_adec_speed_inject);
|
|
}
|
|
__attribute__((optnone)) void adec_speed_uninject_fault()
|
|
{
|
|
g_adec_speed_inject = TD_FALSE;
|
|
ext_info_avplay("g_adec_speed_inject:%d\n", g_adec_speed_inject);
|
|
}
|
|
|
|
volatile td_bool g_vdec_speed_inject = TD_FALSE;
|
|
__attribute__((optnone)) void vdec_speed_inject_fault()
|
|
{
|
|
g_vdec_speed_inject = TD_TRUE;
|
|
ext_info_avplay("g_vdec_speed_inject:%d\n", g_vdec_speed_inject);
|
|
}
|
|
__attribute__((optnone)) void vdec_speed_uninject_fault()
|
|
{
|
|
g_vdec_speed_inject = TD_FALSE;
|
|
ext_info_avplay("g_vdec_speed_inject:%d\n", g_vdec_speed_inject);
|
|
}
|
|
|
|
volatile td_bool g_eos_fail_inject = TD_FALSE;
|
|
__attribute__((optnone)) void eos_fail_inject_fault()
|
|
{
|
|
g_eos_fail_inject = TD_TRUE;
|
|
ext_info_avplay("g_eos_fail_inject:%d\n", g_eos_fail_inject);
|
|
}
|
|
__attribute__((optnone)) void eos_fail_uninject_fault()
|
|
{
|
|
g_eos_fail_inject = TD_FALSE;
|
|
ext_info_avplay("g_eos_fail_inject:%d\n", g_eos_fail_inject);
|
|
}
|
|
|
|
volatile td_bool g_pts_normal_loop_err_inject = TD_FALSE;
|
|
__attribute__((optnone)) void pts_normal_loop_err_inject()
|
|
{
|
|
g_pts_normal_loop_err_inject = TD_TRUE;
|
|
ext_info_avplay("g_pts_normal_loop_err_inject:%d\n", g_pts_normal_loop_err_inject);
|
|
}
|
|
__attribute__((optnone)) void pts_normal_loop_err_uninject()
|
|
{
|
|
g_pts_normal_loop_err_inject = TD_FALSE;
|
|
ext_info_avplay("g_pts_normal_loop_err_inject:%d\n", g_pts_normal_loop_err_inject);
|
|
}
|
|
|
|
typedef struct {
|
|
td_char *tag_name;
|
|
td_char *tag_info;
|
|
} fc_tag_info;
|
|
|
|
typedef struct {
|
|
td_u32 index;
|
|
td_u32 err_id;
|
|
fc_tag_info f1_info;
|
|
fc_tag_info f2_info;
|
|
fc_tag_info detail_info;
|
|
} avplay_fc_err_info;
|
|
|
|
static avplay_fc_err_info g_avplay_fc_err_table[] = {
|
|
{
|
|
.index = AVPLAY_FC_ID_VDEC_SPEED_ERR,
|
|
.err_id = AVPLAY_FC_ERROR_ID,
|
|
.f1_info = {
|
|
.tag_name = "F1NAME",
|
|
.tag_info = "avplay"
|
|
},
|
|
.f2_info = {
|
|
.tag_name = "F2NAME",
|
|
.tag_info = "avplay vdec speed error"
|
|
},
|
|
.detail_info = {
|
|
.tag_name = "VDEC_SPEED_ERR",
|
|
.tag_info = "1"
|
|
},
|
|
},
|
|
|
|
{
|
|
.index = AVPLAY_FC_ID_ADEC_SPEED_ERR,
|
|
.err_id = AVPLAY_FC_ERROR_ID,
|
|
.f1_info = {
|
|
.tag_name = "F1NAME",
|
|
.tag_info = "avplay"
|
|
},
|
|
.f2_info = {
|
|
.tag_name = "F2NAME",
|
|
.tag_info = "avplay adec speed error"
|
|
},
|
|
.detail_info = {
|
|
.tag_name = "ADEC_SPEED_ERR",
|
|
.tag_info = "1"
|
|
},
|
|
},
|
|
|
|
{
|
|
.index = AVPLAY_FC_ID_EOS_FAIL,
|
|
.err_id = AVPLAY_FC_ERROR_ID,
|
|
.f1_info = {
|
|
.tag_name = "F1NAME",
|
|
.tag_info = "avplay"
|
|
},
|
|
.f2_info = {
|
|
.tag_name = "F2NAME",
|
|
.tag_info = "avplay eos error"
|
|
},
|
|
.detail_info = {
|
|
.tag_name = "EOS_ERR",
|
|
.tag_info = "1"
|
|
},
|
|
},
|
|
|
|
{
|
|
.index = AVPLAY_FC_ID_PTS_NORMAL_LOOP_ERR,
|
|
.err_id = AVPLAY_FC_ERROR_ID,
|
|
.f1_info = {
|
|
.tag_name = "F1NAME",
|
|
.tag_info = "avplay"
|
|
},
|
|
.f2_info = {
|
|
.tag_name = "F2NAME",
|
|
.tag_info = "avplay pts normal loop err"
|
|
},
|
|
.detail_info = {
|
|
.tag_name = "PTS_NORMAL_LOOP_ERR",
|
|
.tag_info = "1"
|
|
},
|
|
},
|
|
};
|
|
|
|
static avplay_fc_err_info *avplay_get_err_info(td_u32 index)
|
|
{
|
|
td_u32 i;
|
|
size_t num = sizeof(g_avplay_fc_err_table) / sizeof(avplay_fc_err_info);
|
|
|
|
for (i = 0; i < num; i++) {
|
|
if (g_avplay_fc_err_table[i].index == index) {
|
|
return &g_avplay_fc_err_table[i];
|
|
}
|
|
}
|
|
|
|
return TD_NULL;
|
|
}
|
|
|
|
static td_void fc_report_err_event(td_u32 index)
|
|
{
|
|
td_s32 ret;
|
|
td_handle handle;
|
|
td_char name[1024] = {0};
|
|
|
|
avplay_fc_err_info *err_info = avplay_get_err_info(index);
|
|
if (err_info == TD_NULL) {
|
|
ext_err_avplay("no such err index:%d\n", index);
|
|
return;
|
|
}
|
|
|
|
ret = (td_s32)dft_event_create(err_info->err_id, &handle);
|
|
if (ret == TD_SUCCESS) {
|
|
prctl(PR_GET_NAME, name);
|
|
dft_event_put_string(handle, "PNAME", name);
|
|
dft_event_put_string(handle, err_info->f1_info.tag_name, err_info->f1_info.tag_info);
|
|
dft_event_put_string(handle, err_info->f2_info.tag_name, err_info->f2_info.tag_info);
|
|
dft_event_put_string(handle, err_info->detail_info.tag_name, err_info->detail_info.tag_info);
|
|
dft_event_report(handle);
|
|
dft_event_destroy(handle);
|
|
}
|
|
|
|
ext_info_avplay("err_id: %d\n PNAME: %s\n %s: %s\n %s: %s\n %s: %s\n",
|
|
err_info->err_id, name,
|
|
err_info->f1_info.tag_name, err_info->f1_info.tag_info,
|
|
err_info->f2_info.tag_name, err_info->f2_info.tag_info,
|
|
err_info->detail_info.tag_name, err_info->detail_info.tag_info);
|
|
|
|
return;
|
|
}
|
|
|
|
td_void avplay_fault_check_init(avplay_context *ctx)
|
|
{
|
|
if (ctx == NULL) {
|
|
ext_err_avplay("%s, ctx is null.", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
ctx->fc_info.is_adec_speed_err_report = TD_FALSE;
|
|
ctx->fc_info.is_vdec_speed_err_report = TD_FALSE;
|
|
ctx->fc_info.is_pts_normal_loop_err_report = TD_FALSE;
|
|
|
|
ctx->fc_info.is_eos_fail_err_report = TD_FALSE;
|
|
ctx->fc_info.aud_eos_report_check_status = TD_FALSE;
|
|
ctx->fc_info.vid_eos_report_check_status = TD_FALSE;
|
|
ctx->fc_info.aud_eos_report_check_start_time = 0;
|
|
ctx->fc_info.vid_eos_report_check_start_time = 0;
|
|
}
|
|
|
|
td_void avplay_fault_check_deinit(avplay_context *ctx)
|
|
{
|
|
if (ctx == NULL) {
|
|
ext_err_avplay("%s, ctx is null.", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
ctx->fc_info.is_adec_speed_err_report = TD_FALSE;
|
|
ctx->fc_info.is_vdec_speed_err_report = TD_FALSE;
|
|
ctx->fc_info.is_pts_normal_loop_err_report = TD_FALSE;
|
|
|
|
ctx->fc_info.is_eos_fail_err_report = TD_FALSE;
|
|
ctx->fc_info.aud_eos_report_check_status = TD_FALSE;
|
|
ctx->fc_info.vid_eos_report_check_status = TD_FALSE;
|
|
ctx->fc_info.aud_eos_report_check_start_time = 0;
|
|
ctx->fc_info.vid_eos_report_check_start_time = 0;
|
|
}
|
|
|
|
static td_void avplay_fc_adec_speed_err_check()
|
|
{
|
|
td_bool inject = avplay_get_inject_value(AVPLAY_FC_ID_ADEC_SPEED_ERR);
|
|
if (inject == TD_TRUE) {
|
|
fc_report_err_event(AVPLAY_FC_ID_ADEC_SPEED_ERR);
|
|
g_adec_speed_inject = TD_FALSE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief adec speed check.
|
|
*/
|
|
static td_void avplay_fault_check_adec_speed_process()
|
|
{
|
|
avplay_fc_adec_speed_err_check();
|
|
}
|
|
|
|
static td_void avplay_fc_vdec_speed_err_check()
|
|
{
|
|
td_bool inject = avplay_get_inject_value(AVPLAY_FC_ID_VDEC_SPEED_ERR);
|
|
if (inject == TD_TRUE) {
|
|
fc_report_err_event(AVPLAY_FC_ID_VDEC_SPEED_ERR);
|
|
g_vdec_speed_inject = TD_FALSE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief vdec speed check.
|
|
*/
|
|
static td_void avplay_fault_check_vdec_speed_process()
|
|
{
|
|
avplay_fc_vdec_speed_err_check();
|
|
}
|
|
|
|
static td_bool is_need_report_eos_fail_err(avplay_context *ctx)
|
|
{
|
|
// video eos report check
|
|
if (ctx->vid.enable && ctx->fc_info.is_eos_fail_err_report == TD_FALSE &&
|
|
ctx->vid.set_eos_flag == TD_TRUE && ctx->vid.used_buf_percent == 0) {
|
|
if (ctx->fc_info.vid_eos_report_check_status == TD_FALSE) {
|
|
ctx->fc_info.vid_eos_report_check_start_time = avplay_gettime_system();
|
|
ctx->fc_info.vid_eos_report_check_status = TD_TRUE;
|
|
ext_info_avplay("vdec eos vid_eos_report_check_status start.");
|
|
}
|
|
|
|
if (ctx->fc_info.vid_eos_report_check_status == TD_TRUE &&
|
|
(avplay_gettime_system() - ctx->fc_info.vid_eos_report_check_start_time > AVPLAY_FC_EOS_CHECK_TIMEOUT) &&
|
|
(ctx->vid.vdec_eos == TD_FALSE || ctx->vid.eos_reported == TD_FALSE)) {
|
|
ctx->fc_info.is_eos_fail_err_report = TD_TRUE;
|
|
ext_info_avplay("%s, vdec eos not report, report event.", __FUNCTION__);
|
|
return TD_FALSE;
|
|
}
|
|
}
|
|
|
|
// audio eos report check
|
|
if (ctx->aud.enable && ctx->fc_info.is_eos_fail_err_report == TD_FALSE &&
|
|
ctx->aud.set_eos_flag == TD_TRUE && ctx->aud.used_buf_percent == 0) {
|
|
if (ctx->fc_info.aud_eos_report_check_status == TD_FALSE) {
|
|
ctx->fc_info.aud_eos_report_check_start_time = avplay_gettime_system();
|
|
ctx->fc_info.aud_eos_report_check_status = TD_TRUE;
|
|
ext_info_avplay("adec eos aud_eos_report_check_status start.");
|
|
}
|
|
|
|
if (ctx->fc_info.aud_eos_report_check_status == TD_TRUE &&
|
|
(avplay_gettime_system() - ctx->fc_info.aud_eos_report_check_start_time > AVPLAY_FC_EOS_CHECK_TIMEOUT) &&
|
|
(ctx->aud.adec_eos == TD_FALSE || ctx->aud.eos_reported == TD_FALSE)) {
|
|
ctx->fc_info.is_eos_fail_err_report = TD_TRUE;
|
|
ext_info_avplay("%s, adec eos not report, report event.", __FUNCTION__);
|
|
return TD_FALSE;
|
|
}
|
|
}
|
|
|
|
return TD_FALSE;
|
|
}
|
|
|
|
static td_void avplay_fc_eos_fail_check(avplay_context *ctx)
|
|
{
|
|
td_bool inject = avplay_get_inject_value(AVPLAY_FC_ID_EOS_FAIL);
|
|
if (inject == TD_TRUE) {
|
|
fc_report_err_event(AVPLAY_FC_ID_EOS_FAIL);
|
|
g_eos_fail_inject = TD_FALSE;
|
|
ext_info_avplay("%s, eos test report, report event.", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
if (ctx->com.cur_state != UAPI_AVPLAY_STATUS_PLAY ||
|
|
ctx->fc_info.is_eos_fail_err_report == TD_TRUE) {
|
|
return;
|
|
}
|
|
|
|
if (is_need_report_eos_fail_err(ctx)) {
|
|
fc_report_err_event(AVPLAY_FC_ID_EOS_FAIL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief eos check.
|
|
*/
|
|
static td_void avplay_fault_check_eos_fail_process(avplay_loop *loop)
|
|
{
|
|
avplay_context *ctx = loop->ctx;
|
|
|
|
avplay_fc_eos_fail_check(ctx);
|
|
}
|
|
|
|
static td_void avplay_fc_pts_normal_loop_err_check()
|
|
{
|
|
td_bool inject = avplay_get_inject_value(AVPLAY_FC_ID_PTS_NORMAL_LOOP_ERR);
|
|
if (inject == TD_TRUE) {
|
|
fc_report_err_event(AVPLAY_FC_ID_PTS_NORMAL_LOOP_ERR);
|
|
g_pts_normal_loop_err_inject = TD_FALSE;
|
|
ext_info_avplay("%s, pts normal loop err test report, report event.", __FUNCTION__);
|
|
return;
|
|
}
|
|
}
|
|
|
|
static td_void avplay_fault_check_pts_normal_loop_err_process()
|
|
{
|
|
avplay_fc_pts_normal_loop_err_check();
|
|
}
|
|
|
|
td_bool avplay_get_inject_value(td_u32 event_id)
|
|
{
|
|
switch (event_id) {
|
|
case AVPLAY_FC_ID_VDEC_SPEED_ERR:
|
|
return g_vdec_speed_inject;
|
|
case AVPLAY_FC_ID_ADEC_SPEED_ERR:
|
|
return g_adec_speed_inject;
|
|
case AVPLAY_FC_ID_EOS_FAIL:
|
|
return g_eos_fail_inject;
|
|
case AVPLAY_FC_ID_PTS_NORMAL_LOOP_ERR:
|
|
return g_pts_normal_loop_err_inject;
|
|
default:
|
|
ext_err_avplay("%s, event is is invalidated event_id:%d.", __FUNCTION__, event_id);
|
|
return TD_FALSE;
|
|
}
|
|
}
|
|
|
|
td_void avplay_fault_check_process(avplay_loop *loop)
|
|
{
|
|
if (loop == NULL) {
|
|
ext_err_avplay("%s, loop is null.", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
avplay_fault_check_adec_speed_process();
|
|
avplay_fault_check_vdec_speed_process();
|
|
avplay_fault_check_eos_fail_process(loop);
|
|
avplay_fault_check_pts_normal_loop_err_process();
|
|
}
|