/******************************************************************************
* function : get frame from Ai, send it  to Aenc or Ao
******************************************************************************/
void *SAMPLE_COMM_AUDIO_AiProc(void *parg)
{
    HI_S32 s32Ret;
    HI_S32 AiFd;
    SAMPLE_AI_S *pstAiCtl = (SAMPLE_AI_S *)parg;
    AUDIO_FRAME_S stFrame; 
    AEC_FRAME_S stRefFrame;
    fd_set read_fds;
    struct timeval TimeoutVal;
    AI_CHN_PARAM_S stAiChnPara;
    

    s32Ret = HI_MPI_AI_GetChnParam(pstAiCtl->AiDev, pstAiCtl->AiChn, &stAiChnPara);
    if (HI_SUCCESS != s32Ret)
    {
        printf("%s: Get ai chn param failed\n", __FUNCTION__);
        return NULL;
    }
    
    stAiChnPara.u32UsrFrmDepth = 30;
    
    s32Ret = HI_MPI_AI_SetChnParam(pstAiCtl->AiDev, pstAiCtl->AiChn, &stAiChnPara);
    if (HI_SUCCESS != s32Ret)
    {
        printf("%s: set ai chn param failed\n", __FUNCTION__);
        return NULL;
    }
    
    FD_ZERO(&read_fds);
    AiFd = HI_MPI_AI_GetFd(pstAiCtl->AiDev, pstAiCtl->AiChn);
    FD_SET(AiFd,&read_fds);
    
    while (pstAiCtl->bStart)
    {     
        TimeoutVal.tv_sec = 1;
        TimeoutVal.tv_usec = 0;
        
        FD_ZERO(&read_fds);
        FD_SET(AiFd,&read_fds);
        
        s32Ret = select(AiFd+1, &read_fds, NULL, NULL, &TimeoutVal);
        if (s32Ret < 0) 
        {
            break;
        }
        else if (0 == s32Ret) 
        {
            printf("%s: get ai frame select time out\n", __FUNCTION__);
            continue;
        }        
        
        if (FD_ISSET(AiFd, &read_fds))
        {
            /* get frame from ai chn */
            s32Ret = HI_MPI_AI_GetFrame(pstAiCtl->AiDev, pstAiCtl->AiChn,
                &stFrame, &stRefFrame, HI_FALSE);
            if (HI_SUCCESS != s32Ret )
            {
                printf("%s: HI_MPI_AI_GetFrame(%d, %d), failed with %#x!\n",\
                       __FUNCTION__, pstAiCtl->AiDev, pstAiCtl->AiChn, s32Ret);
                //pstAiCtl->bStart = HI_FALSE;
                //return NULL;
                continue;
            }


            /* send frame to encoder */
            if (HI_TRUE == pstAiCtl->bSendAenc)
            {
                HI_MPI_AENC_SendFrame(pstAiCtl->AencChn, &stFrame, &stRefFrame);
            }
            
            /* send frame to ao */
            if (HI_TRUE == pstAiCtl->bSendAo)
            {
                HI_MPI_AO_SendFrame(pstAiCtl->AoDev, pstAiCtl->AoChn,
                    &stFrame, HI_TRUE);
            }

            /* finally you must release the stream */
            HI_MPI_AI_ReleaseFrame(pstAiCtl->AiDev, pstAiCtl->AiChn,
                &stFrame, &stRefFrame);
            usleep(10000);
        }
    }
    
    pstAiCtl->bStart = HI_FALSE;
    return NULL;
}
/*
 * 获取音频数据,格式为PCM
 */
int unidoli_aduio_read(AUDIO_DEV AiDev, AI_CHN AiChn, void *buf, uint32_t max_len, uint32_t *pts, uint32_t *id)
{
    HI_S32 s32Ret;
    AI_CHN_PARAM_S stAiChnPara;

    s32Ret = HI_MPI_AI_GetChnParam(AiDev, AiChn, &stAiChnPara);
    if (HI_SUCCESS != s32Ret) {
        printf("%s: Get ai chn param failed\n", __FUNCTION__);
        return -1;
    }

    stAiChnPara.u32UsrFrmDepth = 30;

    s32Ret = HI_MPI_AI_SetChnParam(AiDev, AiChn, &stAiChnPara);
    if (HI_SUCCESS != s32Ret) {
        printf("%s: set ai chn param failed\n", __FUNCTION__);
        return -1;
    }

    fd_set read_fds;
    FD_ZERO(&read_fds);
    HI_S32 AiFd = HI_MPI_AI_GetFd(AiDev, AiChn);
    FD_SET(AiFd, &read_fds);

    struct timeval TimeoutVal;
    TimeoutVal.tv_sec = 1;
    TimeoutVal.tv_usec = 0;
    FD_ZERO(&read_fds);
    FD_SET(AiFd, &read_fds);

    s32Ret = select(AiFd + 1, &read_fds, NULL, NULL, &TimeoutVal);
    if (s32Ret < 0) {
        return -1;
    } else if (0 == s32Ret) {
        printf("%s: get ai frame select time out.\n", __FUNCTION__);
        return -1;
    }

    int buf_len = 0;
    if (FD_ISSET(AiFd, &read_fds)) {
        /* get frame from ai chn */
        AUDIO_FRAME_S stFrame;
        AEC_FRAME_S   stAecFrm;
        memset(&stAecFrm, 0, sizeof(AEC_FRAME_S));
        s32Ret = HI_MPI_AI_GetFrame(AiDev, AiChn, &stFrame, &stAecFrm, HI_FALSE);
        if (HI_SUCCESS != s32Ret ) {
            printf("%s: get ai frame failed.\n", __FUNCTION__);
            return -1;
        }

        //printf("id:%d len:%d time:%lld\r\n", stFrame.u32Seq, stFrame.u32Len, stFrame.u64TimeStamp/1000);
        buf_len = stFrame.u32Len;
        *pts = stFrame.u64TimeStamp/1000;
        *id = stFrame.u32Seq;
        if(buf_len < max_len) {
            memcpy(buf, stFrame.pVirAddr[0], buf_len);
        } else {
            printf("%s: max len failed.\n", __FUNCTION__);
            return -1;
        }

        /* finally you must release the stream */
        s32Ret = HI_MPI_AI_ReleaseFrame(AiDev, AiChn, &stFrame, &stAecFrm);
        if (HI_SUCCESS != s32Ret ) {
            printf("%s: HI_MPI_AI_ReleaseFrame(%d, %d), failed with %#x!\n", __FUNCTION__, AiDev, AiChn, s32Ret);
            return -1;
        }
    }

    return buf_len;
}