当前位置: 首页> 教育> 高考 > SDL直接渲染yuv视频帧数据

SDL直接渲染yuv视频帧数据

时间:2025/8/27 4:16:05来源:https://blog.csdn.net/weixin_38887743/article/details/141351693 浏览次数:0次

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

直接上代码把 

SDLRender::SDLRender()
{SDL_Init(SDL_INIT_VIDEO);m_spN12Chech = std::make_shared<std::vector<uint8_t>>();
}
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;
}
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;
}
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;
}
关键字:SDL直接渲染yuv视频帧数据

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: