当前位置: 首页 > article >正文

c 从avi 视频中提取图片

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;
}

 

 


http://www.kler.cn/news/109217.html

相关文章:

  • linux中好玩的数据流定向和管道命令一
  • 【蓝桥每日一题]-前缀和与差分(保姆级教程 篇3)#涂国旗 #重新排序
  • VBA宏查找替换目录下所有Word文档中指定字符串
  • leetcode-数组
  • 计算机网络基础二
  • MATLAB中mse函数用法
  • ✔ ★【备战实习(面经+项目+算法)】 10.29学习
  • 提高抖音小店用户黏性和商品销量的有效策略
  • Python 批量解压Zip文件
  • RabbitMQ初入门
  • PyCharm中文使用详解
  • <学习笔记>从零开始自学Python-之-常用库篇(十三)内置小型数据库shelve
  • TiDB 7.4 发版:正式兼容 MySQL 8.0
  • 探秘Spring的设计精髓,深入解析架构原理
  • AD9371 官方例程HDL详解之JESD204B RX侧格式配置及各层主要功能
  • 银河麒麟服务器版v4安装程序缺少依赖包,改为利用手机联网在线安装
  • Android 13.0 通过驱动实现禁用usb鼠标和usb键盘功能
  • 【数据结构】插入排序
  • C++标准模板(STL)- 类型支持 (类型特性,is_pointer,is_lvalue_reference,is_rvalue_reference)
  • pytest-yaml 测试平台-3.创建执行任务定时执行用例
  • RabbitMQ学习05
  • 网络滤波器/网络滤波器/脉冲变压器要怎样进行测试,一般要测试哪些参数?
  • 云计算概述笔记
  • 建筑能源管理(7)——建筑节能诊断内容
  • RabbitMQ基础
  • 华为OD机考算法题:寻找最大价值的矿堆
  • [毕设记录]@开题调研:一些产品
  • 分类预测 | Matlab实现KOA-CNN-LSTM-selfAttention多特征分类预测(自注意力机制)
  • [动态规划] (一) LeetCode 1137.第N个泰波那契数
  • 刀具磨损状态识别(Python代码,MSCNN_LSTM_Attention模型,初期磨损、正常磨损和急剧磨损分类,解压缩直接运行)