video_dec.c

来自「sample on embedded linux」· C语言 代码 · 共 1,783 行 · 第 1/4 页

C
1,783
字号
    HI_S32 ret;    VERSION_INFO_S Version;    ret = HI_VDEC_GetCapability(&Cap);    if(HI_SUCCESS != ret)    {        printf("HI_VDEC_GetCapability failed!\n");        return;    }    printf("VDEC Capability: Max Channel Number %d\n",Cap.channels);    printf("VDEC Capability: Version %s\n",Cap.version);    printf("VDEC Capability: Support Decoder Type: ");    if(Cap.vdec_ability[VDEC_H264].support)    {        printf("H264 ");    }    if(Cap.vdec_ability[VDEC_MPEG2].support)    {        printf("MPEG2 ");    }    if(Cap.vdec_ability[VDEC_H263].support)    {        printf("H263 ");        printf("mq_mode %d\n",((VDEC_H263CAPABILITY_S*)(Cap.vdec_ability[VDEC_H263].value))->mq_mode);        printf("cif %d\n",((VDEC_H263CAPABILITY_S*)(Cap.vdec_ability[VDEC_H263].value))->cif);        printf("fourcif %d\n",((VDEC_H263CAPABILITY_S*)(Cap.vdec_ability[VDEC_H263].value))->fourcif);        printf("lostpacket %d\n",((VDEC_H263CAPABILITY_S*)(Cap.vdec_ability[VDEC_H263].value))->lostpacket);        printf("upperbandwidth %d\n",((VDEC_H263CAPABILITY_S*)(Cap.vdec_ability[VDEC_H263].value))->upperbandwidth);        printf("lowerbandwidth %d\n",((VDEC_H263CAPABILITY_S*)(Cap.vdec_ability[VDEC_H263].value))->lowerbandwidth);        printf("palfps %d\n",((VDEC_H263CAPABILITY_S*)(Cap.vdec_ability[VDEC_H263].value))->palfps);        printf("ntscfps %d\n",((VDEC_H263CAPABILITY_S*)(Cap.vdec_ability[VDEC_H263].value))->ntscfps);    }    if(Cap.vdec_ability[VDEC_H261].support)    {        printf("H261 ");    }    if(Cap.vdec_ability[VDEC_MPEG4].support)    {        printf("MPEG4 ");    }    if(Cap.vdec_ability[VDEC_VC1].support)    {        printf("VC1 ");    }    printf("\n");    ret = HI_SYS_GetVersionInfo(&Version);    if (HI_SUCCESS == ret)    {        printf("Alg version %x\n",Version.u32AlgVer);        printf("Chip version %x\n",Version.u32ChipVer);        printf("Linux version %x\n",Version.u32LinuxVer);        printf("Msp version %x\n",Version.u32MspVer);        printf("Product version %x\n",Version.u32ProductVer);        printf("RootBox version %x\n",Version.u32RootBoxVer);    }}/*this thread read the stream from file and send it to decoder,  dec.h264'content is H.264 stream,it saved in NAL*/void test_Video_Decoder_Process(){    VDEC_CHN ChanID;    VDEC_ATTR_TYPE_E type = VDEC_ATTR_ALL;    VDEC_ChannelPara_S config;    HI_S32 ret;    HI_U64 pts;    VDEC_STREAM_S stream;    HI_CHAR fnStream[] = "dec.h264";    FILE*      fhStream;    HI_U32 len_nalu = 0;    HI_CHAR *streambuf;    pthread_t thread;    static VDEC_RECEIVE_THTREAD_ARGS arg;    streambuf = malloc(0x10000);    if (NULL == streambuf)    {        printf("malloc failed !\n");        return;    }    /*synchronization head*/    *streambuf = 0x0;    *(streambuf+1) = 0x0;    *(streambuf+2) = 0x0;    *(streambuf+3) = 0x1;    /*set config value*/    config.type = VDEC_H264;    config.framenumber = 8;    config.picformat = VDEC_DEFAULT_PICTUREFORMAT;    /*create video decoce channel*/    ret = HI_VDEC_CreateCH(&ChanID, type, &config);    if (HI_SUCCESS == ret)    {        printf("test_Video_Decoder_Process:Create a Channel: %d\n",ChanID);    }    else    {        printf("test_Video_Decoder_Process:Failed to Create a Channel!!!\n");        return;    }    printf("** file to decode is %s . **\n", fnStream);    fhStream = fopen(fnStream, "rb");    if (fhStream == NULL)    {        printf("open file %s to decode error: %#x.\n", fnStream, errno);        return;    }    arg.ChanID = ChanID;    s32vdecthreadflag = 1;    /*create thread which used for receive decode data*/    pthread_create(&thread, NULL, receive_thread, &arg);bbb:        fbuf_pointer = 0;    fbuf_bytes_num = 0;    fseek(fhStream, 0, SEEK_SET);    stream.Dataaddr = (ADDR)streambuf;    pts = 0;    while(1)    {        if (4 != Fread(&len_nalu, 1, 4, fhStream))        {            printf("end of file.\n");            break;        }        stream.Datalen = len_nalu;        if (0 == len_nalu)        {            printf("end of file.\n");            break;        }        len_nalu = HI_ALIGN_LENGTH(len_nalu, 2);        if ( len_nalu != Fread(streambuf+4, 1,len_nalu, fhStream) )        {            printf("end of file.\n");            break;        }        stream.Datalen += 4;            stream.pts = pts;                /*send stream data to video decode channel*/        ret = HI_VDEC_SendStream(ChanID, &stream, HI_TRUE);        while(HI_SUCCESS != ret)        {            if(HI_ERR_VDEC_NO_PAYLOAD == ret)break;            /*retry it*/            ret = HI_VDEC_SendStream(ChanID, &stream, HI_TRUE);        }        pts++;                if (10000== pts)break;    }        //goto bbb;    fclose(fhStream);    /*wait until decoding over*/    usleep(500000);    s32vdecthreadflag = 0;    pthread_join(thread, NULL);    ret = HI_VDEC_ResetCH(ChanID);    printf("reset ret %x\n",ret);    /*destrou video decode channel*/    ret = HI_VDEC_DestroyCH(ChanID);    printf("close ret %x\n",ret);    free(streambuf);}/*the input parameter is file name, the file forma is H.264 stream   each nalu is compart with synchronization head*/void test_Video_Decoder_Process1(char *filename){    VDEC_CHN ChanID;    VDEC_ATTR_TYPE_E type = VDEC_ATTR_ALL;    VDEC_ChannelPara_S config;    HI_S32 ret;    HI_U64 pts;    VDEC_STREAM_S stream;    FILE*      fhStream;    HI_U32 len_nalu = 0;    HI_CHAR *streambuf;    pthread_t thread;    static VDEC_RECEIVE_THTREAD_ARGS arg;    HI_CHAR startcode[3] = {0,0,1};/*nal分割码*/    HI_BOOL eof_flag = HI_FALSE;    HI_CHAR val;    int zero_count;            streambuf = malloc(0x10000);    if (NULL == streambuf)    {        printf("malloc failed !\n");        return;    }    /*set config value*/    config.type = VDEC_H264;    config.framenumber = 8;    config.picformat = VDEC_DEFAULT_PICTUREFORMAT;    /*create video decode channel*/    ret = HI_VDEC_CreateCH(&ChanID, type, &config);    if (HI_SUCCESS == ret)    {        printf("test_Video_Decoder_Process1:Create a Channel: %d\n",ChanID);    }    else    {        printf("test_Video_Decoder_Process1:Failed to Create a Channel!!!\n");        return;    }    printf("** file to decode is %s . **\n", filename);    fhStream = fopen(filename, "rb");    if (fhStream == NULL)    {        printf("open file %s to decode error: %#x.\n", filename, errno);        return;    }    arg.ChanID = ChanID;    s32vdecthreadflag = 1;    pthread_create(&thread, NULL, receive_thread, &arg);    stream.Dataaddr = (ADDR)streambuf;aaa:        pts = 0;    fbuf_pointer = 0;    fbuf_bytes_num = 0;    fseek(fhStream, 0, SEEK_SET);    /*找到第一个分隔码*/    while(1)    {                ret = Fread(&val, 1, 1, fhStream);        if (1 != ret)        {            printf("end of file(invalid file format)!\n");            exit(-1);        }        printf("%d ",val);        if(0 == val)        {            zero_count++;        }        else        {            if(zero_count >= 2 && 1 == val)            {                /*找到第一个分隔码*/                break;            }            else            {                zero_count = 0;            }        }    }    //printf("len %d\n",len_nalu);    while(1)    {        streambuf = (char *)stream.Dataaddr;        *streambuf = startcode[0];        *(streambuf+1) = startcode[1];        *(streambuf+2) = startcode[2];        len_nalu += 3;        while(1)        {            ret = Fread(streambuf+len_nalu, 1, 1, fhStream);            if (1 != ret)            {                printf("end of file!\n");                eof_flag = HI_TRUE;                len_nalu +=3;                break;            }            //printf("$ %d",*(streambuf+len_nalu));            if(*(streambuf+len_nalu)  == 0x1                && *(streambuf+len_nalu-1) == 0x0                && *(streambuf+len_nalu-2) == 0x0)            {                break;            }            len_nalu++;        }                if (eof_flag == HI_TRUE) break;/*discard the last packet of the file*/        len_nalu -= 2;        if(0)        {            int i;            for(i=0;i<len_nalu;i++)            {                //printf("%0x ",*(streambuf+i));            }            printf("\n len 0x%x %d",len_nalu,len_nalu);getchar();        }                stream.Datalen = len_nalu;        //getchar();        //printf("\n len 0x%x %d",len_nalu,len_nalu);getchar();#if 0                printf("\n len %x %d\n",len_nalu,len_nalu);        pts++;        if (10== pts)break;        len_nalu = 0;        continue;#endif                stream.pts = pts;//printf("len_nalu %d\n",stream.Datalen);usleep(100);        ret = HI_VDEC_SendStream(ChanID, &stream, HI_TRUE);        while(HI_SUCCESS != ret)        {            if(HI_ERR_VDEC_NO_PAYLOAD == ret)break;            printf("*");fflush(stdout);            ret = HI_VDEC_SendStream(ChanID, &stream, HI_TRUE);        }        //usleep(20000);                pts++;        //printf("pts %d\n",pts);        len_nalu = 0;        if (6228== pts)break;    }//    printf("pts %d\n",pts);getchar();    eof_flag = HI_FALSE;    len_nalu = 0;    printf("recircyl!\n");goto aaa;    /*play the same file cycle*/    fclose(fhStream);    /*wait until all the stream is decoded over*/    usleep(500000);    s32vdecthreadflag = 0;    pthread_join(thread, NULL);    /*destroy the video decode channel*/    HI_VDEC_DestroyCH(ChanID);    free(streambuf);}VDEC_CHN ChanID[4];/* receive multiple channel video data, and send one of them to VO*/void* receive_thread_multi(void *args){    VDEC_RECEIVE_THTREAD_ARGS *parg = args;    int i;    HI_S32 ret;    VDEC_FRAMEINFO_S frameinfo;    while(s32vdecthreadflag)    {        for (i=0;i<parg->chnum;i++)        {            HI_VDEC_Receive(ChanID[i], &frameinfo, NULL, HI_TRUE);            if (frameinfo.value)            {                if (parg->ChanID == ChanID[i])                {                    ret = HI_VO_SendData(VO_CHN0, &frameinfo);                    while(HI_SUCCESS != ret)                     {                        ret = HI_VO_SendData(VO_CHN0, &frameinfo);                    }                }                else                {                    HI_VDEC_ReleaseVideoBuf(ChanID[i], &frameinfo);                }            }        }        //usleep(1000);    }    printf("break while!\n");    pthread_exit(NULL);}/*decode multiple channel the same time*/void test_Video_Decoder_MultiChannel(char *arg1,char *arg2){    VDEC_ATTR_TYPE_E type = VDEC_ATTR_ALL;    VDEC_ChannelPara_S config;    HI_S32 ret;    HI_U64 pts;    VDEC_STREAM_S stream;    char fnStream[] = "dec.h264";    FILE*      fhStream;    HI_U32 len_nalu = 0;    char *streambuf;    pthread_t thread;    static VDEC_RECEIVE_THTREAD_ARGS arg;    int Maxchnum = atoi(arg1);    int chindex = atoi(arg2);    int i;    streambuf = malloc(0x10000);    if (NULL == streambuf)    {        printf("malloc failed !\n");        return;    }    *streambuf = 0x0;    *(streambuf+1) = 0x0;    *(streambuf+2) = 0x0;    *(streambuf+3) = 0x1;    /*set config value*/    config.type = VDEC_H264;    config.framenumber = 10;    config.picformat = VDEC_DEFAULT_PICTUREFORMAT;    /*create multiple decode channel*/    for (i=0;i<Maxchnum;i++)    {        ret = HI_VDEC_CreateCH(&ChanID[i], type, &config);        if (HI_SUCCESS == ret)        {            printf("test_Video_Decoder_MultiChannel:Create a Channel: %d\n",ChanID[i]);        }        else        {            printf("test_Video_Decoder_MultiChannel:failed at create ch %d\n",i);            exit(-1);        }    }    printf("** file to decode is %s . **\n", fnStream);    fhStream = fopen(fnStream, "rb");    if (fhStream == NULL)    {        printf("open file %s to decode error: %#x.\n", fnStream, errno);

⌨️ 快捷键说明

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