Initial setup for CLion
This commit is contained in:
244
MediaClient/media/video_render_sdl.cpp
Normal file
244
MediaClient/media/video_render_sdl.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sys_inc.h"
|
||||
#include "video_render_sdl.h"
|
||||
#include "lock.h"
|
||||
extern "C"
|
||||
{
|
||||
#include <libavutil/imgutils.h>
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
|
||||
static void * g_sdl_mutex = sys_os_create_mutex();
|
||||
|
||||
/***************************************************************************************/
|
||||
|
||||
CSDLVideoRender::CSDLVideoRender()
|
||||
: CVideoRender()
|
||||
, m_pWindow(NULL)
|
||||
, m_pRenderer(NULL)
|
||||
, m_pTexture(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CSDLVideoRender::~CSDLVideoRender()
|
||||
{
|
||||
unInit();
|
||||
}
|
||||
|
||||
BOOL CSDLVideoRender::init(WId hWnd, int w, int h, int videofmt)
|
||||
{
|
||||
CVideoRender::init(hWnd, w, h, videofmt);
|
||||
|
||||
CLock lock(g_sdl_mutex);
|
||||
|
||||
m_bInited = initTexture();
|
||||
|
||||
return m_bInited;
|
||||
}
|
||||
|
||||
void CSDLVideoRender::unInit()
|
||||
{
|
||||
CLock lock(g_sdl_mutex);
|
||||
|
||||
if (m_pTexture)
|
||||
{
|
||||
SDL_DestroyTexture(m_pTexture);
|
||||
m_pTexture = NULL;
|
||||
}
|
||||
|
||||
if (m_pRenderer)
|
||||
{
|
||||
SDL_DestroyRenderer(m_pRenderer);
|
||||
m_pRenderer = NULL;
|
||||
}
|
||||
|
||||
if (m_pWindow)
|
||||
{
|
||||
SDL_DestroyWindow(m_pWindow);
|
||||
m_pWindow = NULL;
|
||||
}
|
||||
|
||||
m_bInited = FALSE;
|
||||
}
|
||||
|
||||
BOOL CSDLVideoRender::reInit(WId hWnd, int w, int h, int videofmt)
|
||||
{
|
||||
BOOL ret;
|
||||
#ifdef IOS
|
||||
char title[512] = {'\0'};
|
||||
|
||||
if (m_pWindow)
|
||||
{
|
||||
const char * p_title = SDL_GetWindowTitle(m_pWindow);
|
||||
if (p_title)
|
||||
{
|
||||
strncpy(title, p_title, sizeof(title)-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
unInit();
|
||||
|
||||
ret = init(m_hWnd, w, h, m_nVideoFmt);
|
||||
|
||||
#ifdef IOS
|
||||
if (ret && m_pWindow)
|
||||
{
|
||||
SDL_SetWindowTitle(m_pWindow, title);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL CSDLVideoRender::render(AVFrame * frame, int mode)
|
||||
{
|
||||
if (!m_bInited || NULL == frame)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return renderTexture(frame, mode);
|
||||
}
|
||||
|
||||
BOOL CSDLVideoRender::initTexture()
|
||||
{
|
||||
#ifdef IOS
|
||||
// On Mac platform, SDL does not support rendering videos on child windows
|
||||
// and must be presented on a separate top-level window
|
||||
m_pWindow = SDL_CreateWindow("", 0, 0, 400, 300, SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
|
||||
#else
|
||||
m_pWindow = SDL_CreateWindowFrom((void *)m_hWnd);
|
||||
#endif
|
||||
if (NULL == m_pWindow)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
|
||||
if (NULL == m_pRenderer)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_pTexture = SDL_CreateTexture(m_pRenderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, m_nVideoWidth, m_nVideoHeight);
|
||||
if (NULL == m_pTexture)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SDL_ShowWindow(m_pWindow);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSDLVideoRender::renderTexture(AVFrame * frame, int mode)
|
||||
{
|
||||
int pitch;
|
||||
uint8 * ptr;
|
||||
uint8 * pixels;
|
||||
AVFrame dstFrame;
|
||||
|
||||
if (m_nVideoWidth != frame->width || m_nVideoHeight != frame->height)
|
||||
{
|
||||
if (!reInit(m_hWnd, frame->width, frame->height, m_nVideoFmt))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
m_nVideoWidth = frame->width;
|
||||
m_nVideoHeight = frame->height;
|
||||
}
|
||||
|
||||
memset(&dstFrame, 0, sizeof(AVFrame));
|
||||
|
||||
SDL_LockTexture(m_pTexture, NULL, (void **)&pixels, &pitch);
|
||||
|
||||
av_image_fill_arrays(dstFrame.data, dstFrame.linesize, pixels, AV_PIX_FMT_YUV420P, m_nVideoWidth, m_nVideoHeight, 1);
|
||||
|
||||
// swap UV plane
|
||||
ptr = dstFrame.data[1];
|
||||
dstFrame.data[1] = dstFrame.data[2];
|
||||
dstFrame.data[2] = ptr;
|
||||
|
||||
av_image_copy(dstFrame.data, dstFrame.linesize, (const uint8_t**)frame->data, frame->linesize, AV_PIX_FMT_YUV420P, m_nVideoWidth, m_nVideoHeight);
|
||||
|
||||
SDL_UnlockTexture(m_pTexture);
|
||||
|
||||
SDL_RenderClear(m_pRenderer);
|
||||
|
||||
int w, h;
|
||||
SDL_Rect rect;
|
||||
|
||||
SDL_GetRendererOutputSize(m_pRenderer, &w, &h);
|
||||
|
||||
if (mode == RENDER_MODE_KEEP)
|
||||
{
|
||||
double dw = w / (double) m_nVideoWidth;
|
||||
double dh = h / (double) m_nVideoHeight;
|
||||
double rate = (dw > dh) ? dh : dw;
|
||||
|
||||
int rw = (int)(m_nVideoWidth * rate);
|
||||
int rh = (int)(m_nVideoHeight * rate);
|
||||
|
||||
rect.x = (w - rw) / 2;
|
||||
rect.y = (h - rh) / 2;
|
||||
rect.w = rw;
|
||||
rect.h = rh;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = w;
|
||||
rect.h = h;
|
||||
}
|
||||
|
||||
SDL_RenderCopy(m_pRenderer, m_pTexture, NULL, &rect);
|
||||
|
||||
SDL_RenderPresent(m_pRenderer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CSDLVideoRender::setWindowSize(QSize size)
|
||||
{
|
||||
reInit(m_hWnd, m_nVideoWidth, m_nVideoHeight, m_nVideoFmt);
|
||||
}
|
||||
|
||||
void CSDLVideoRender::setWindowTitle(const char * title)
|
||||
{
|
||||
if (m_pWindow)
|
||||
{
|
||||
if (title)
|
||||
{
|
||||
SDL_SetWindowTitle(m_pWindow, title);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetWindowTitle(m_pWindow, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user