Intel qsv + ffmpeg 硬解h264

  Quick Sync Video,简称qsv,是英特尔推出的集成加速接口,使用该接口可以硬解h264,提高解码效率的同时降低CPU占用率,ffmpeg 4.4.2中 doc\example中有一个qsvdec.c的demo,我在此基础上进行修改,实现了硬解h264。

   环境准备

  下载安装Intel Media Mdk,https://software.intel.com/en-us/media-sdk,选择window平台,安装后在安装目录下IntelSWTools\Intel(R) Media SDK 2019 R1\Software Development Kit 有include和lib 文件夹,拷贝lib、dll、头文件备用。

  编码

   创建一个VS c++ 控制台工程,将拷贝的include和lib 等复制到工程目录下,设置好库目录和包含目录以及连接库。新建一个cpp文件,qsvdev.c的代码拷贝到cpp文件,并对代码做出以下修改。

1、修改get_format返回值为AVPixelFormat

static AVPixelFormat get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
{
	while (*pix_fmts != AV_PIX_FMT_NONE) 
	{
		if (*pix_fmts == AV_PIX_FMT_QSV) 
		{
			DecodeContext *decode = (DecodeContext *)avctx->opaque;
			AVHWFramesContext  *frames_ctx;
			AVQSVFramesContext *frames_hwctx;
			int ret;

			/* create a pool of surfaces to be used by the decoder */
			avctx->hw_frames_ctx = av_hwframe_ctx_alloc(decode->hw_device_ref);
			if (!avctx->hw_frames_ctx)
				return AV_PIX_FMT_NONE;
			frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
			frames_hwctx = (AVQSVFramesContext*)frames_ctx->hwctx;

			frames_ctx->format = AV_PIX_FMT_QSV;
			frames_ctx->sw_format = avctx->sw_pix_fmt;
			frames_ctx->width = FFALIGN(avctx->coded_width, 32);
			frames_ctx->height = FFALIGN(avctx->coded_height, 32);
			frames_ctx->initial_pool_size = 32;

			frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;

			ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
			
			if (ret < 0)
				return AV_PIX_FMT_NONE;

			return AV_PIX_FMT_QSV;
		}

		pix_fmts++;
	}

	fprintf(stderr, "The QSV pixel format not offered in get_format()\n");

	return AV_PIX_FMT_NONE;
}

  2、添加SDL 头文件 SDL,在连接器那里输入SDL2.lib、SDL2main.lib,拷贝SDL 相关的DLL到目录下,使用SDL来显示数据。

 SDL 初始化

 创建窗口

screen = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
		decoder_ctx->width, decoder_ctx->height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

 创建渲染器

render = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);

创建纹理

texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_NV12, SDL_TEXTUREACCESS_STREAMING, decoder_ctx->width, decoder_ctx->height);

分配一个buffer用来存储NV12 数据

nv12Data = new unsigned char[decoder_ctx->width * decoder_ctx->height * 1.5];

将NV12 数据拷贝到分配的内存

for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++)//
		{
			for (j = 0; j < (sw_frame->height >> (i > 0)); j++)//
			{
				memcpy(nv12Data + i* sw_frame->width*sw_frame->height + sw_frame->width*j, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width);
			}
		}

 

渲染

SDL_UpdateTexture(texture, NULL, nv12Data, sw_frame->linesize[0]);
		//SDL_UpdateTexture(texture, NULL, sw_frame->data[0], sw_frame->linesize[0]);
		SDL_RenderClear(render);
		SDL_RenderCopy(render, texture, NULL, &sdlRect);
		SDL_RenderPresent(render);

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值