• PUDN用户
    了解作者
  • Visual C++
    开发工具
  • 168KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 9
    下载次数
  • 2012-04-24 21:50
    上传日期
对MPEG-TS流中ES,PES,IFrame分析
IFrame--.rar
  • IFrame
  • Debug
  • IFram.exe
    172.1KB
  • IFram.sbr
    0B
  • IFram.ilk
    176.2KB
  • IFram.pdb
    345KB
  • vc60.idb
    33KB
  • IFram.obj
    20.5KB
  • IFram.pch
    171.4KB
  • vc60.pdb
    52KB
  • IFram.bsc
    41KB
  • IFram.dsp
    3.3KB
  • IFram.dsw
    535B
  • IFram.ncb
    41KB
  • IFram.opt
    52.5KB
  • IFram.c
    13.9KB
  • IFram.plg
    1.5KB
内容介绍
#include <stdio.h> unsigned char Mbuf[10*188 * 1024]; //分离TS int Tsdumx(char *srcfile,char *tsfile,unsigned short pid) { unsigned char *p; int Tssize=0; FILE *fpd,*fp; unsigned short Pid; fp = fopen(srcfile,"rb"); fpd = fopen(tsfile,"wb"); // if(fp==NULL )printf("*********************"); // if(fpd == NULL)printf("*********************"); if(fp==NULL || fpd == NULL) {return -1;} do{ Tssize = fread(Mbuf, 1, sizeof(Mbuf), fp); p = Mbuf; while( p + 188 <= Mbuf + Tssize )//寻找TS包的起始点 { if( p + 376 < Mbuf + Tssize )//TS超过3个包长 { if( *p == 0x47 && *(p+188) == 0x47 && *(p+376) == 0x47 ) break; } else if( p + 188 < Mbuf + Tssize )//TS为两个包长 { if( *p == 0x47 && *(p+188) == 0x47 ) break; } else if( *p == 0x47 )//ts为一个包长 break; p++; } while( p < Mbuf + Tssize)//将视频流数据提取出来,写到另一个新的文件中 { Pid = ((p[1] & 0x1f)<<8) | p[2]; if( Pid == pid) fwrite(p,1,188,fpd); p += 188; } }while(! feof( fp )); fclose(fp ); fclose(fpd ); printf("TS包已经分离完!\n"); return 0; } //提取PES int Ts2Pes(char *tsfile,char *pesfile,unsigned short pid) { FILE *fpd,*fp; int start = 0; int size,num,total; int count = 0; unsigned char *p,*payload; unsigned short Pid; unsigned char Lcounter = 0xff; unsigned char Adapcontrol; unsigned char counter; //计数器 fp = fopen( tsfile, "rb"); fpd = fopen( pesfile, "wb"); if(fp == NULL || fpd == NULL ) return -1; //初始化设置值大小 total = 0; num = 0; size = 0; while( ! feof( fp )) { size = fread(Mbuf, 1,sizeof(Mbuf), fp); p = Mbuf; do{ Pid = (((p[1] & 0x1f)<<8) | p[2]); //获取pid Adapcontrol = (p[3]>>4)&0x3 ; //判断自适应区是否有可调整字段 counter = p[3]&0xf ; //提取连续计数器 if( Pid == pid) { payload = NULL; switch(Adapcontrol) { case 0: //保留 case 2: break; //2为只有调整无负载 case 1: payload = p + 4; //无调整字段 break; case 3: payload = p + 5 + p[4]; //调整字段后是净荷 break; } if((p[1] & 0x40)!= 0 )//取出有效荷载单元起始指示符,确定TS,pes数据开始 { start = 1; } if(start && payload && fpd)//往fpd写pes包数据 { fwrite(payload, 1,p+188-payload, fpd); } if( Lcounter != 0xff && ((Lcounter + 1)&0xf) != counter)//判断数据是否丢失 { ///////////// printf("%ddata lost\n",count); count++; } Lcounter = counter ; } p += 188; total += 188; }while(p<Mbuf+size); } fclose( fp ); fclose( fpd ); printf( "PES包分离完!\n" ); return 0; } //提取ES int pes2es( char *pesfile, char *esfile ) { FILE *fpd, *fp; unsigned char *p, *payload, *tmp; int size, num, rdsize; unsigned int last = 0; __int64 total = 0, wrsize = 0; unsigned int Lenght; unsigned char PES_extension_flag; unsigned char PES_header_data_Lenghtgth; unsigned char PTS_DTS_flags; int k=0; fp = fopen( pesfile, "rb" ); fpd = fopen( esfile, "wb" ); if( fp == NULL || fpd == NULL ) return -1; num = 0; size = 0; p = Mbuf; while(1) { REDO: if( Mbuf + size <= p ) { p = Mbuf; size = 0; } else if( Mbuf < p && p < Mbuf + size ) { size -= p - Mbuf; memmove(Mbuf, p, size ); p = Mbuf; } if( !feof(fp) && size < sizeof(Mbuf) ) { rdsize = fread( Mbuf+size, 1, sizeof(Mbuf)-size, fp ); size += rdsize; total += rdsize; } if( size <= 0 ) break; tmp = p; // 寻找PES-HEADER: 0X000001E0 while( p[0] != 0 || p[1] != 0 || p[2] != 0x01 || ( ( p[3] & 0xe0 ) != 0xe0 )) { p++; if( Mbuf + size <= p ) goto REDO; } // PES_packet_Lenghtgth Lenght = (p[4]<<8) | p[5]; if( Lenght == 0 ) { unsigned char *end = p + 6; while( end[0] != 0 || end[1] != 0 || end[2] != 0x01 || ( ( end[3] & 0xe0 ) != 0xe0 )) { if( Mbuf + size <= end ) { if( feof(fp) ) break; goto REDO; } end++; } Lenght = end - p - 6; } if( Mbuf + size < p + 6 + Lenght ) { if( feof(fp) ) break; continue; } p += 6; p++; PTS_DTS_flags = (*p>>6)&0x3; PES_extension_flag = (*p)&0x1; p++; PES_header_data_Lenghtgth = *p; p++; payload = p + PES_header_data_Lenghtgth; if (PTS_DTS_flags == 0x2 )//'10' { unsigned int pts; pts = (*p>>1) & 0x7; pts = pts << 30; p++; pts += (*p)<<22; p++; pts += ((*p)>>1)<<15; p++; pts += (*p)<<7; p++; pts += (*p)>>1; p++; p -= 5; if(last!=0) k=k+pts-last; // if( pts < last) // { // printf( "?\n" ); // } last = pts; } else if( PTS_DTS_flags == 0x3 )//'11' { unsigned int pts, dts; pts = (*p>>1) & 0x7; pts = pts << 30; p++; pts += (*p)<<22; p++; pts += ((*p)>>1)<<15; p++; pts += (*p)<<7; p++; pts += (*p)>>1; p++; dts = (*p>>1) & 0x7; dts = dts << 30; p++; dts += (*p)<<22; p++; dts += ((*p)>>1)<<15; p++; dts += (*p)<<7; p++; dts += (*p)>>1; p++; p -= 10; if(last!=0) k=k+pts-last; // if( pts < last ) // { // printf( "?\n" ); // } last = pts; } else if( PTS_DTS_flags != 0 ) { printf( "error\n" ); } if( fpd ) { fwrite( payload, 1, Lenght - 3 - PES_header_data_Lenghtgth, fpd ); } num++; p += Lenght - 3; payload = p; size -= p - Mbuf; memmove( Mbuf, p, size ); p = Mbuf; } fclose( fp ); fclose( fpd ); printf("视屏流的PES的个数为:%d\n",num); printf("pes平均时间间隔为:%d\n",k/(num*90)); printf("ES分离完!\n"); return 0; } //提取I帧,B帧,P帧 int es2iframe(char *esfile, char *ifile ) { FILE *fes, *fi; int size, Lenght; unsigned char *p, *PI=NULL,*s=NULL; unsigned char picture_coding_type; int nsqueue, niframe; int npframe=0; int nbframe=0; //printf( "Begin get iframe...\n" ); // 打开ES文件 和 IFRAME文件 fes = fopen( esfile, "rb" ); fi = fopen( ifile, "wb" ); if( NULL == fes || NULL == fi ) { printf( "error: open file error!\n" ); return -1; } size = 0; nsqueue = 0; niframe = 0; while( !feof( fes ) ) { /* 读入ES文件,size表示当前缓存中还有多少字节数据 */ Lenght = fread( Mbuf+size, 1, sizeof(Mbuf) - size, fes ); p = Mbuf; PI = NULL; /* 指向Sequence 或 Picture 的开始位置 */ while( p+6 < Mbuf+size+Lenght ) { /* 寻找前缀0x000001 */ if( 0x00 == p[0] && 0x00 == p[1] && p[2]== 0x01 ) { /* 以Sequence header与Picture header 为I帧 */ if( p[3]==0xB3 ||p[3] == 0x00 ) { if(s!=NULL) { fwrite( s, 1, p-s, fi ); s=NULL; } } /* Sequence header 的开始代码 0xB3 */ if( 0xB3 == p[3] ) { nsqueue++; s=p; } /* Picture header 的开始代码 0x00 */ picture_coding_type = (p[5]>>3) & 0x7; /* 帧类型, 第42-44位 */ if( 0x00 == p[3] && 1 == picture_coding_type ) { niframe++; s=p; } if( 0x00 == p[3] && 2 == picture_coding_type ) { npframe++; } if( 0x00 == p[3] && 3 == picture_coding_type ) { nbframe++; } } p++; } /* 确定缓存中未处理数据的大小, 并移至缓存的开始处 */ if( NULL == PI ) { size = Mbuf+Lenght+size - p; memmove( Mbuf, p, size ); } else { size = Mbuf+Lenght+size - PI; memmove( Mbuf, PI, size ); } } printf("vedio sequence个数是:%d\n",nsqueue); printf("i fream个数是:%d\n",niframe); printf("p fream个数是:%d\n",npframe); printf("b fream个数是:%d\n",nbframe); fclose( fes ); fclose( fi ); printf( "I帧提取完成!\n" ); return 0; } // 设置Dts时间戳(90khz)
评论
    相关推荐