SDL直接渲染yuv视频帧数据

用ffmpeg解码出来的视频数据都是yuv视频帧,直接用sdl渲染可以有效的降低系统的cpu资源

直接上代码把

cpp 复制代码
SDLRender::SDLRender()
{
	SDL_Init(SDL_INIT_VIDEO);
	m_spN12Chech = std::make_shared<std::vector<uint8_t>>();
}
cpp 复制代码
bool SDLRender::DrawFrame(AVFrame *frame)
{
	std::unique_lock<std::mutex> locker(m_mtDrawFrame);
	if (!frame)
	{
		return false;
	}

	if (!m_SdlRender)
	{
		m_SdlRender = SDL_CreateRenderer(m_SdlWindow, -1, SDL_RendererFlags::SDL_RENDERER_ACCELERATED);
	}

	if (frame->width != m_tureWidth || frame->height != m_tureHeight || !m_SdlTexture)
	{
		m_tureWidth = frame->width;
		m_tureHeight = frame->height;

		if (m_SdlTexture)
		{
			SDL_DestroyTexture(m_SdlTexture);
			m_SdlTexture = nullptr;
		}
		
		m_SdlTexture = SDL_CreateTexture(m_SdlRender, GetSDLFormat((AVPixelFormat)frame->format), SDL_TEXTUREACCESS_STREAMING, frame->width, frame->height);
	}

	int linesize = 0;
	switch (frame->format)
	{
	case AV_PIX_FMT_YUVJ420P:
	case AV_PIX_FMT_YUV420P:
		return Draw(frame->data[0], frame->linesize[0], frame->data[1], frame->linesize[1], frame->data[2], frame->linesize[2]);
	case AV_PIX_FMT_NV12:
		if (m_spN12Chech)
		{
			m_spN12Chech->clear();
		}
		else
		{
			return false;
		}
		linesize = frame->width;
		if (frame->linesize[0] == frame->width)
		{
			// 拷贝所有Y分量
			m_spN12Chech->insert(m_spN12Chech->end(), frame->data[0], frame->data[0] + frame->linesize[0] * frame->height);
			// 拷贝所有的UV分量
			m_spN12Chech->insert(m_spN12Chech->end(), frame->data[1], frame->data[1] + frame->linesize[1] * frame->height/2);
		}
		return Draw(m_spN12Chech->data(), linesize);
	case AV_PIX_FMT_RGBA:
	case AV_PIX_FMT_BGRA:
	case AV_PIX_FMT_ARGB:
		return Draw(frame->data[0], frame->linesize[0]);
	default:
		break;
	}

	return false;
}
cpp 复制代码
bool SDLRender::Draw(const unsigned char* y, int y_pitch, const unsigned char* u, int u_pitch, const unsigned char* v, int v_pitch)
{
	if (!y || !u || !v)
	{
		return false;
	}

	std::unique_lock<std::mutex> locker(m_mtSdl);
	if (!m_SdlWindow || !m_SdlRender || !m_SdlTexture)
	{
		return false;
	}

	// 复制内存到显存
	auto re = SDL_UpdateYUVTexture(m_SdlTexture, NULL, y, y_pitch, u, u_pitch, v, v_pitch);
	if (re)
	{
		return false;
	}

	// 清理渲染器
	SDL_RenderClear(m_SdlRender);

	// 如果用户手动设置了缩放,就按照用户设置的大小显示
	// 如果用户没有设置,就传递null, 采用默认的窗口大小
	SDL_Rect* prect = nullptr;
	if (m_nScaleWidth > 0 || m_nScaleHeight > 0)
	{
		SDL_Rect rect;
		rect.x = 0;
		rect.y = 0;
		rect.w = m_nScaleWidth;
		rect.h = m_nScaleHeight;
		prect = &rect;
	}

	// 拷贝材质到渲染器
	re = SDL_RenderCopy(m_SdlRender, m_SdlTexture, NULL, prect);
	if (re)
	{
		return false;
	}

	SDL_RenderPresent(m_SdlRender);
	return true;
}
cpp 复制代码
bool SDLRender::Draw(const unsigned char* data, int linesize)
{
	if (!data)
	{
		return false;
	}

	std::unique_lock<std::mutex> locker(m_mtSdl);
	if (!m_SdlWindow || !m_SdlRender || !m_SdlTexture)
	{
		return false;
	}

	if (linesize <= 0)
	{
		return false;
	}

	// 复制内存到显存
	auto re = SDL_UpdateTexture(m_SdlTexture, NULL, data, linesize);
	if (re)
	{
		return false;
	}

	// 清理渲染器
	SDL_RenderClear(m_SdlRender);

	// 如果用户手动设置了缩放,就按照用户设置的大小显示
	// 如果用户没有设置,就传递null, 采用默认的窗口大小
	SDL_Rect *prect = nullptr;
	if (m_nScaleWidth > 0 || m_nScaleHeight > 0)
	{
		SDL_Rect rect;
		rect.x = 0;
		rect.y = 0;
		rect.w = m_nScaleWidth;
		rect.h = m_nScaleHeight;
		prect = &rect;
	}
	re = SDL_RenderCopy(m_SdlRender, m_SdlTexture, NULL, prect);
	if (re)
	{
		return false;
	}

	SDL_RenderPresent(m_SdlRender);
	return true;
}
相关推荐
换个昵称都难1 小时前
webrtc 音频混音介绍
音视频·webrtc
“码”力全开1 小时前
统一解耦海量设备:基于 Docker 与边缘计算的 GB28181/RTSP 视频中台全协议兼容架构解析(附源码交付)
docker·音视频·边缘计算
爱睡懒觉的焦糖玛奇朵1 小时前
【从视频到数据集:焦糖玛奇朵的魔法工具Dataset Cleaner】
人工智能·python·学习·算法·yolo·音视频
俊哥工具1 小时前
027免费开源硬盘检测工具,一键查看健康度,杜绝数据丢失
pdf·电脑·word·excel·音视频
电商API_1800790524711 小时前
bilibili关键字搜索视频列表|获取视频详情API调用示例
大数据·数据挖掘·网络爬虫·音视频
hz5678912 小时前
国产化视频会议系统怎么做?鲲鹏+麒麟+国密的完整国产化路径
音视频·实时音视频·信息与通信
Code-keys16 小时前
ARM NEON SIMD 编程实战:从音频信号处理到AI算子研发实战
arm开发·音视频·信号处理
dualven_in_csdn18 小时前
一键起飞条件分析
音视频
故渊at21 小时前
第九板块:Android 多媒体体系 | 第二十三篇:AudioFlinger 与 AudioPolicyService 音频架构
android·架构·音视频·audiopolicy·audioflinger
纳祥科技1 天前
NX699,内置精度±5%晶振的lightning苹果PD快充12W
单片机·手机·音视频