H.264视频编码在VC++.Net中的实现

引言:H.264编码技术是俱乐部在过去一段时间内研究的一个方向,对该编码技术进行过实际的开发和应用,并取得了很大的收获。下面将重点介绍H.264视频编码在VC++.Net中的实现。

1.   H.264编码的介绍

H.264是一种 视频高压缩技术,全称是MPEG-4 AVC,用中文说是“活动图像专家组-4的高等视频编码”,或称为MPEG-4 Part10。它是由国际电信标准化部门ITU-T和规定MPEG的国际标准化组织ISO/国际电工协会IEC共同制订的一种活动图像编码方式的国际标准 格式。由于H.264在制定时就充分考虑了多媒体通信对视频编解码的各种要求,并借鉴了H系列和MPEG系列视频标准的研究成果,因而具有明显的优势。 H.264作为最新的国际建议标准,在IP视频监控系统中有着重要的意义。它与目前的Mpeg4和H.263编码相比较,优势表现在以下几个方面:

1)      压缩率和图像质量方面

H.264通过对传统的帧内预测、帧间预测、变换编码和熵编码等算法的改进来进一步提高编码效率和图像质量。在相同的重建图像质量下,H.264比H.263节约50%左右的码率,比Mpeg4节约35%左右。

2)      网络适应性方面

H.264支持不同网络资源下的分级编码传输,从而获得平稳的图像质量。H.264能适应于不同网络中的视频传 输,网络亲和性好。H.264的基本系统无需使用版权,具有开放的性质,能很好地适应IP和无线网络的使用,这对目前的因特网传输多媒体信息、移动网中传 输宽带信息等都具有重要的意义。

3)      抗丢包和抗误码方面

H.264具有较强的抗误码特性,可适应丢包率高、干扰严重的信道中的视频传输。

实际应用中,实时性和较好的图像质量,较低的网络带宽占用以及带宽适应能力是监控系统的主要考虑因素。H.264 相比较以前的视频编码标准,主要在网络接口友好性和高的压缩性能上有了很大的提高。综合以上因素在本系统中采用H.264作为视频数据的编码方式。

2.   H.264编码的实现原理

         

 

1)      量化

H. 264为了提高码率控制的能力, 量化步长的变化的幅度控制在12.5 %左右, 而不是以不变的增幅变化。变换系数幅度的归一化被放在反量化过程中处理以减少计算的复杂性。为了强调彩色的逼真性,对色度系数采用了较小量化步长。

2)      运动补偿

宏块划分方式: H. 264 支持形状不等的宏块划分, 其划分方法有: 16×16, 16×8, 8×16, 8×8, 8×4, 4×8, 4×4. 这种更小的、更多形状的的宏块划分,更切合图形中实际运动物体的形状, 改善运动补偿的精度, 更好的实现运动隔离, 提高图像质量和编码效率. 搜索精度: H. 264 支持1/4 和1/8 精度的运动补偿, 使用一个6 抽头滤波器从整像素样本的到1/2 像素样本, 用线性插值获得1/4 像素样本, 用8 抽头滤波器实现1/8 像素精度。 多参考帧模式: H. 264 在对周期性的运动或背景切换进行预测时, 多参考帧可以提供更好的预测效果。

3)      帧内预测

4)      变换编码

5)      熵编码

3   H.264编码算法的实现

在H.264编码具体实现过程中,采用了目前国际上应用最广泛的开源编码器X.264作为实现的基础。X.264和JM系列编码器、T.264编码器相比 有着优秀的性能和出色效果。由于X.264没有提供直接的开发API,所以在本系统中的编码部分重新封装了X.264的编码API,便于软件系统的设计和 使用。以下是本系统中H.264编码的具体实现过程:

1)      RGB和YUV颜色空间的转换

在系统中通过Logitech摄像头获得的视频数据为RGB24格式,但是X.264的输入流为标准的YUV(4:2:0)的图像子采样格式。因此,在编 码前需要将RGB颜色空间转换为YUV的颜色空间。实现的函数调用有InitLookupTable()用于初始化色彩空间转换;

RGB2YUV420(int x_dim, int y_dim, unsigned char *bmp, unsigned char *yuv, int flip);用于实际的转换。由于人眼的生理特性,经过图像子采样后,实际的图像大小已经减小为采样前的1.5个样本点,即减小了一半的数据量。

2)      设置H.264编码参数

使用x264_param_default(x264_param_t *param)对当前需要编码的图像参数进行设置。包括数据帧数量(param .i_frame_total)、采样图像的长宽度和高度(param .i_width,param .i_height)、视频数据比特率(param .rc.i_bitrate) 、视频数据帧率(param .i_fps_num)等参数进行设置,以完成编码前预设置。

3)      初始化编码器

将上步中的设置作为编码器初始化的参数,x264_t *x264_encoder_open   ( x264_param_t *param )。如果初始化失败将返回NULL,在这里需要对编码器初始化结果进行处理。

4)      分配编码空间

如果编码器初始化成功,则需要为本次处理分配内存空间

Void x264_picture_alloc(x264_picture_t *pic, int i_csp, int i_width, int i_height)。

5)      图像编码

将以上步骤初始化后的数据作为编码输入,使用下面的方法进行编码:

int x264_encoder_encode( x264_t *h,x264_nal_t **pp_nal, int *pi_nal,x264_picture_t *pic_in,x264_picture_t *pic_out );

6)      资源回收

编码完成后,需要回收系统资源和关闭编码器,使用以下函数调用实现回收。

void x264_picture_clean( x264_picture_t *pic );

void x264_encoder_close( x264_t *h );

至此,完成了H.264编码,编码后的数据量将大大减小。我们可以对编码后的数据做相关的进一步处理。

H.264编码算法的完整源代码

文件:VideoEncoderX264.h

class CVideoEncoderX264 : 
{
public:
 CVideoEncoderX264(void);
 ~CVideoEncoderX264(void);

 virtual bool Connect(CVideoEnDecodeNotify* pNotify, const CVideoEnDecodeItem& Item);
 virtual void Release(void);
 virtual void Encode(BYTE* pInData, int nLen, BYTE* pOutBuf, int& nOutLen, int& nKeyFrame);

private:
  x264_picture_t m_Pic;
  x264_t *h;
  x264_param_t param;

  void Flush(void);
};

文件:VideoEncoderX264.cpp

bool CVideoEncoderX264::Connect(CVideoEnDecodeNotify* pNotify, const CVideoEnDecodeItem& Item)
{
 CBase::Connect(pNotify, Item);

 ParseSize(Item.m_stSize);

 x264_param_default( &param );

 param.i_threads = 1;

 param.i_frame_total = 0;

 param.i_width  = m_nWidth;
 param.i_height = m_nHeight;

 param.i_keyint_min = Item.m_nKeyInterval;
 param.i_keyint_max = Item.m_nKeyInterval * 10;

 param.i_fps_num = Item.m_nFps;*/
 param.i_log_level = X264_LOG_NONE;

if( ( h = x264_encoder_open( &param ) ) == NULL )
    {
        return false;
    }

/* Create a new pic */
    x264_picture_alloc( &m_Pic, X264_CSP_I420, param.i_width, param.i_height );

return true;
}

void CVideoEncoderX264::Release(void)
{
 Flush();

x264_picture_clean( &m_Pic );
    x264_encoder_close( h );

CBase::Release();
}

void CVideoEncoderX264::Encode(BYTE* pInData, int nLen, BYTE* pOutBuf, int& nOutLen, int& nKeyFrame)
{
 if(nLen != param.i_width * param.i_height * 3)
  return;

param.i_frame_total ++;

memcpy(m_Pic.img.plane[0], pInData, param.i_width * param.i_height);
 memcpy(m_Pic.img.plane[1], pInData + param.i_width * param.i_height, param.i_width * param.i_height / 4);
 memcpy(m_Pic.img.plane[2], pInData + param.i_width * param.i_height * 5 / 4, param.i_width * param.i_height / 4);

m_Pic.i_pts = (int64_t)param.i_frame_total * param.i_fps_den;

static x264_picture_t pic_out;
    x264_nal_t *nal = NULL;
    int i_nal, i;

if( &m_Pic )
    {
        m_Pic.i_type = X264_TYPE_AUTO;
        m_Pic.i_qpplus1 = 0;
    }

//TraceTime("x264_encoder_encode begin");

if( x264_encoder_encode( h, &nal, &i_nal, &m_Pic, &pic_out ) < 0 )   {
  return;
    }

//TraceTime("x264_encoder_encode   end");

int nOutCanUse = nOutLen;
 nOutLen = 0;
    for( i = 0; i < i_nal; i++ )
    {
  int i_size = 0;

if( ( i_size = x264_nal_encode( pOutBuf + nOutLen, &nOutCanUse, 1, &nal[i] ) ) > 0 )
  {
   nOutLen += i_size;
   nOutCanUse -= i_size;
  } 
 }

nKeyFrame = pic_out.i_type==X264_TYPE_IDR;// || (pic_out.i_type==X264_TYPE_I && coCfg->x264_max_ref_frames==1);
}

void CVideoEncoderX264::Flush(void)
{
 x264_picture_t pic_out;
    x264_nal_t *nal;
    int i_nal, i;
    int i_file = 0;

if( x264_encoder_encode( h, &nal, &i_nal, NULL, &pic_out ) < 0 ){

}
}

转载于:https://www.cnblogs.com/shulianghe/archive/2012/11/21/3724154.html

H.264视频编码在VC .Net中的实现(H264全文)相关推荐

  1. H.264视频编码在VC++.Net中的实现

    From: http://blog.csdn.net/xwchen/article/details/5052981 引言:H.264编码技术是俱乐部在过去一段时间内研究的一个方向,对该编码技术进行过实 ...

  2. 【Android RTMP】安卓直播推流总结 ( 直播服务器搭建 | NV21 图像采集 | H.264 视频编码 | PCM 音频采集 | AAC 音频编码 | RTMP 包封装推流 )

    文章目录 一. 安卓直播推流专栏博客总结 二. 相关资源介绍 三. GitHub 源码地址 四. 整体 Android 直播推流数据到服务器并观看直播演示过程 Android 直播推流流程 : 手机采 ...

  3. 音视频开发(24)---H.264视频编码基本知识

    H.264视频编码基本知识 一.视频编码技术的发展历程 视频编码技术基本是由iso/iec制定的mpeg-x和itu-t制定的h.26x两大系列视频编码国际标准的推出.从h.261视频编码建议,到 h ...

  4. H.264视频编码推荐的分辨率和码率配置表

    在各种视频编码标准中,行业一直在求追"高压缩比(数据量越小越好)",同时又保证"高视频质量"的算法.鱼和熊掌不可兼得,视频编码是一种折中的游戏.参数" ...

  5. Windows 下令 OpenCV 支持 h.264 视频编码的方法

    引言 OpenCV 和 ffmpeg 修改 opencv_ffmepgdll 的步骤 安装 MinGW 编译 x264 编译 ffmpeg 生成 opencv_ffmpegdll 准备 生成 测试 结 ...

  6. H.264视频编码基本知识

    一.视频编码技术的发展历程 视频编码技术基本是由ISO/IEC制定的MPEG-x和ITU-T制定的H.26x两大系列视频编码国际标准的推出.从H.261视频编码建议,到 H.262/3.MPEG-1/ ...

  7. MPEG-4 AVC/H.264 视频编码资源列表(中文)

    ============================================================================ 软件编解码器: =============== ...

  8. 视频【编码】原理(H.264 librtmp推流),图像编码中sps ,pps ,nalu ,frame ,silce ect

    视频编码格式:H264, VC-1, MPEG-2, MPEG4-ASP (Divx/Xvid), VP8, MJPEG 等.  音频编码格式:AAC, AC3, DTS(-HD), TrueHD, ...

  9. 实现RTP协议的H.264视频传输系统

    1.  引言        随着信息产业的发展,人们对信息资源的要求已经逐渐由文字和图片过渡到音频和视频,并越来越强调获取资源的实时性和互动性.但人们又面临着另外一种不可避免的尴尬,就是在网络上看到生 ...

最新文章

  1. SharePoint 2003, 2007对上传文件的URL的长度限制
  2. 如何制作并更改项目icon文件
  3. HDU 1002 大整数
  4. 成都睿铂 | 云南省地矿测绘院1:500地形免像控项目分享
  5. JAVA时间操作类常用方法汇总
  6. [转]说说大型高并发高负载网站的系统架构
  7. html中用js调用ASP文件 实现静态页面动态显示
  8. 实对称矩阵的特征值求法_实对称矩阵、相似、标准型、合同的逻辑网
  9. python爬淘宝评论源代码_一篇文章教会你用Python爬取淘宝评论数据(写在记事本)...
  10. 科研必备:LaTeX论文排版软件的简介,安装与使用教程
  11. HttpClient模拟请求
  12. 一文读懂反向传播算法原理
  13. Rhino7.4软件安装教程
  14. 简单A/BTest验证图片懒加载效果
  15. (分布式网络)基于残差网络的多光谱全色图像分布式融合框架
  16. WannaCryptor 勒索蠕虫样本深度技术分析
  17. socket缓冲区/sk_buffer/滑动窗口关系
  18. 智能锁忘记密码怎么办
  19. OJ 1199 堆积木
  20. Java项目:ERP管理系统(java+SpringBoot+EasyUI+maven+mysql)

热门文章

  1. Cordic的学习之硬件实现
  2. Java把表导出成Excel的代码
  3. 新闻更新延时引发的学习,CACHE的利用。
  4. php读写xml文件,另辟蹊径 搞定PHP读取XML大文件 数据导入
  5. cocos2dx 圆盘抽奖_【cocos2dx 3.3 lua】06 抽奖转盘效果
  6. java定义一个类显示没有_Java 中的每个类都至少有一个构造方法,一个类中如果没有定义构造方法,系统会自动为这个类创建一个默认的构造方法。_学小易找答案...
  7. 基于FPGA实现压缩算法
  8. Vivado生成bit文件报错彻底解决
  9. mvc html绑定变量,c# – Asp.Net MVC 3使用变量对象进行自定义模型绑定
  10. diag开关什么意思_1P空气开关便宜、好用,为什么电工师傅却要我们买2P空气开关?...