视频采集、视频压缩

简介:

1.引言

      视频的采集和压缩是进行视频传输、监控等视频应用开发时必须采取的步骤。 
      关于视频采集,本文探讨了一种基于Windows平台的简单而实用的方法,利用微软提供的VFW(Video For Windows)软件包来实现,只需要有一般的USB摄像头,就可以方便地对视频进行采集和保存。 
    
视频压缩方面,本文探讨了如何利用现阶段压缩率最大、传输可靠性最高的一种编码标准—H.264标准的开源编码器(T264)来实现对采集到的视频文件进行压缩的方法,利用VFW 所采集到的视频格式是没有进行任何压缩的AVI 格式,首先对AVI 格式进行转换,再利用T264源码对转换后的视频流文件进行压缩编码,这样就极大地压缩了视频文件,方便视频的传输。

2.视频信息的采集

    由于利用VFW软件包能够方便地实现视频、音频数据流到AVI文件的存储,在Visual C++中将VFW软件包的函数封装成为AVICAP窗口类函数,利用AVICAP窗口类函数,程序员能够通过发送消息或设置属性来捕获、播放和编辑视频剪辑,能灵活地实现从模拟视频源采集数字视频信号,并将捕捉的视频流存储到磁盘或者直接对视频缓存进行处理。
    
本文所述的方法是在Viusal C++ 6.0 软件平台上实现的,而软件实现的具体步骤如下: 
    1)在采集视频前必须先创建一个视频采集的窗口,以及添加一些具体的操作按钮,窗口利用函数capCreateCaptureWindow 来创建,如果窗口创建成功,返回窗口的句柄(程序中hwndV),如果创建不成功,则返回NULL 值。具体的创建程序及注释如下: 
       hwndV=capCreateCaptureWindow( 
      (LPSTR) "My Capture Window",   //捕捉窗口名称
               
 WS_CHILD | WS_VISIBLE,       //窗口风格样式 
                        150, 150, 300, 280,          //窗口位置和大小 
                        (HWND) hwndMain,             //父窗口句柄 
                
(int) 1);                    //窗口标识 
       2)采集开始前,要将采集窗口与视频设备相关联,VFW接口采用capDriverConnect (hWndCap,,nIndex)这个函数,式中:hWndCap所建立的视频捕捉窗口的句柄;nIndex为查询得到的视频卡驱动程序的索引号。接下来,获取视频采集设备的能力及状态信息,VFW中采用函数capDriverGetCaps(hwnd,psCaps,wsize)来得到采集设备的能力,而采用capGetStatus (hwnd,s,size)函数来得到采集设备的状态信息。
       3)启动显示模式并设置其模式参数,AVICAP  窗口类采用两个函数来实现,具体程序和注释如下:  
       capPreviewRate( hwndVideo, 66); //设置预览播放速率 
        capreview( hwndVideo, TRUE);   //启动预览模式 

      4)采集视频流并保存,并终止视频采集并断开与采集设备的连接,在程序的开头定义一个结构体OPENFN,用于初始化一个对话框,而这个对话框是用来保存视频的对话框。 
  具体程序如下: 
 if (!isRecordFileOpen) 

      OPENFN ofname;     //打开文件结构体 
       ZeroMemory(&ofname, sizeof(OPENFN)); //初始化结构体 
      ofname.lStructSize = sizeof(OPENFN);    //结构体的大小 
      ofname.hwndOwner = hwndMain;            //主窗口句柄 
     ofname.lpstrFile = recordFile;         //保存的文件指针 
     ofname.nMaxFile = sizeof(recordFile);   //保存文件的大小 
      ofname.lpstrFilter = "Video\0*.avi";   //保存文件的后缀 
      ofname.nFilterIndex = 1;               //文件索引号 
      ofname.lpstrFileTitle = NULL;          //文件名指针 
      ofname.nMaxFileTitle = 0; 
    ofname.lpstrInitialDir = NULL; 
    ofname.Flags=OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST; 

     if(GetSaveFileName(&ofn) == TRUE)    //显示保存文件的对话框 
     
       strcpy(recordFile, ofn.lpstrFile); 
       strcat(recordFile, ".avi"); 
       isRecordFileOpen = true; 
     } 
 } 

        设置好保存文件以后,需用函数CreateThread来创建一个录像的线程在其中采集视频流,并利用函数capDriverDisconnect 来终止视频采集并断开与采集设备的连接,录像线程的具体代码如下:

       DWORD id;                          //创建一个录像线程 
          SECURITY_ATTRIBUTES ma; 
       ma.nLength = sizeof(SECURITY_ATTRIBUTES); 
       ma.lpSecurityDescriptor = NULL; 
       ma.bInheritHandle = TRUE; 
       hVideoThread = (&ma, (ULONG)0, 
       videoThreadProc, (LPVOID)(ULONG)0, (ULONG)0, &id);

