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,固定为strf
unsigned int size; //块大小,等于struct avi_strf_chunk去掉id和size的大小
unsigned int size1; //size1含义和值同size一样
unsigned int width; //视频主窗口宽度(单位:像素)
unsigned int height; //视频主窗口高度(单位:像素)
unsigned short planes; //始终为1
unsigned short bitcount; //每个像素占的位数,只能是1、4、8、16、24和32中的一个
unsigned char compression[4]; //视频流编码格式,如JPEG、MJPG等
unsigned int image_size; //视频图像大小,等于width * height * bitcount / 8
unsigned 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格式的avi
if(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,mjpg
char 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;
}