avi 视频的视频流编码必须是jpeg,或者mjpg
直接用摄像头录取的视频都是这两种格式,不能用ffmpeg转成avi的视频。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <string.h>
#include <sys/mman.h>
static int zz=1;int main(void){struct strf{unsigned char id[4]; //块ID,固定为strfunsigned int size; //块大小,等于struct avi_strf_chunk去掉id和size的大小unsigned int size1; //size1含义和值同size一样unsigned int width; //视频主窗口宽度(单位:像素)unsigned int height; //视频主窗口高度(单位:像素)unsigned short planes; //始终为1unsigned short bitcount; //每个像素占的位数,只能是1、4、8、16、24和32中的一个unsigned char compression[4]; //视频流编码格式,如JPEG、MJPG等unsigned int image_size; //视频图像大小,等于width * height * bitcount / 8unsigned int x_pixels_per_meter; //显示设备的水平分辨率,设为0即可unsigned int y_pixels_per_meter; //显示设备的垂直分辨率,设为0即可unsigned int num_colors; //含义不清楚,设为0即可unsigned int imp_colors; //含义不清楚,设为0即可}str;FILE *f=fopen("/home/wzpc/Videos/tra_mjpg.avi","rb"); //必须是JPEG,MJPG格式的aviif(f==NULL){puts("file error");exit(-1);}fseek(f,0,SEEK_END);int fsize=ftell(f);fseek(f,0,SEEK_SET);int fd=fileno(f);char *m=mmap(NULL,fsize,PROT_READ,MAP_SHARED,fd,0);for(int t=0;t<fsize;t++){if((m[t]=='s')&&(m[t+1]=='t')&&(m[t+2]=='r')&&(m[t+3]=='f')){memcpy(&str,&m[t],sizeof(str));printf("%d\n",str.bitcount);printf("%s\n",str.compression);printf("%d*%d\n",str.width,str.height);char r[]={'M','J','P','G'}; //avi 编码必须是jpeg,mjpgchar r1[]={'J','P','E','G'};int bj=memcmp(str.compression,r,4);int bj1=memcmp(str.compression,r1,4);if((bj==0)||(bj1==0)){zz=0;}}}if(zz!=0){puts("no zc");exit(-1);}for(int t=0;t<fsize;t++){if((m[t]=='0')&&(m[t+1]=='0')&&(m[t+2]=='d')&&(m[t+3]=='c')){char file[10]={};sprintf(file,"%d",t);chdir("/home/wzpc/Pictures/pic_avi"); //存储图片的目录FILE * fo=fopen(file,"w+b");if(fo==NULL){puts("fo error");exit(-1);}int k;memcpy(&k,&m[t+4],4);fwrite(&m[t+8],k,1,fo); //直接从mmap中读数据到文件fclose(fo);}}munmap(m,fsize);return 0;
}