3.视频格式的转换

     本文所采用的是基于H.264编码标准的视频压缩方法,所利用的源码是由中国视频编码自由组织联合开发的t264编解码器,在使用本源码前,编码器要求进行压缩的文件格式应为YUV 格式视频文件,而VFW采集到的视频文件是最原始的AVI 格式,因而要进行格式的转换 。 
       从AVI格式到YUV 格式的转换,并没有直接的公式,而AVI视频文件流的每一帧对应一个BMP(RGB)文件,则可以利用公式转换成YUV 文件,转换的公式如下:
     Y = 0.299R + 0.587G + 0.114B 
     Cb = 0.564(B - Y ) 
     Cr = 0.713(R -Y ) 

      其中,Cb 对应U,Cr 对应V,分别表示构成彩色的两个分量,而在程序中,则通过以下的程序来实现(按4:2:0 采样格式): 
      void RGB2YUV ( uint8 R, uint8 G, uint8 B, uint8 *y, uint8 *u, uint8 *v ) 
   { 
     *y = Clip ( ( ( 66 * int(R) + 129 * int(G) + 25 * int(B) + 128) >> 8) + 16 ); 
     *u = Clip ( ( ( -38 * int(R) - 74 * int(G) + 112 * int(B) + 128) >> 8) + 128 ); 
     *v = Clip ( ( ( 112 * int(R) - 94 * int(G) - 18 * int(B) + 128) >> 8) + 128 ); 
   }

4.利用编码器进行压缩编码

     由中国视频编码自由组织联合开发的编码器在基于VisualC++平台上创建了一个console程序,而前述的视频采集程序因为有窗口、按钮等视图窗口,故是一个windows程序,在Visual C++平台中,要将console 程序和windows 程序很好地结合在一起使用,是个很复杂的过程,因此,可以在前面视频采集程序里面运用一个C++函数ShellExecute 来调用编码器函数。 
    具体实现的步骤如下: 

    1)首先针对采集后经格式转换生成的YUV文件,得到它的帧数目,在配置文件enconfig.txt修改编码帧的数目,例如如果帧数目为100,将enconfig.txt 文件中的第6、7、8 行: 
     300 # total frame number 
    300 # i intervals 
    300 # idr intervals 

     改为 :
    100 # total frame number 
    100 # i intervals 
    100 # idr intervals 

     帧数目修改以后,文件生成的路径也应该改为最终exe 文件生成的路径,在enconfig.txt的最后三行进行修改。 
    1)编译编码器,是采用的CONSOLE 程序,一般是在命令行中来执行exe 程序,而本文中的方法是利用入口函数main(int argc, char* argv[])的特征,其中,argc 表示参数的个数,而argv[]数组用于保存参数的指针,在程序中就对参数进行赋值,省去了进入命令行进行执行的繁琐过程,从而生成一个可以直接拿来运用的exe 程序。具体赋值语句如下: 
     argv[0]="T264.exe"; 
   argv[1]="-e"; 
   argv[2]="enconfig.txt"; 

   2)设置t264.exe 文件路径,上述的过程中已经生成一个可执行的t264.exe 文件,如果将YUV文件放在与之相同的目录下,在调试运行这个程序的时候就可以生成264码流文件,达到编码的目的。但本文是需要将采集、压缩编码在同一个程序中完成,因而把生成的t264.exe文件复制到采集程序的调试目录下面。 
