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.

729 lines
22 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved.
* Description: IEC61937 data parser function
* Author: audio
* Create: 2012-05-30
*/
#include <string.h>
#include "mpi_ai_debug.h"
#include "iec61937_parser.h"
#include "soc_math.h"
#include "mpi_memory_ext.h"
#include "mpi_system_ext.h"
#include "securec.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
static td_void ai_free(td_void *buf)
{
if (buf == TD_NULL) {
return;
}
free(buf);
}
static td_void *ai_malloc(td_u32 size)
{
td_s32 ret;
td_void *buf = TD_NULL;
if (size == 0) {
soc_log_err("invalid size\n");
return TD_NULL;
}
buf = malloc(size);
if (buf == TD_NULL) {
soc_log_err("call malloc( failed\n");
return TD_NULL;
}
ret = memset_s(buf, size, 0, size);
if (ret != EOK) {
soc_err_print_call_fun_err(memset_s, ret);
free(buf);
return TD_NULL;
}
return buf;
}
/* when sync not found, return pos = (bytes - 3) */
static td_bool iec61937_parser_find_sync_word(const td_u8 *buf, td_u32 bytes, td_u32 *pos, td_bool *dtscd)
{
td_u32 state;
td_u32 i;
td_bool big_endian = TD_FALSE;
/* find IEC SYNC */
for (i = 0; i < (bytes - 3); i++) { /* 3 is a number */
state = (buf[i] << 24) | (buf[i + 1] << 16) | /* 24 and 16 is shift number */
(buf[i + 2] << 8) | buf[i + 3]; /* 8 is a shift number, 2 and 3 is serial number */
if ((state == IEC61937_SYNCWORD_LE) || (state == IEC61937_SYNCWORD_BE)) {
big_endian = (state == IEC61937_SYNCWORD_BE) ? TD_TRUE : TD_FALSE;
*dtscd = TD_FALSE;
*pos = i;
return big_endian;
}
}
/* find DTSCD */
for (i = 0; i < (bytes - 3); i++) { /* 3 is a number */
state = (buf[i] << 24) | (buf[i + 1] << 16) | /* 24 and 16 is shift number */
(buf[i + 2] << 8) | buf[i + 3]; /* 8 is a shift number, 2 and 3 is serial number */
if ((state == DCA_MARKER_RAW_BE) || (state == DCA_MARKER_RAW_LE) ||
(state == DCA_MARKER_14B_BE) || (state == DCA_MARKER_14B_LE)) {
*dtscd = TD_TRUE;
break;
}
}
*pos = i;
return big_endian;
}
static td_void iec61937_parser_get_frame_len(iec61937_parser_stream_type stream_type,
const td_u16 *buf, td_u32 *bytes)
{
td_u32 frame_len = 0;
switch (stream_type) {
case IEC61937_PARSER_STREAM_DD:
frame_len = buf[3] >> 3; /* 3 is a shift number */
break;
case IEC61937_PARSER_STREAM_DDP:
frame_len = buf[3]; /* 3 is a number */
break;
case IEC61937_PARSER_STREAM_DTS:
frame_len = buf[3] >> 3; /* 3 is a shift number */
frame_len = ((frame_len + 3) >> 2) << 2; /* 2 is a shift number, 3 is a number */
break;
case IEC61937_PARSER_STREAM_DTSHD:
frame_len = buf[9]; /* 9 is a number */
frame_len = ((frame_len + 3) >> 2) << 2; /* 2 is a shift number, 3 is a number */
break;
case IEC61937_PARSER_STREAM_MAT:
frame_len = buf[3]; /* 3 is a number */
break;
default:
soc_log_err("invalid iec61937 stream type!\n");
break;
}
*bytes = frame_len;
}
static td_void iec61937_parser_move_buf_to_head(iec61937_parser_state *state, const td_u8 *src_buf)
{
td_s32 ret;
ret = memmove_s(state->buffer, IEC61937_PARSER_LENGTH_MAX, src_buf, state->filled_len);
if (ret != EOK) {
soc_log_err("memmove_s failed,err = 0x%x\n", ret);
return;
}
state->free_len = state->alloc_len - state->filled_len;
}
static td_s32 iec61937_parser_build_burst_info_default(iec61937_parser_state *state, const td_u8 *src_buf,
td_u32 data_type)
{
state->filled_len -= LENGTH_OF_PA_AND_PB;
iec61937_parser_move_buf_to_head(state, src_buf + LENGTH_OF_PA_AND_PB);
soc_log_err("invalid IEC61937 data type!\n");
soc_err_print_u32(data_type);
if (data_type == IEC61937_DATATYPE_NULL) {
return SOC_ERR_AI_BITS_INVALID_DATA;
} else if (data_type == IEC61937_DATATYPE_PAUSE) {
return SOC_ERR_AI_BITS_PAUSE_DATA;
}
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
static const struct {
td_u32 data_type;
const td_char *str;
td_u32 stream_type;
td_u32 len;
} g_iec61937_parser[] = {
{ IEC61937_DATATYPE_AC3, "IEC61937_DATATYPE_AC3", IEC61937_PARSER_STREAM_DD, BITS_BURSTLENGTH_AC3 },
{ IEC61937_DATATYPE_EAC3, "IEC61937_DATATYPE_EAC3", IEC61937_PARSER_STREAM_DDP, BITS_BURSTLENGTH_EAC3 },
{ IEC61937_DATATYPE_DTS_TYPE_I, "IEC61937_DATATYPE_DTS_TYPE_I",
IEC61937_PARSER_STREAM_DTS, BITS_BURSTLENGTH_DTS_TYPE_I },
{ IEC61937_DATATYPE_DTS_TYPE_II, "IEC61937_DATATYPE_DTS_TYPE_II",
IEC61937_PARSER_STREAM_DTS, BITS_BURSTLENGTH_DTS_TYPE_II },
{ IEC61937_DATATYPE_DTS_TYPE_III, "IEC61937_DATATYPE_DTS_TYPE_III",
IEC61937_PARSER_STREAM_DTS, BITS_BURSTLENGTH_DTS_TYPE_III },
{ IEC61937_DATATYPE_MAT, "IEC61937_DATATYPE_MAT", IEC61937_PARSER_STREAM_MAT, BITS_BURSTLENGTH_MAT },
};
static td_s32 iec61937_parser_build_burst_info(iec61937_parser_state *state, td_u8 *src_buf)
{
/* data type: value of PC bit 0-4 */
td_u32 data_type = (td_u16)src_buf[4] & 0x1f; /* 4 is a serial number */
td_u32 i;
for (i = 0; i < (sizeof(g_iec61937_parser) / sizeof(g_iec61937_parser[0])); i++) {
if (data_type == g_iec61937_parser[i].data_type) {
soc_log_dbg("g_iec61937_parser[%d].data_type %s!\n", i, g_iec61937_parser[i].str);
state->stream_type = g_iec61937_parser[i].stream_type;
state->burst_len = g_iec61937_parser[i].len;
return TD_SUCCESS;
}
}
if (data_type == IEC61937_DATATYPE_DTS_TYPE_IV) {
soc_log_dbg("IEC61937_DATATYPE_DTS_TYPE_IV\n");
state->stream_type = IEC61937_PARSER_STREAM_DTSHD;
state->burst_len = (BITS_BURSTLENGTH_DTS_TYPE_I << ((td_u16)src_buf[5] & 0x7)); /* 5 is a serial number */
return TD_SUCCESS;
}
return iec61937_parser_build_burst_info_default(state, src_buf, data_type);
}
static td_s32 iec61937_parser_continual_dtscd(iec61937_parser_state *state)
{
td_bool dtscd = TD_FALSE;
td_u32 sync_skip = 0;
if (state->stream_type != IEC61937_PARSER_STREAM_DTS) {
if (state->filled_len < BITS_BURSTLENGTH_DTSCD + IEC61937_PARSER_LENGTH_MIN) {
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
(td_void)iec61937_parser_find_sync_word(state->buffer + BITS_BURSTLENGTH_DTSCD,
state->filled_len - BITS_BURSTLENGTH_DTSCD, &sync_skip, &dtscd);
if ((sync_skip != 0) || (dtscd != TD_TRUE)) {
state->filled_len -= (BITS_BURSTLENGTH_DTSCD + sync_skip);
state->total_discard_len += (BITS_BURSTLENGTH_DTSCD + sync_skip);
iec61937_parser_move_buf_to_head(state, state->buffer + BITS_BURSTLENGTH_DTSCD + sync_skip);
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
}
return TD_SUCCESS;
}
static td_bool iec61937_check_is_empty_frame(const td_u8 *buffer, td_u32 size)
{
td_u32 i;
for (i = 0; i < size; i++) {
if (*(buffer + i) != 0) {
return TD_FALSE;
}
}
return TD_TRUE;
}
static td_s32 iec61937_parser_handup_dtscd(iec61937_parser_state *state)
{
td_s32 ret;
soc_log_dbg("IEC61937_DATATYPE_DTSCD\n");
ret = iec61937_parser_continual_dtscd(state);
if (ret != TD_SUCCESS) {
soc_log_warn("iec61937_parser_continual_dtscd failed\n");
soc_err_print_err_code(ret);
return ret;
}
state->burst_len = BITS_BURSTLENGTH_DTSCD;
state->stream_type = IEC61937_PARSER_STREAM_DTS;
return TD_SUCCESS;
}
static td_s32 iec61937_parser_avoid_handup_dtscd(iec61937_parser_state *state)
{
td_s32 ret;
td_u32 cur_sys_time_ms;
/* avoid handup when getframelen */
if (state->filled_len < LENGTH_OF_PREAMBLE + DTSHD_HEADER_SIZE) {
ext_mpi_sys_get_time_stamp_ms(&cur_sys_time_ms);
if (state->first_empty_time == 0) {
state->first_empty_time = cur_sys_time_ms;
}
if (state->total_discard_len >= IEC61937_PARSER_LENGTH_MAX * 2) { /* 2 is a number */
return SOC_ERR_AI_FIND_SYNC_FAILED;
} else if (cur_sys_time_ms > state->first_empty_time + 1000) { /* 1000 means 1 second */
return SOC_ERR_AI_BITS_INVALID_DATA;
} else {
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
}
ret = iec61937_parser_build_burst_info(state, state->buffer);
if (ret != TD_SUCCESS) {
soc_log_err("iec61937_parser_build_burst_info failed\n");
soc_err_print_err_code(ret);
return ret;
}
if (state->stream_type != IEC61937_PARSER_STREAM_MAT) {
state->big_endian = TD_FALSE; /* only for turehd or mat */
}
return TD_SUCCESS;
}
static td_s32 iec61937_parser_build_burst_data(iec61937_parser_state *state, td_bool *dtscd)
{
td_s32 ret;
td_u32 sync_skip = 0;
state->big_endian = iec61937_parser_find_sync_word(state->buffer, state->filled_len, &sync_skip, dtscd);
if (sync_skip != 0) {
state->filled_len -= sync_skip;
state->total_discard_len += sync_skip;
iec61937_parser_move_buf_to_head(state, state->buffer + sync_skip);
}
if (*dtscd == TD_TRUE) {
ret = iec61937_parser_handup_dtscd(state);
if (ret != TD_SUCCESS) {
return ret;
}
} else {
/* avoid handup when getframelen */
ret = iec61937_parser_avoid_handup_dtscd(state);
if (ret != TD_SUCCESS) {
soc_log_warn("iec61937_parser_handup_dtscd failed\n");
return ret;
}
}
/* if successfully find sync, reset first_empty_time */
state->first_empty_time = 0;
state->total_discard_len = 0;
/* ensure release frame including the stuffing */
if (state->filled_len < state->burst_len) {
soc_log_warn("state->filled_len < state->burst_len\n");
soc_warn_print_u32(state->filled_len);
soc_warn_print_u32(state->burst_len);
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
return TD_SUCCESS;
}
#define IEC61937_PARSER_MAX_TIMES 150
static td_s32 iec61937_parser_build_burst_data_inner(iec61937_parser_state *state, td_bool *dtscd)
{
td_s32 ret;
td_u32 i;
ret = iec61937_parser_build_burst_data(state, dtscd);
/* PAUSE data should be consumed timely. */
if (ret == SOC_ERR_AI_BITS_PAUSE_DATA) {
for (i = 0; i < IEC61937_PARSER_MAX_TIMES; i++) {
ret = iec61937_parser_build_burst_data(state, dtscd);
if ((ret == TD_SUCCESS) || (ret == SOC_ERR_AI_PARSERBUF_EMPTY)) {
break;
}
}
}
if (ret != TD_SUCCESS) {
soc_warn_print_call_fun_err(iec61937_parser_build_burst_data, ret);
return ret;
}
return TD_SUCCESS;
}
static td_u32 iec61937_calc_frame_size(td_u32 ch, td_u32 bit_depth)
{
switch (bit_depth) {
case EXT_BIT_DEPTH_16:
return ch * sizeof(td_u16);
case EXT_BIT_DEPTH_24:
return ch * sizeof(td_u32);
default:
return 0;
}
}
td_s32 iec61937_parser_create(ext_parser_handle *parser)
{
iec61937_parser_state *state = TD_NULL;
check_ai_null_ptr(parser);
state = (iec61937_parser_state *)ai_malloc(sizeof(iec61937_parser_state));
if (state == TD_NULL) {
soc_log_err("malloc parser instance failed\n");
return SOC_ERR_AI_INSUFFICIENT_RESOURCES;
}
state->buffer = (td_u8 *)ai_malloc(IEC61937_PARSER_LENGTH_MAX);
if (state->buffer == TD_NULL) {
soc_log_err("malloc parser inner buffer failed\n");
ai_free(state);
return SOC_ERR_AI_INSUFFICIENT_RESOURCES;
}
state->free_len = IEC61937_PARSER_LENGTH_MAX;
state->alloc_len = IEC61937_PARSER_LENGTH_MAX;
state->stream_type = IEC61937_PARSER_STREAM_TYPE_MAX;
*parser = (ext_parser_handle)state;
return TD_SUCCESS;
}
td_void iec61937_parser_destroy(ext_parser_handle parser)
{
iec61937_parser_state *state = (iec61937_parser_state *)parser;
if (state == TD_NULL) {
return;
}
if (state->buffer != TD_NULL) {
/* no need to set state->buffer to NULL, because state is going to be free next */
ai_free(state->buffer);
}
ai_free(state);
}
td_s32 iec61937_parser_get_buf(ext_parser_handle parser, td_u32 request_size, iec61937_parser_stream_buf *stream)
{
iec61937_parser_state *state = TD_NULL_PTR;
td_u32 actual_req_size;
td_u32 frame_size;
check_ai_null_ptr(parser);
check_ai_null_ptr(stream);
state = (iec61937_parser_state *)parser;
stream->size = 0;
if (request_size == 0) {
return TD_SUCCESS;
}
frame_size = iec61937_calc_frame_size(state->channel, state->bit_depth);
if (frame_size == 0) {
soc_log_err("invalid parameter!\n");
soc_err_print_u32(state->channel);
soc_err_print_u32(state->bit_depth);
return SOC_ERR_AI_INVALID_PARA;
}
/* ensure actual_req_size - filled_len is aligned with frame_size */
actual_req_size = request_size;
if ((state->stream_type == IEC61937_PARSER_STREAM_PCM) ||
(state->stream_type == IEC61937_PARSER_STREAM_UNKNOWN) ||
(state->stream_type == IEC61937_PARSER_STREAM_TYPE_MAX)) {
actual_req_size += (state->filled_len % frame_size);
}
if (actual_req_size > IEC61937_PARSER_LENGTH_MAX) {
soc_log_err("request_size is too big!\n");
soc_err_print_u32(request_size);
soc_err_print_u32(actual_req_size);
return SOC_ERR_AI_INVALID_PARA;
}
if (request_size > state->filled_len) {
stream->data = state->buffer + state->filled_len;
stream->size = actual_req_size - state->filled_len;
}
return TD_SUCCESS;
}
td_s32 iec61937_parser_put_buf(ext_parser_handle parser, iec61937_parser_stream_buf *stream)
{
iec61937_parser_state *state = TD_NULL_PTR;
check_ai_null_ptr(parser);
check_ai_null_ptr(stream);
check_ai_null_ptr(stream->data);
if (stream->size == 0) {
return TD_SUCCESS;
}
state = (iec61937_parser_state *)parser;
if (stream->size > state->free_len) {
soc_log_err("size is bigger then free_len\n");
soc_err_print_u32(stream->size);
soc_err_print_u32(state->free_len);
return SOC_ERR_AI_INVALID_PARA;
}
state->free_len -= stream->size;
state->filled_len += stream->size;
return TD_SUCCESS;
}
static inline td_u16 swapbit_16(td_u16 x)
{
td_u16 res = (x >> 8) | (x << 8); /* shift right 8 bits, shift left 8 bits */
return res;
}
static td_void big_endian2_little_endian(td_u8 *io, td_s32 bytes)
{
td_s32 i;
td_u16 *data = (td_u16 *)io;
td_u16 pcm_data;
for (i = 0; i < bytes / 2; i++) { /* 2 is a number */
pcm_data = *data;
*data++ = swapbit_16(pcm_data);
}
}
static td_void iec61937_parser_acquire_dtscd_frame(iec61937_parser_state *state)
{
state->frame_buf = state->buffer;
state->frame_len = BITS_BURSTLENGTH_DTSCD;
}
static td_s32 iec61937_parser_acquire_mat_frame(iec61937_parser_state *state)
{
state->frame_buf = state->buffer;
state->frame_len = BITS_BURSTLENGTH_MAT;
if (state->filled_len < state->frame_len) {
soc_log_warn("frame_len < filled_len");
soc_warn_print_u32(state->frame_len);
soc_warn_print_u32(state->filled_len);
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
if (state->big_endian == TD_TRUE) {
big_endian2_little_endian(state->buffer, BITS_BURSTLENGTH_MAT);
}
return TD_SUCCESS;
}
static td_s32 iec61937_parser_acquire_other_frame(iec61937_parser_state *state)
{
iec61937_parser_get_frame_len(state->stream_type, (td_u16 *)state->buffer, &state->frame_len);
if ((state->frame_len == 0) || (state->frame_len > BITS_BURSTLENGTH_MAT)) {
state->filled_len -= LENGTH_OF_PA_AND_PB;
iec61937_parser_move_buf_to_head(state, state->buffer + LENGTH_OF_PA_AND_PB);
soc_log_err("invalid frame_len!\n");
soc_err_print_u32(state->frame_len);
return SOC_ERR_AI_BITS_INVALID_DATA;
}
if (state->filled_len < state->frame_len) {
soc_log_warn("frame_len < filled_len\n");
soc_warn_print_u32(state->frame_len);
soc_warn_print_u32(state->filled_len);
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
if ((state->stream_type == IEC61937_PARSER_STREAM_DTSHD) || (state->stream_type == IEC61937_PARSER_STREAM_MAT)) {
state->frame_buf = state->buffer + LENGTH_OF_PREAMBLE + DTSHD_HEADER_SIZE;
} else {
state->frame_buf = state->buffer + LENGTH_OF_PREAMBLE;
}
return TD_SUCCESS;
}
td_s32 iec61937_parser_acquire_frame(ext_parser_handle parser, td_void *dst_buf, td_u32 *frame_len)
{
td_s32 ret;
td_bool dtscd = TD_FALSE;
td_u8 **pp_dst_buf = TD_NULL_PTR;
iec61937_parser_state *state = TD_NULL_PTR;
check_ai_null_ptr(parser);
check_ai_null_ptr(dst_buf);
check_ai_null_ptr(frame_len);
state = (iec61937_parser_state *)parser;
pp_dst_buf = (td_u8 **)dst_buf;
/* avoid acquire frame much times without release frame */
if (state->frame_is_ready == TD_TRUE) {
soc_log_warn("call iec61937_parser_acquire_frame continuously many times!\n");
*pp_dst_buf = state->frame_buf;
*frame_len = state->frame_len;
return TD_SUCCESS;
}
*frame_len = 0; /* avoid acquire fail and do release */
if ((state->filled_len < IEC61937_PARSER_LENGTH_MIN) || (state->filled_len > IEC61937_PARSER_LENGTH_MAX)) {
soc_log_warn("state->filled_len is not fit!\n");
soc_warn_print_u32(state->filled_len);
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
ret = iec61937_parser_build_burst_data_inner(state, &dtscd);
if (ret != TD_SUCCESS) {
soc_log_warn("iec61937_parser_build_burst_data_inner failed\n");
soc_warn_print_h32(ret);
return ret;
}
check_ai_null_ptr(state->buffer);
if (dtscd == TD_TRUE) {
iec61937_parser_acquire_dtscd_frame(state);
} else if (state->stream_type == IEC61937_PARSER_STREAM_MAT) {
ret = iec61937_parser_acquire_mat_frame(state);
if (ret != TD_SUCCESS) {
return ret;
}
} else {
ret = iec61937_parser_acquire_other_frame(state);
if (ret != TD_SUCCESS) {
return ret;
}
}
*pp_dst_buf = state->frame_buf;
*frame_len = state->frame_len;
state->frame_is_ready = TD_TRUE;
return TD_SUCCESS;
}
td_s32 iec61937_parser_release_frame(ext_parser_handle parser, td_u32 frame_len)
{
iec61937_parser_state *state = TD_NULL_PTR;
check_ai_null_ptr(parser);
if (frame_len == 0) {
return TD_SUCCESS;
}
state = (iec61937_parser_state *)parser;
/* avoid release frame much times without acquire frame */
if (state->frame_is_ready == TD_FALSE) {
soc_log_warn("call iec61937_parser_release_frame continuously many times!");
return TD_SUCCESS;
}
if (state->filled_len < state->burst_len) {
soc_log_err("filled_len < burst_len, release failed!");
soc_err_print_u32(state->filled_len);
soc_err_print_u32(state->burst_len);
return SOC_ERR_AI_INVALID_PARA;
}
state->frame_is_ready = TD_FALSE;
state->filled_len -= state->burst_len;
iec61937_parser_move_buf_to_head(state, state->buffer + state->burst_len);
return TD_SUCCESS;
}
td_s32 iec61937_parser_get_stream_type(ext_parser_handle parser, iec61937_parser_stream_type *stream_type)
{
td_s32 ret;
td_bool dtscd = TD_FALSE;
iec61937_parser_state *state = TD_NULL_PTR;
check_ai_null_ptr(parser);
check_ai_null_ptr(stream_type);
state = (iec61937_parser_state *)parser;
*stream_type = state->stream_type;
if ((state->stream_type != IEC61937_PARSER_STREAM_UNKNOWN) &&
(state->stream_type != IEC61937_PARSER_STREAM_TYPE_MAX)) {
*stream_type = state->stream_type;
return TD_SUCCESS;
}
if ((state->filled_len < IEC61937_PARSER_LENGTH_MIN) ||
(state->filled_len > IEC61937_PARSER_LENGTH_MAX)) {
soc_log_warn("state->filled_len is not fit!\n");
soc_warn_print_u32(state->filled_len);
return SOC_ERR_AI_PARSERBUF_EMPTY;
}
ret = iec61937_parser_build_burst_data_inner(state, &dtscd);
if (ret != TD_SUCCESS) {
soc_log_warn("iec61937_parser_build_burst_data_inner failed\n");
soc_err_print_err_code(ret);
return ret;
}
*stream_type = state->stream_type;
return TD_SUCCESS;
}
td_s32 iec61937_parser_get_burst_len(ext_parser_handle parser, td_u32 *burst_len)
{
iec61937_parser_state *state = TD_NULL_PTR;
check_ai_null_ptr(parser);
check_ai_null_ptr(burst_len);
state = (iec61937_parser_state *)parser;
if ((state->stream_type == IEC61937_PARSER_STREAM_UNKNOWN) ||
(state->stream_type == IEC61937_PARSER_STREAM_TYPE_MAX)) {
/* A proper value enough to parse all stream type and to synchronize. */
*burst_len = BITS_BURSTLENGTH_DTS_TYPE_III;
return TD_SUCCESS;
}
if ((state->burst_len) > BITS_BURSTLENGTH_MAT) {
soc_log_err("burst length is too big!");
soc_err_print_u32(state->burst_len);
return SOC_ERR_AI_BITS_INVALID_DATA;
} else {
*burst_len = state->burst_len;
return TD_SUCCESS;
}
}
td_bool iec61937_check_is_empty(ext_parser_handle parser)
{
iec61937_parser_state *state = (iec61937_parser_state *)parser;
if ((state == TD_NULL) || (state->buffer == TD_NULL)) {
return TD_FALSE;
}
if (iec61937_check_is_empty_frame(state->buffer, state->filled_len) == TD_TRUE) {
state->filled_len = 0;
state->free_len = state->alloc_len;
return TD_TRUE;
}
return TD_FALSE;
}
#ifdef __cplusplus
}
#endif /* __cplusplus */