user-0 提问: 急！c读取视频数据时如何跳过包头并另存为文件？

回复:
user: user-1
content: 读完    AOS_UINT16  uLen;   // the data package length, the data len must less than 65535. 后，需要跳过后面的     AOS_UINT16  uMilliSecond; // the data reveived time offset in second, in millisecond     AOS_TIME_T  uSeconds 继续读数据  因为AOS_UINT16肯定占2字节 AOS_TIME_T假定占SIZEOF_AOS_TIME_T字节 所以共需要跳过2+SIZEOF_AOS_TIME_T个字节。

user: user-1
content: 不一定对，仅供参考： #include <stdio.h> #include <string.h> #if 0 /**包头的标识**/ #define SFUNIT_PACKAGE_HEAD htonl(('z' << 24 ) | ('x' << 16) | ('e' << 8) | ('l'))  //zxel   /**构造数据包头**/     stPackHead.uKey          = SFUNIT_PACKAGE_HEAD;     stPackHead.uLen          = (AOS_UINT16)ulDataBufferLen;     stPackHead.uMilliSecond  = (AOS_UINT16)(pstRcvTime->tv_usec / 1000);     stPackHead.uSeconds.time = pstRcvTime->tv_sec;   /**包的结构**/ typedef struct _PACKAGE_HEAD_ {     AOS_UINT32  uKey;   // before each data package, is a magic words, should be SFUNIT_PACKAGE_HEAD     AOS_UINT16  uLen;   // the data package length, the data len must less than 65535.     AOS_UINT16  uMilliSecond; // the data reveived time offset in second, in millisecond     AOS_TIME_T  uSeconds;     // the data reveived time, it is a absult time, in second }PACKAGE_HEAD; #endif #define SIZEOF_AOS_TIME_T 2 //假定AOS_TIME_T类型占用16位即2字节 char s[5]; int c; unsigned short uLen; int i,offset; FILE *fi,*fo; int main(int argc,char **argv) {     if (argc<3) {         printf("%s inputfile outputfile\n",argv[0]);         return 1;     }     fi=fopen(argv[1],"rb");     if (NULL==fi) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     fo=fopen(argv[2],"wb");     if (NULL==fo) {         fclose(fi);         printf("Can not create file [%s]!\n",argv[2]);         return 3;     }     s[4]=0;     while (1) {         c=fgetc(fi);         if (EOF==c) break;         s[0]=c;         c=fgetc(fi);         if (EOF==c) break;         s[1]=c;         c=fgetc(fi);         if (EOF==c) break;         s[2]=c;         c=fgetc(fi);         if (EOF==c) break;         s[3]=c;         if (0==strcmp(s,"zxel")) {             if (1!=fread(&uLen,2,1,fi)) break;             fseek(fi,2+SIZEOF_AOS_TIME_T,SEEK_CUR);             for (i=0;i<uLen;i++) {                 c=fgetc(fi);                 if (EOF==c) break;                 fputc(c,fo);             }             if (EOF==c) break;         } else {             offset=ftell(fi);             printf("Format Error at file [%s] offset %09d(0x%08x),Expect 'zxel' but '%s'!",argv[1],offset,offset,s);             break;         }     }     fclose(fo);     fclose(fi);     return 0; }

user: user-2
content: 楼主可以尝试： 题中： 1、zxel 为包头标识，当读取到的 zxel 时被认为是一个数据包的开始。 2、跳过包头部分（sizeof(PACKAGE_HEAD)），读取数据到另一个文件中。 3、从图1，可以以zxel 为结束或者说是下一次读取的开始，同时可以写入特殊字符作为视频数据部分的分割符。 直至读取结束...

user: user-0
content: 可能描述上不是很清楚，画个图可能会更明白点 原始数据如图1，最终需要的结果如图中2所示，可以根据包头里的ulen确定这个包的大小，每个包的结构都是完整的且没有垃圾数据。把最后读到的数据再保存到一个新的文件即可。

