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 + -
显示快捷键?