3)上述的工作都做好以后,可以在采集程序里面调用编码器程序了,这时用一个函数来
实现,具体代码是:  
           ShellExecute(NULL,"open","t264.exe", 
       "T264.exe –e enconfig.txt",NULL,SW_SHOWNORMAL); 

      其中,SW_SHOWNORMAL 指的是一种程序运行风格,此时代表正常运行,在调用时可以看到程序运行的全部过程(DOS命令窗口显示),如果需要程序透明执行,不可见,则可以用SW_HIDE 来代替它。 
      至此,整个视频采集、格式转换与编码压缩的过程就全部完成了,本文中所采集的AVI文件大小为4.075M,经格式转换后的YUV 文件大小为5.458M,而最终生成的264 码流大小只有27k,压缩率达到了150.9倍。

5.总结 

   
本文所探讨的从视频采集、格式转换到压缩编码的整个过程,可以简单方便地完成,可以直接应用在视频监控或者视频的网络传输等的前期开发。佰锐科技已为视频监控音视频即时通讯提供了解决方案。




本文转自 fanxiaojun 51CTO博客,原文链接:http://blog.51cto.com/2343338/493899,如需转载请自行联系原作者

相关文章
|
9月前
|
编解码 Windows
如何将视频压缩到指定的大小?
如何将视频压缩到指定的大小?
|
9月前
|
编解码 C++
基于Live555实现RtspServer及高清高分辨率和高码率视频传输优化
基于Live555实现RtspServer及高清高分辨率和高码率视频传输优化
381 0
|
编解码
流媒体技术学习笔记之(五)码流、码率、采样率、比特率、帧速率、分辨率、高清视频的概念
码流、码率、采样率、比特率、帧速率、分辨率、高清视频的概念   高清视频主要编码   480P格式:720x480  720P格式:1280x720 【表现体育节目、快速运动的视频时,720P更明显】 1080P格式:1920x1080 【适合普通电视节目、电影等慢速运动的视频时,1080P更明显】 1、码流(码率)           码流(Data Rate)是指视频文件在单位时间内使用的数据流量,也叫码率或码流率,通俗一点的理解就是取样率,是视频编码中画面质量控制中最重要的部分,一般我们用的单位是kb/s或者Mb/s。
4021 0
【音频处理】乐器音符播放时电流处理 ( 使用均衡器调节低频 )
【音频处理】乐器音符播放时电流处理 ( 使用均衡器调节低频 )
119 0
【音频处理】乐器音符播放时电流处理 ( 使用均衡器调节低频 )
|
Web App开发 编解码 监控
网页播放海康威视大华华为摄像头RTSP流,不需转码转流,延迟毫秒级,支持多路播放、H.264/H.265及1080P/2K/4K,支持抓图录像字幕
在遍地都是摄像头的今天,往往需要在各种信息化、数字化、可视化B/S系统中集成实时视频流播放等功能,海康、大华、华为等厂家摄像头或录像机等设备一般也都遵循监控行业标准,支持国际标准的主流传输协议RTSP输出,而Chrome、Firefox、Edge等新一代浏览器从2015年开始取消了NPAPI插件技术支持导致不再支持RTSP的原生播放
593 0
|
编解码
小技巧:不用任何媒体处理软件进行视频压缩
小技巧:不用任何媒体处理软件进行视频压缩
414 0
|
传感器 SQL 编解码
无电池摄像头如何实现高清晰度视频编码?
本文来自日本法政大学理工学院副教授 周金佳在LiveVideoStackCon 2019上海大会演讲,介绍了一种可被广泛应用于监控系统的超低功耗的视频采集和编码系统,在保证画质的同时,可大大降低系统的功耗。
232 0
无电池摄像头如何实现高清晰度视频编码?
|
算法
《数字视频和高清:算法和接口》一2.4图像获取
本节书摘来华章计算机《数字视频和高清:算法和接口》一书中的第2章 ,第2.4节, [加]查尔斯·波因顿(Charles Poynton)著 刘开华 褚晶辉 马永涛 吕卫 宫霄霖 等译 译更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1688 0
|
算法 测试技术
《数字视频和高清:算法和接口》一3.2对比度
本节书摘来华章计算机《数字视频和高清:算法和接口》一书中的第3章 ,第3.2节, [加]查尔斯·波因顿(Charles Poynton)著 刘开华 褚晶辉 马永涛 吕卫 宫霄霖 等译 译更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1300 0