user: user-0
content: 引用 8 楼 duoduodxyyy 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 不一定对，仅供参考： #include <stdio.h> #include <string.h> #if 0 /**包头的标识**/ #define SFUNIT_PACKAGE_HEAD htonl(('z' << 24 ) | ('x' << 16) | ('e' << 8) | ('l'))  //zxel   /**构造数据包头**/     stPackHead.uKey          = SFUNIT_PACKAGE_HEAD;     stPackHead.uLen          = (AOS_UINT16)ulDataBufferLen;     stPackHead.uMilliSecond  = (AOS_UINT16)(pstRcvTime->tv_usec / 1000);     stPackHead.uSeconds.time = pstRcvTime->tv_sec;   /**包的结构**/ typedef struct _PACKAGE_HEAD_ {     AOS_UINT32  uKey;   // before each data package, is a magic words, should be SFUNIT_PACKAGE_HEAD     AOS_UINT16  uLen;   // the data package length, the data len must less than 65535.     AOS_UINT16  uMilliSecond; // the data reveived time offset in second, in millisecond     AOS_TIME_T  uSeconds;     // the data reveived time, it is a absult time, in second }PACKAGE_HEAD; #endif #define SIZEOF_AOS_TIME_T 2 //假定AOS_TIME_T类型占用16位即2字节 char s[5]; int c; unsigned short uLen; int i,offset; FILE *fi,*fo; int main(int argc,char **argv) {     if (argc<3) {         printf("%s inputfile outputfile\n",argv[0]);         return 1;     }     fi=fopen(argv[1],"rb");     if (NULL==fi) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     fo=fopen(argv[2],"wb");     if (NULL==fo) {         fclose(fi);         printf("Can not create file [%s]!\n",argv[2]);         return 3;     }     s[4]=0;     while (1) {         c=fgetc(fi);         if (EOF==c) break;         s[0]=c;         c=fgetc(fi);         if (EOF==c) break;         s[1]=c;         c=fgetc(fi);         if (EOF==c) break;         s[2]=c;         c=fgetc(fi);         if (EOF==c) break;         s[3]=c;         if (0==strcmp(s,"zxel")) {             if (1!=fread(&uLen,2,1,fi)) break;             fseek(fi,2+SIZEOF_AOS_TIME_T,SEEK_CUR);             for (i=0;i<uLen;i++) {                 c=fgetc(fi);                 if (EOF==c) break;                 fputc(c,fo);             }             if (EOF==c) break;         } else {             offset=ftell(fi);             printf("Format Error at file [%s] offset %09d(0x%08x),Expect 'zxel' but '%s'!",argv[1],offset,offset,s);             break;         }     }     fclose(fo);     fclose(fi);     return 0; }  您好，还想问下您，#define SIZEOF_AOS_TIME_T 2    这个#define 是什么意思?在fseek的偏移量中也有加这个值，不太明白，能否讲解下？很感谢！[/quote]不好意思，可能我问的有歧义，本意是想问为什么会加上：SIZEOF_AOS_TIME_T  ，在fseek的时候:2+SIZEOF_AOS_TIME_T ，这个地方也不太明白.....

user: user-1
content: 就是我猜想在你系统环境下AOS_TIME_T这个数据类型大概是占16位即2个字节的。 如果实际上不是，比如是32位即4个字节的话，只要修改 #define SIZEOF_AOS_TIME_T 2 为 #define SIZEOF_AOS_TIME_T 4 再重新编译链接即可。

user: user-0
content: 引用 7 楼 zhao4zhong1 的回复:不一定对，仅供参考： #include <stdio.h> #include <string.h> #if 0 /**包头的标识**/ #define SFUNIT_PACKAGE_HEAD htonl(('z' << 24 ) | ('x' << 16) | ('e' << 8) | ('l'))  //zxel   /**构造数据包头**/     stPackHead.uKey          = SFUNIT_PACKAGE_HEAD;     stPackHead.uLen          = (AOS_UINT16)ulDataBufferLen;     stPackHead.uMilliSecond  = (AOS_UINT16)(pstRcvTime->tv_usec / 1000);     stPackHead.uSeconds.time = pstRcvTime->tv_sec;   /**包的结构**/ typedef struct _PACKAGE_HEAD_ {     AOS_UINT32  uKey;   // before each data package, is a magic words, should be SFUNIT_PACKAGE_HEAD     AOS_UINT16  uLen;   // the data package length, the data len must less than 65535.     AOS_UINT16  uMilliSecond; // the data reveived time offset in second, in millisecond     AOS_TIME_T  uSeconds;     // the data reveived time, it is a absult time, in second }PACKAGE_HEAD; #endif #define SIZEOF_AOS_TIME_T 2 //假定AOS_TIME_T类型占用16位即2字节 char s[5]; int c; unsigned short uLen; int i,offset; FILE *fi,*fo; int main(int argc,char **argv) {     if (argc<3) {         printf("%s inputfile outputfile\n",argv[0]);         return 1;     }     fi=fopen(argv[1],"rb");     if (NULL==fi) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     fo=fopen(argv[2],"wb");     if (NULL==fo) {         fclose(fi);         printf("Can not create file [%s]!\n",argv[2]);         return 3;     }     s[4]=0;     while (1) {         c=fgetc(fi);         if (EOF==c) break;         s[0]=c;         c=fgetc(fi);         if (EOF==c) break;         s[1]=c;         c=fgetc(fi);         if (EOF==c) break;         s[2]=c;         c=fgetc(fi);         if (EOF==c) break;         s[3]=c;         if (0==strcmp(s,"zxel")) {             if (1!=fread(&uLen,2,1,fi)) break;             fseek(fi,2+SIZEOF_AOS_TIME_T,SEEK_CUR);             for (i=0;i<uLen;i++) {                 c=fgetc(fi);                 if (EOF==c) break;                 fputc(c,fo);             }             if (EOF==c) break;         } else {             offset=ftell(fi);             printf("Format Error at file [%s] offset %09d(0x%08x),Expect 'zxel' but '%s'!",argv[1],offset,offset,s);             break;         }     }     fclose(fo);     fclose(fi);     return 0; }  您好，还想问下您，#define SIZEOF_AOS_TIME_T 2    这个#define 是什么意思?在fseek的偏移量中也有加这个值，不太明白，能否讲解下？很感谢！

user: user-3
content: 引用 3 楼 duoduodxyyy 的回复:[quote=引用 楼主 duoduodxyyy 的回复:] 求代码实现：   数据data中包含不定数量的数据包，每个数据包里存的都是视频数据，现在需要读取data中数据的过程时跳过PACKAGE_HEAD，读取完毕以后把跳过PACKAGE_HEAD的纯视频数据另存为一个(纯码流的)文件中,读取数据的过程中只要遇到 zxel 就认为是读到一个包头。    /**包头的标识**/ #define SFUNIT_PACKAGE_HEAD htonl(('z' << 24 ) | ('x' << 16) | ('e' << 8) | ('l'))  zxel   /**构造数据包头**/     stPackHead.uKey          = SFUNIT_PACKAGE_HEAD;     stPackHead.uLen          = (AOS_UINT16)ulDataBufferLen;     stPackHead.uMilliSecond  = (AOS_UINT16)(pstRcvTime->tv_usec / 1000);     stPackHead.uSeconds.time = pstRcvTime->tv_sec;   /**包的结构**/ typedef struct _PACKAGE_HEAD_ {     AOS_UINT32  uKey;   // before each data package, is a magic words, should be SFUNIT_PACKAGE_HEAD     AOS_UINT16  uLen;   // the data package length, the data len must less than 65535.     AOS_UINT16  uMilliSecond; // the data reveived time offset in second, in millisecond     AOS_TIME_T  uSeconds;     // the data reveived time, it is a absult time, in second }PACKAGE_HEAD; 引用 1 楼 zjq9931 的回复:fseek 就可以了啊。能给个具体实现么？之前尝试过最后得到的数据总是不对。谢谢！上面回复的表情不知道怎么加进去了，是没有那个表情的。[/quote] 其实我也不太明白你说的情况，但是你都把条件列出来了，按道理不应当分不清数据啊。 你的问题是什么？有没有跟踪调试？ 绝大多数问题，跟踪调试都能找到根源的。

user: user-0
content: 引用 楼主 duoduodxyyy 的回复:求代码实现：   数据data中包含不定数量的数据包，每个数据包里存的都是视频数据，现在需要读取data中数据的过程时跳过PACKAGE_HEAD，读取完毕以后把跳过PACKAGE_HEAD的纯视频数据另存为一个(纯码流的)文件中,读取数据的过程中只要遇到 zxel 就认为是读到一个包头。    /**包头的标识**/ #define SFUNIT_PACKAGE_HEAD htonl(('z' << 24 ) | ('x' << 16) | ('e' << 8) | ('l'))  zxel   /**构造数据包头**/     stPackHead.uKey          = SFUNIT_PACKAGE_HEAD;     stPackHead.uLen          = (AOS_UINT16)ulDataBufferLen;     stPackHead.uMilliSecond  = (AOS_UINT16)(pstRcvTime->tv_usec / 1000);     stPackHead.uSeconds.time = pstRcvTime->tv_sec;   /**包的结构**/ typedef struct _PACKAGE_HEAD_ {     AOS_UINT32  uKey;   // before each data package, is a magic words, should be SFUNIT_PACKAGE_HEAD     AOS_UINT16  uLen;   // the data package length, the data len must less than 65535.     AOS_UINT16  uMilliSecond; // the data reveived time offset in second, in millisecond     AOS_TIME_T  uSeconds;     // the data reveived time, it is a absult time, in second }PACKAGE_HEAD; 引用 1 楼 zjq9931 的回复:fseek 就可以了啊。能给个具体实现么？之前尝试过最后得到的数据总是不对。谢谢！上面回复的表情不知道怎么加进去了，是没有那个表情的。

user: user-0
content: 能给个具体实现么？之前尝试过最后得到的数据总是不对。谢谢！

user: user-3
content: fseek 就可以了啊。