⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 receiver.c

📁 sample on embedded linux
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "avcommon.h"#include "hi_rtp.h"#include "avsync.h"#define VO_CHN0 0static VIDEO_NORM_E compose_mode  = VIDEO_ENCODING_MODE_PAL;static HI_BOOL      g_bZoomEnable = HI_TRUE;/*VO open*/HI_S32 vo_open(void){    HI_S32            s32Ret;    VO_CHN_ATTR_S     l_chn_attr ;    VO_PUBLIC_ATTR_S  l_pub_attr;        HI_VO_Init();    s32Ret = HI_VO_GetPublicAttr (&l_pub_attr);    ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret);    l_pub_attr.enable       = HI_TRUE;    l_pub_attr.bOutputScale = g_bZoomEnable;    /* TV mode */    l_pub_attr.display_mode            = VO_MODE_BT656;    l_pub_attr.tv_config.enMaster      = VIDEO_CONTROL_MODE_MASTER;    l_pub_attr.tv_config.compose_mode  = compose_mode;    l_pub_attr.tv_config.seriatim_mode = HI_TRUE;    l_pub_attr.background_color        = 0x00ff00;   /* blue */        l_pub_attr.vo_chn_img_num = 4;    l_pub_attr.pip_buf_num = 4;    l_pub_attr.vo_chn_img_num = 4;    l_pub_attr.pip_buf_num = 4;    s32Ret = HI_VO_SetPublicAttr (&l_pub_attr);    ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret);    s32Ret = HI_VO_GetChnAttr(VO_CHN0, &l_chn_attr);    ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret);    l_chn_attr.enable          = HI_TRUE;    l_chn_attr.rectangle.x     = 0;    l_chn_attr.rectangle.y     = 0;    l_chn_attr.rectangle.width = 720;        if(compose_mode == VIDEO_ENCODING_MODE_PAL)    {        l_chn_attr.rectangle.height = 576;    }    else    {        l_chn_attr.rectangle.height = 480;    }    l_chn_attr.zoom_enable =  g_bZoomEnable;    s32Ret = HI_VO_SetChnAttr (VO_CHN0, &l_chn_attr);    ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret);    return HI_SUCCESS;}/*VO close*/HI_S32 vo_close(void){    HI_S32 s32Ret;        VO_CHN_ATTR_S     l_chn_attr ;    VO_PUBLIC_ATTR_S  l_pub_attr ;        s32Ret = HI_VO_GetChnAttr (VO_CHN0, &l_chn_attr);    ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret);    l_chn_attr.enable = HI_FALSE;    s32Ret = HI_VO_SetChnAttr (VO_CHN0, &l_chn_attr);    ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret);    /* Disable VO */    s32Ret = HI_VO_GetPublicAttr (&l_pub_attr);    ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret);    l_pub_attr.enable = HI_FALSE ;    s32Ret = HI_VO_SetPublicAttr (&l_pub_attr);    ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret);    return HI_SUCCESS;}#define PACKET_HEADER_SIZE 8#define RECEIVEBUF_NUM 200HI_S32 file_fd;HI_S32 onrecv_count = 0;HI_CHAR receivebuf[RECEIVEBUF_NUM][2048+PACKET_HEADER_SIZE];volatile HI_S32 read_pointer;volatile HI_S32 write_pointer;#define HI_ALIGN_LENGTH(v,a) ((((v) + ((a)-1)) & (~((a)-1))))HI_S32 s32vdecsendthreadflag;RTP_RECV_S* pRtpRecvStream = NULL;/*read data form receive buffer and send it to decoder*/void* sendstream_thread(void *args){    VDEC_THTREAD_ARGS *parg = args;    HI_S32 retrycount = 0;    VDEC_STREAM_S stream;    HI_S32 ret;    pid_t  pid;    pid = getpid();    printf("sendstream thread pid %d\n",pid);    while(s32vdecsendthreadflag)    {        while(read_pointer != write_pointer)        {            stream.Dataaddr = (ADDR)&receivebuf[read_pointer][8];            stream.Datalen = *((HI_S32 *)(&receivebuf[read_pointer][0]));            stream.pts = *((HI_S32 *)(&receivebuf[read_pointer][4]));            ret = HI_VDEC_SendStream(parg->ChanID, &stream, HI_TRUE);            while(HI_SUCCESS != ret)            {                if(HI_ERR_VDEC_NO_PAYLOAD == ret)break;                if(retrycount > 80000)                {                    printf("HI_VDEC_SendStream failed at %d retries\n",retrycount);                    //exit(1);                    break;                }                retrycount++;                if(!((retrycount)%3))                {                    usleep(10);                }                ret = HI_VDEC_SendStream(parg->ChanID, &stream, HI_TRUE);            }                        retrycount = 0;            read_pointer++;            //printf("read_pointer %d\n",read_pointer);            if(read_pointer == RECEIVEBUF_NUM)read_pointer = 0;        }                usleep(100);    }        printf("sendstream_thread break while!\n");    pthread_exit(NULL);}volatile long discardcount=0;/*deal with rtp packet*/int onrecv(IN struct hiRTP_RECV_S  * pRtpStream, unsigned char * pBuff,  unsigned int len, int *ext_args){    RTP_HDR_S *pheader = (RTP_HDR_S *)pBuff;            //write(file_fd, pBuff+12, len-12);    onrecv_count++;    if (read_pointer <= write_pointer)    {        /*overload warning*/        if(write_pointer-read_pointer >= RECEIVEBUF_NUM*4/5)        {            discardcount++;            if(!(discardcount%100))printf("discardcount %ld\n",discardcount);fflush(stdout);            return 1;        }                if(read_pointer+RECEIVEBUF_NUM == write_pointer+1)        {            printf("no receive buf !\n");            exit(-1);            return 1;        }        *((HI_S32 *)(&receivebuf[write_pointer][0])) = len - RTP_HDR_LEN;        *((HI_S32 *)(&receivebuf[write_pointer][4])) = ntohl(pheader->ts);        memcpy(&receivebuf[write_pointer][8],(void *)(pBuff + RTP_HDR_LEN),len - RTP_HDR_LEN);        write_pointer++;        if(RECEIVEBUF_NUM == write_pointer)write_pointer=0;    }    else    {        /*overload warning*/        if(write_pointer+RECEIVEBUF_NUM-read_pointer >= RECEIVEBUF_NUM*4/5)        {            //printf("receive buf is nearly full! \n");            discardcount++;            if(!(discardcount%100))printf("discardcount %ld\n",discardcount);fflush(stdout);            return 1;        }        if(write_pointer+1 == read_pointer)        {            printf("no receive buf !\n");            exit(-1);            return 1;        }        *((HI_S32 *)(&receivebuf[write_pointer][0])) = len - RTP_HDR_LEN;        *((HI_S32 *)(&receivebuf[write_pointer][4])) = ntohl(pheader->ts);        memcpy(&receivebuf[write_pointer][8],(void *)(pBuff + RTP_HDR_LEN),len - RTP_HDR_LEN);        write_pointer++;    }    if (len > 0x800)printf("stream.Datalen %x\n",len);    //printf("ChanID %d",ChanID);#if 0        ret = HI_VDEC_SendStream(ChanID, &stream);    while(HI_SUCCESS != ret)    {        /*防止解码器挂死后程序进入无限死循环*/        if(retrycount > 500000)        {            printf("HI_VDEC_SendStream failed at %d retries\n",retrycount);            return -1;        }        ret = HI_VDEC_SendStream(ChanID, &stream);        retrycount++;    }#endif        return 1;}void test_Video_Decoder_Rtp_Receiver(){    VDEC_CHN ChanID;    VDEC_ATTR_TYPE_E type = VDEC_ATTR_ALL;    VDEC_ChannelPara_S config;    HI_S32 ret;    pthread_t thread_receivestream;    static VDEC_THTREAD_ARGS arg;    char filename[255] = "receive.h264";    file_fd = open(filename, O_RDWR | O_TRUNC | O_CREAT ,0664);    /*set config value*/    config.type = VDEC_H264;    config.framenumber = 5;    config.picformat = VDEC_DEFAULT_PICTUREFORMAT;    ret = HI_VDEC_CreateCH(&ChanID, type, &config);      if (HI_SUCCESS == ret)    {        printf("test_Video_Decoder_Rtp_Receiver:Create a Channel: %d\n",ChanID);    }    else    {        printf("test_Video_Decoder_Rtp_Receiver:Failed to Create a Channel!!!\n");        return;    }    if (HI_SUCCESS == HI_RTP_Recv_Create(&pRtpRecvStream, VIDEO_PORT, onrecv, &ChanID))    {        printf("Create RTP Recevier OK.\n");    }    /*init the receive buffer*/    memset(receivebuf, 0 , sizeof(receivebuf));    read_pointer = 0;    write_pointer = 0;        arg.ChanID = ChanID;    s32vdecsendthreadflag = 1;    /*start thread to send stream*/    pthread_create(&thread_receivestream, NULL, sendstream_thread, &arg);    /*start rtp thread to receive data */    HI_RTP_Recv_Start(pRtpRecvStream);    AVSYNC_Frame2Vo_Start(ChanID);    while(1)    {        int c;        c = getchar();        if('q' == c)break;    }    s32vdecsendthreadflag = 0;    pthread_join(thread_receivestream, NULL);       printf("after send stream thread exit!\n");    usleep(100);    AVSYNC_Frame2Vo_Stop();    HI_RTP_Recv_Destroy(pRtpRecvStream);    printf("after receive rtp thread exit!\n");    usleep(100);    HI_VDEC_DestroyCH(ChanID);    close(file_fd);    printf("onrecv_count %d\n",onrecv_count);}RTP_RECV_S* pRtpAudioRecvStream = NULL;void test_Audio_Decoder_Rtp_Receiver(){      AUDIO_CODEC_FORMAT_E enType = AUDIO_CODEC_FORMAT_AAC;    ADEC_CHN        decChnID;    int ret;    printf("test_Audio_Decoder_Rtp_Receiver pid %d\n",getpid());fflush(stdout);    if(AUDIO_CODEC_FORMAT_AAC == enType)    {        /* Set the sample rate of audio AD and SIO as 48K.*/        SetADSampleRate(SET_48K_SAMPLERATE);        SetAiSampleRate(0, AUDIO_SAMPLE_RATE_48);      }    else    {        /* Set the sample rate of audio AD and SIO as 8K.*/            SetADSampleRate(SET_8K_SAMPLERATE);        SetAiSampleRate(0, AUDIO_SAMPLE_RATE_8);    }    /* Create and start audio decoder channel */    ret = HI_ADEC_CreateCH(0, enType, HI_TRUE, &decChnID);    ASSERT_RETURN((HI_SUCCESS==ret), ret);    printf("1 decChnID %d\n",decChnID);    ret = HI_ADEC_StartCH(decChnID, 0);    ASSERT_RETURN((HI_SUCCESS==ret), ret);    if (HI_SUCCESS == HI_RTP_Recv_Create(&pRtpAudioRecvStream, AUDIO_PORT, audio_onrecv, &decChnID))    {        printf("Create AUDIO RTP Recevier OK.\n");    }    /*start rtp thread to receive data */    HI_RTP_Recv_Start(pRtpAudioRecvStream);    while(1)    {        sleep(1);    }    }int main(int argc, char *argv[]){    int ret;    pthread_t video_thread;    pthread_t audio_thread;    printf("main pid %d\n",getpid());    if(argc >= 2)    {        compose_mode = (VIDEO_NORM_E)(atoi(argv[1]));    }    printf("compose_mode = %d [0~PAL, 1~NTSC]\n", compose_mode);    if(argc >= 3)    {        g_bZoomEnable = (atoi(argv[2]) == 1) ? HI_TRUE : HI_FALSE;    }    printf("Zoom enbale is %s\n", g_bZoomEnable?"TRUE":"FALSE");    /*open video decode device*/    ret = HI_VDEC_Open();    ASSERT_RETURN((HI_SUCCESS==ret), ret);    /*open vo device*/    ret = vo_open();    ASSERT_RETURN((HI_SUCCESS==ret), ret);        /*open audio decode device*/    ret = HI_ADEC_Open();    ASSERT_RETURN((HI_SUCCESS==ret), ret);    AVSYNC_Start();    //test_Video_Decoder_Rtp_Receiver();    pthread_create(&video_thread, NULL, (void *)test_Video_Decoder_Rtp_Receiver, NULL);    pthread_create(&audio_thread, NULL, (void *)test_Audio_Decoder_Rtp_Receiver, NULL);    while(1)    {        sleep(1);    }    AVSYNC_Stop();    vo_close();       HI_VDEC_Close();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -