windows 10 vs2017 x264的编译和使用测试

1 篇文章 0 订阅
1 篇文章 0 订阅

做了一次更新,工具改成vs2019了。

x264这个sdk非常棒!

————————————————————————————————

主页:x264, the best H.264/AVC encoder - VideoLANhttps://www.videolan.org/developers/x264.html

在win10 中,用 git bash中下载github上的x264源代码:

git clone https://code.videolan.org/videolan/x264.git

如果上述链接找不到,可以在此处下载源代码

在 MSYS2的MinGW 64bit中配置好开发环境

然后进入x264源代码目录:

$cd   xxx/x264

然后执行如下命令:

$./configure    --enable-shared     --disable-asm

完毕后,执行make:

$make -j16

$ls

————————————————————————————————

下载pexports 源代码:在 git bash中执行:

git clone  https://github.com/Crystalnix/pexports-0.44.git

如果上述源码链接已经不存在,可以在此处下载

在Msys2中执行:

$make clean

删掉Makefile中第一行里的   -m32,并执行编译命令:

$make

$ls

在CMD中执行 p e x p o r t s . e x e :

拷贝 p e x p o r t s . e x e 放到

D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\bin\Hostx64\x64

打开vs2017开始中的 “VS 2017的x64 Native命令提示符

把libx264-164.dll拷贝到一个独立的文件夹,然后执行:

pexports ./libx264-164.dll > libx264-164.def

再在工具执行:

lib /def:libx264-164.def /machine:x64 /out:libx264-164.lib

把x264/ 文件夹中的include文件夹拷贝到安装目录D:\x264,把其他的libx264-164.dll和libx264-164.lib放到  D:\x264\bin目录和D:\x264\lib目录中。

然后就可以在vs2017的vc项目的x64的release中使用了。

测试环境,下面这个经典的例子已经包含了编码器的主要使用流程,只是参数设置上略显单调,参数的使用需要慢慢掌握。

新建VC 2017的控制台程序,设置为x86项目,配置属性中的 包含目录 和 库目录 以及 链接输入libx264-164.lib:

#include <cassert>
#include <iostream>
#include <string>
#include "stdint.h"
extern "C"
{
#include "x264.h"
};
unsigned int g_uiPTSFactor = 0;
int iNal = 0;
x264_nal_t* pNals = NULL;
int encode(x264_t* p264, x264_picture_t* pIn, x264_picture_t* pOut);
int main(int argc, char** argv)
{
	int iResult = 0;
	x264_t* pX264Handle = NULL;

	x264_param_t* pX264Param = new x264_param_t;
	assert(pX264Param);
	//* 配置为默认参数
	x264_param_default(pX264Param);
	//* cpuFlags
	pX264Param->i_threads = X264_SYNC_LOOKAHEAD_AUTO;
	//* video Properties
	pX264Param->i_width = 320; //* width
	pX264Param->i_height = 240; //* height
	pX264Param->i_frame_total = 0; //* 视频总帧数,0表示任意
	pX264Param->i_keyint_max = 10;
	//* bitstream parameters
	pX264Param->i_bframe = 5;
	pX264Param->b_open_gop = 0;
	pX264Param->i_bframe_pyramid = 0;
	pX264Param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;

	//* 比特流参数
	//pX264Param->vui.i_sar_width = 1080;
	//pX264Param->vui.i_sar_height = 720;

	//* Log参数
	pX264Param->i_log_level = X264_LOG_DEBUG;
	//* Rate control Parameters
	pX264Param->rc.i_bitrate = 1024 * 10;//* 码率(Kbps)
	//* muxing parameters
	pX264Param->i_fps_den = 1; //* 帧率分母
	pX264Param->i_fps_num = 25;//* 帧率分子
	pX264Param->i_timebase_den = pX264Param->i_fps_num;
	pX264Param->i_timebase_num = pX264Param->i_fps_den;

	//* 设置编码等级profile : baseline、main、height ( 直播baseline:流畅 、Main:有停顿现象 、本地FLV文件:main)
	x264_param_apply_profile(pX264Param, x264_profile_names[1]);

	//* 创建264编码器。后面可以使用x264_encoder_parameters来编码器参数,可以使用x264_encoder_reconfig更新设置参数
	pX264Handle = x264_encoder_open(pX264Param);
	assert(pX264Handle);

	//* 获取流的PPS和SPS
	iResult = x264_encoder_headers(pX264Handle, &pNals, &iNal);
	assert(iResult >= 0);
	//* PPS SPS 解析
	for (int i = 0; i < iNal; ++i)
	{
		switch (pNals[i].i_type)
		{
		case NAL_SPS:
			break;
		case  NAL_PPS:
			break;
		default:
			break;
		}
	}

	//* 编码器缓存的最大帧数
	int iMaxFrames = x264_encoder_maximum_delayed_frames(pX264Handle);

	//* 编码需要的临时变量
	iNal = 0;
	pNals = NULL;
	x264_picture_t* pPicIn = new x264_picture_t;
	x264_picture_t* pPicOut = new x264_picture_t;

	x264_picture_init(pPicOut);
	x264_picture_alloc(pPicIn, X264_CSP_I420, pX264Param->i_width, pX264Param->i_height);
	pPicIn->img.i_csp = X264_CSP_I420;
	pPicIn->img.i_plane = 3;

	//* 创建264本地视频文件
	FILE* pFile;
	fopen_s(&pFile,"d:\\hellox264.264", "wb");
	assert(pFile);

	//* 一帧中YUV420中Y的数据长度
	int iDataLen = pX264Param->i_width * pX264Param->i_height;
	uint8_t* data = new uint8_t[iDataLen];

	unsigned int  uiComponent = 0;
	while (++uiComponent<1030)
	{
		//* 每一帧的数据构成YUV420
		::memset(data, uiComponent, iDataLen);
		::memcpy(pPicIn->img.plane[0], data, iDataLen);
		::memcpy(pPicIn->img.plane[1], data, iDataLen / 4);
		::memcpy(pPicIn->img.plane[2], data, iDataLen / 4);

		if (uiComponent <= 1000)
		{
			pPicIn->i_pts = uiComponent + g_uiPTSFactor * 1000;
			encode(pX264Handle, pPicIn, pPicOut);
		}
		else
		{
			int iResult = encode(pX264Handle, NULL, pPicOut);
			if (0 == iResult)
			{
				//uiComponent = 0;
				++g_uiPTSFactor;

			}
		}

		//* 编码完成的多帧数据逐一写入视频文件
		for (int i = 0; i < iNal; ++i)
		{
			fwrite(pNals[i].p_payload, 1, pNals[i].i_payload, pFile);
		}
	}
	//* 释放清除图像数据
	x264_picture_clean(pPicIn);
//	x264_picture_clean(pPicOut);
	//* 利用句柄关闭解码器
	x264_encoder_close(pX264Handle);
	pX264Handle = NULL;

	delete pPicIn;
	pPicIn = NULL;

	delete pPicOut;
	pPicOut = NULL;

	delete pX264Param;
	pX264Param = NULL;

	delete[] data;
	data = NULL;
	return 0;
}

int encode(x264_t* pX264Handle, x264_picture_t* pPicIn, x264_picture_t* pPicOut)
{

	int iResult = 0;
	iResult = x264_encoder_encode(pX264Handle, &pNals, &iNal, pPicIn, pPicOut);
	if (0 == iResult)
	{
		std::cout << "编码成功,但是缓存在编码器中" << std::endl;
	}
	else
		if (iResult < 0)
		{
			std::cout << "编码出错" << std::endl;
		}
		else
			if (iResult > 0)
			{
				std::cout << "编码成功,并需要写入视频文件流" << std::endl;
			}

	
	int iFrames = x264_encoder_delayed_frames(pX264Handle);
	std::cout << "缓冲帧数:" << iFrames << "\n";//因为要进行编码,所以编码器需要缓存很多帧才好生成I、P、B帧
	return iFrames;
}

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值