用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 = ▭
- }
- // 拷贝材质到渲染器
- 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 = ▭
- }
- re = SDL_RenderCopy(m_SdlRender, m_SdlTexture, NULL, prect);
- if (re)
- {
- return false;
- }
- SDL_RenderPresent(m_SdlRender);
- return true;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |