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

📄 video_dec.c

📁 sample on embedded linux
💻 C
📖 第 1 页 / 共 4 页
字号:
        return;    }    arg.ChanID = ChanID[chindex];    arg.chnum = Maxchnum;    s32vdecthreadflag = 1;    /*create thread which is used for recive data*/    pthread_create(&thread, NULL, receive_thread_multi, &arg);    stream.Dataaddr = (ADDR)streambuf;    pts = 0;    fbuf_pointer = 0;    fbuf_bytes_num = 0;    while(1)    {        if (4 != Fread(&len_nalu, 1, 4, fhStream))        {            printf("read nalu length error.\n");            break;        }        stream.Datalen = len_nalu;        len_nalu = HI_ALIGN_LENGTH(len_nalu, 2);        if ( len_nalu != Fread(streambuf+4, 1,len_nalu, fhStream) )        {            printf("read nalu error.\n");            break;        }        stream.Datalen += 4;        stream.pts = pts;                for (i=0;i<Maxchnum;i++)        {            ret = HI_VDEC_SendStream(ChanID[i], &stream, HI_TRUE);            while(HI_SUCCESS != ret)            {                if(HI_ERR_VDEC_NO_PAYLOAD == ret)break;                ret = HI_VDEC_SendStream(ChanID[i], &stream, HI_TRUE);            }        }        pts++;        if (10000== pts)break;    }    fclose(fhStream);    /*wait until all the data is decoded over*/    usleep(500000);    s32vdecthreadflag = 0;    pthread_join(thread, NULL);    /*destroy all the decode channel*/    for (i=0;i<Maxchnum;i++)    {        ret = HI_VDEC_DestroyCH(ChanID[i]);        if (HI_SUCCESS == ret)        {            printf("test_Video_Decoder_MultiChannel:destroy ch %d\n",ChanID[i]);        }    }    free(streambuf);}RTP_RECV_S* pRtpRecvStream = NULL;#define default_port 6666#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;/*read data form receive buffer and send it to decoder*/void* sendstream_thread(void *args){    VDEC_RECEIVE_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%2))printf("discardcount %d\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])) = 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%2))printf("discardcount %d\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])) = 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;}/*receive frame data , it receive data and send to VO for real time frame presentation,if send vo failed,discard this frame*/void* receive_thread_realmode(void *args){    VDEC_RECEIVE_THTREAD_ARGS *parg = args;    HI_S32  ret;    HI_BOOL bBlock = HI_FALSE;    volatile HI_U64 count = 0;        pid_t  pid;    pid = getpid();    printf("receive_thread  pid %d\n",pid);    VDEC_FRAMEINFO_S frameinfo;    while(s32vdecthreadflag)    {         count ++;        HI_VDEC_Receive(parg->ChanID, &frameinfo, NULL, bBlock);        if (frameinfo.value)        {            /*VO will release the data, user not need to care it. if the data isn't send to VO, user need call HI_VDEC_ReleaseVideoBuf to release buffer*/            ret = HI_VO_SendData(VO_CHN0, &frameinfo);            if(HI_SUCCESS != ret)             {                /*if send vo failed , discard this frame*/                HI_VDEC_ReleaseVideoBuf(parg->ChanID, &frameinfo);            }        }                /*don't call HI_VDEC_Receive frequency*/        if(!(count % 5))         {            usleep(10);        }    }    printf("break while!\n");    pthread_exit(NULL);}/*receive rtp packet from the static socket, and send it to decoder*/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_receiveframe;    pthread_t thread_receivestream;    static VDEC_RECEIVE_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, default_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;    s32vdecthreadflag = 1;    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);    arg.ChanID = ChanID;    s32vdecthreadflag = 1;    /*start thread to receive frame, and send it to vo*/    pthread_create(&thread_receiveframe, NULL, receive_thread_realmode, &arg);    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);    s32vdecthreadflag = 0;    pthread_join(thread_receiveframe, NULL);       printf("after receive frame thread exit!\n");    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);}char args[10][255];/*parameter parse*/static void parsearg(int argc){    if(0 == strcmp("dec", args[0])&& 1 == argc)    {        test_Video_Decoder_Process();    }    else if(0 == strcmp("dec", args[0]) && 2 == argc)    {        test_Video_Decoder_Process1(args[1]);    }    else if(0 == strcmp("cap", args[0]))    {        test_HI_VDEC_GetCapability();    }    else if(0 == strcmp("testmulti", args[0]) && 3 == argc)    {        test_Video_Decoder_MultiChannel(args[1],args[2]);    }    else if(0 == strcmp("rcv", args[0]) && 1 == argc)    {        test_Video_Decoder_Rtp_Receiver();    }    else    {        printf("input dec : decode file dec.h264\n");        printf("input dec xxx: decode file xxx\n");        printf("input cap : get capability\n");        printf("input testmulti x y: test x channels decode, send channel[y] to vo!x(1~4) y(0~3) y<x\n");        printf("input rcv : receive rtp packet at port 6666\n");    }}/*adjust input parameter*/static int adjust_str(char *ptr){	int i;	while(*ptr==' ' && *ptr++ != '\0');	for(i=strlen(ptr);i>0;i--)	{		if(*(ptr+i-1) == 0x0a || *(ptr+i-1) == ' ')			*(ptr+i-1) = '\0';		else			break;	}	for(i=0;i<10;i++)	{		int j = 0;		while(*ptr==' ' && *ptr++ != '\0');		while((*ptr !=' ') && (*ptr!='\0'))		{			args[i][j++] = *ptr++;		}		args[i][j] = '\0';		if('\0' == *ptr)		{			i++;			break;		}		args[i][j] = '\0';	}	return i;}int main(int argc, char* argv[]){    char buffer[256];    char *ptr;    HI_S32 ret;    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();    if ( ret != HI_SUCCESS )    {        printf("HI_VDEC_Open failed!\n");        return ret;    }        vo_open();    //test_Video_Decoder_Process();    for(;;)    {        printf("> ");        ptr = fgets(buffer, 255, stdin);        memset(args, 0, sizeof(args));        argc = adjust_str(ptr);        if(0 == strcmp("q", args[0]) || 0 == strcmp("Q", args[0]))        {            vo_close();               HI_VDEC_Close();            return 0;        }        parsearg(argc);    }        return 1;}

⌨️ 快捷键说明

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