123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- #include "preheader.h"
- #include "CSdlProc.h"
- extern "C"
- {
- #include <libswscale/swscale.h>
- #include <libavutil/imgutils.h>
- #include <libswresample/swresample.h>
- #include <sdl/SDL_ttf.h>
- #include <sdl/SDL.h>
- };
- #include <sdl/SDL2_gfxPrimitives.h>
- #pragma comment(lib, "SDL2_ttf.LIB")
- #pragma comment(lib, "SDL2_gfx.LIB")
- #pragma comment(lib, "sdl2main.lib")
- #pragma comment(lib, "sdl2.lib")
- bool CSdlProc::m_bUseDispalyArea = false;
- CSdlProc::CSdlProc()
- {
- //初始化字体库
- TTF_Init();
- m_sdlRect = new SDL_Rect;
- if (m_pFont == nullptr)
- {
- std::string fileName = std::string(QCoreApplication::applicationDirPath().toLocal8Bit());
- fileName += "\\font\\msyh.ttc";
- m_pFont = TTF_OpenFont(fileName.c_str(), 40);
- if (!m_pFont)
- {
- return;
- }
- }
- }
- CSdlProc::~CSdlProc()
- {
- if (m_pFont!=nullptr)
- {
- TTF_CloseFont(m_pFont);
- }
- if (m_sdlRect!=nullptr)
- {
- delete m_sdlRect;
- m_sdlRect = nullptr;
- }
- }
- bool CSdlProc::Init(void * pWnd, int nVideoWidth, int nVideoHeight, bool bHard)
- {
- if (m_pFrameYUV != nullptr)
- {
- av_frame_free(&m_pFrameYUV);
- }
- if (m_out_buffer != nullptr)
- {
- av_free(m_out_buffer);
- m_out_buffer = nullptr;
- }
- m_pFrameYUV = av_frame_alloc();
- m_out_buffer = (uint8_t *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, nVideoWidth, nVideoHeight, 1));
- av_image_fill_arrays(m_pFrameYUV->data, m_pFrameYUV->linesize, m_out_buffer, AV_PIX_FMT_YUV420P, nVideoWidth, nVideoHeight, 1);
- if (bHard)
- {
- m_img_convert_ctx = sws_getContext(nVideoWidth, nVideoHeight, /*AV_PIX_FMT_YUV420P*/AV_PIX_FMT_NV12,
- nVideoWidth, nVideoHeight, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
- }
- else
- {
- m_img_convert_ctx = sws_getContext(nVideoWidth, nVideoHeight, AV_PIX_FMT_YUV420P,
- nVideoWidth, nVideoHeight, AV_PIX_FMT_YUV420P, /*SWS_BILINEAR*/SWS_BICUBIC, NULL, NULL, NULL);
- }
- //SDL 2.0 Support for multiple windows
- if (m_screen == nullptr)
- {
- /*m_screen = SDL_CreateWindow("VIDEO Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
- nVideoWidth, nVideoHeight,
- SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);*/
- m_screen = SDL_CreateWindowFrom(pWnd);
- if (m_screen==nullptr)
- {
- return false;
- }
- m_sdlRenderer = SDL_CreateRenderer(m_screen, -1, SDL_RENDERER_SOFTWARE| SDL_RENDERER_PRESENTVSYNC);
- m_sdlTexture = SDL_CreateTexture(m_sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, nVideoWidth, nVideoHeight);
- }
- else
- {
- SDL_RenderClear(m_sdlRenderer);
- SDL_DestroyTexture(m_sdlTexture);
- m_sdlTexture = nullptr;
- SDL_DestroyRenderer(m_sdlRenderer);
- m_sdlRenderer = nullptr;
- m_sdlRenderer = SDL_CreateRenderer(m_screen, -1, SDL_RENDERER_SOFTWARE | SDL_RENDERER_PRESENTVSYNC);
- m_sdlTexture = SDL_CreateTexture(m_sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, nVideoWidth, nVideoHeight);
- }
- SDL_ShowWindow(m_screen);
- return true;
- }
- void CSdlProc::DisplayFrame(AVFrame *pFrame)
- {
- int nRet = 0;
- if (m_img_convert_ctx==nullptr)
- {
- return;
- }
- sws_scale(m_img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pFrame->height,
- m_pFrameYUV->data, m_pFrameYUV->linesize);
- nRet = SDL_UpdateTexture(m_sdlTexture, NULL, m_pFrameYUV->data[0], m_pFrameYUV->linesize[0]);
- //SDL_UpdateTexture(m_sdlTexture, NULL, pFrame->data[0], pFrame->linesize[0]);
- //SDL_UpdateYUVTexture(m_sdlTexture, &m_sdlRect,
- // m_pFrameYUV->data[0], m_pFrameYUV->linesize[0],
- // m_pFrameYUV->data[1], m_pFrameYUV->linesize[1],
- // m_pFrameYUV->data[2], m_pFrameYUV->linesize[2]);
- //OutputDebugPrintf("VideoPlayer SDL_UpdateTexture nRet %d %s", nRet, SDL_GetError());
-
- nRet = SDL_RenderClear(m_sdlRenderer);
- nRet = SDL_RenderCopy(m_sdlRenderer, m_sdlTexture, NULL, m_sdlRect);
-
- if (m_bUseDispalyArea && m_bDisplayArea)
- {
- DisplayChooseArea(m_ptArea);
- }
- if (m_bDisplayRect)
- {
- DisplayChooseAreaRect(m_ptlt, m_ptbr);
- }
- SDL_RenderPresent(m_sdlRenderer);
- }
- void CSdlProc::DisplayFrame(uint8_t* pData, int nWidth, int nHeight)
- {
- int nRet = 0;
- if (m_img_convert_ctx == nullptr)
- {
- return;
- }
- //创建一个AVFrame类似的结构体
- unsigned char** pFrameData = new unsigned char*[4];
- pFrameData[0] = pData;
- pFrameData[1] = pFrameData[0] + nWidth * nHeight;
- pFrameData[2] = pFrameData[1] + nWidth * nHeight / 4;
- int* lineSizeArray = new int[3];
- lineSizeArray[0] = nWidth;
- lineSizeArray[1] = nWidth >> 1;
- lineSizeArray[2] = nWidth >> 1;
- //nRet = sws_scale(m_img_convert_ctx, (const uint8_t* const*)pFrameData, lineSizeArray, 0, nWidth,
- // m_pFrameYUV->data, m_pFrameYUV->linesize);
- memcpy(m_pFrameYUV->data[0], pData/*pFrameData[0]*/, nWidth * nHeight);
- memcpy(m_pFrameYUV->data[1], pData + nWidth*nHeight /*pFrameData[1]*/, nWidth * nHeight / 4);
- memcpy(m_pFrameYUV->data[2], pData + nWidth * nHeight*5/4, nWidth * nHeight / 4);
- memcpy(m_pFrameYUV->linesize, lineSizeArray, sizeof(int) * 3);
- nRet = SDL_UpdateTexture(m_sdlTexture, NULL, m_pFrameYUV->data[0], m_pFrameYUV->linesize[0]);
- //SDL_UpdateTexture(m_sdlTexture, NULL, pFrame->data[0], pFrame->linesize[0]);
- //SDL_UpdateYUVTexture(m_sdlTexture, &m_sdlRect,
- // m_pFrameYUV->data[0], m_pFrameYUV->linesize[0],
- // m_pFrameYUV->data[1], m_pFrameYUV->linesize[1],
- // m_pFrameYUV->data[2], m_pFrameYUV->linesize[2]);
- //OutputDebugPrintf("VideoPlayer SDL_UpdateTexture nRet %d %s", nRet, SDL_GetError());
- nRet = SDL_RenderClear(m_sdlRenderer);
- nRet = SDL_RenderCopy(m_sdlRenderer, m_sdlTexture, NULL, m_sdlRect);
- if (m_bUseDispalyArea && m_bDisplayArea)
- {
- DisplayChooseArea(m_ptArea);
- }
- if (m_bDisplayRect)
- {
- DisplayChooseAreaRect(m_ptlt, m_ptbr);
- }
- SDL_RenderPresent(m_sdlRenderer);
- }
- void CSdlProc::SetRect(int nOffset_x, int nOffset_y, int nWidth, int nHeight)
- {
- m_sdlRect->x = nOffset_x;
- m_sdlRect->y = nOffset_y;
- m_sdlRect->w = nWidth;
- m_sdlRect->h = nHeight;
- }
- void CSdlProc::Destroy()
- {
- if (m_pFrameYUV!=nullptr)
- {
- av_frame_free(&m_pFrameYUV);
- }
- if (m_out_buffer != nullptr)
- {
- av_free(m_out_buffer);
- m_out_buffer = nullptr;
- }
-
- SDL_RenderClear(m_sdlRenderer);
- SDL_DestroyTexture(m_sdlTexture);
- m_sdlTexture = nullptr;
- SDL_DestroyRenderer(m_sdlRenderer);
- m_sdlRenderer = nullptr;
- SDL_DestroyWindow(m_screen);
- m_screen = nullptr;
- }
- void CSdlProc::SetUseDispalyArea(bool bUseDispalyArea)
- {
- m_bUseDispalyArea = bUseDispalyArea;
- }
- void CSdlProc::DisplayReconn()
- {
- SDL_RenderClear(m_sdlRenderer);
- TTF_SetFontStyle(m_pFont, TTF_STYLE_NORMAL /*TTF_STYLE_ITALIC | TTF_STYLE_BOLD*/);
- //创建文本表面
- SDL_Color color2 = { 255,255,255,255 };
- SDL_Surface *pTextSurface = NULL;//文本表面
- SDL_Texture *pTextTexture = NULL;//文本纹理
- SDL_Rect sdlRectFont = { m_sdlRect->w / 2 - 200, m_sdlRect->h / 2 - TTF_FontHeight(m_pFont) / 2, 400/*m_sdlRect->w*/, TTF_FontHeight(m_pFont) };
- pTextSurface = TTF_RenderUTF8_Solid(m_pFont, u8"网络异常,请检查设备网络连接,设备重连中......", color2);
- //创建文本纹理
- pTextTexture = SDL_CreateTextureFromSurface(m_sdlRenderer, pTextSurface);
-
- SDL_RenderCopy(m_sdlRenderer, pTextTexture, NULL, &sdlRectFont);
- SDL_FreeSurface(pTextSurface); //释放写有文字的surface
- SDL_DestroyTexture(pTextTexture);
- SDL_SetRenderDrawColor(m_sdlRenderer,70, 97, 146,128);
- SDL_RenderPresent(m_sdlRenderer);
- }
- void CSdlProc::DisplayChooseArea(const QPoint & pt)
- {
- const int nWidthIn = 80 / 2;
- const int nHieghtIn = 80 / 2;
- const int nWidthOut = m_sdlRect->w / 2;
- const int nHeightOut = m_sdlRect->h / 2;
- const int nLengthLine = 100 / 2;
- const int nWidthInner = 3;
- const int nWidthOuter = 3;
- //外圈4个角线
- thickLineRGBA(m_sdlRenderer, pt.x() - nWidthOut / 2, pt.y() - nHeightOut / 2,
- pt.x() - nWidthOut / 2, pt.y() - nHeightOut / 2 + nLengthLine, 2, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() - nWidthOut / 2, pt.y() - nHeightOut / 2,
- pt.x() - nWidthOut / 2 + nLengthLine, pt.y() - nHeightOut / 2, 2, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() + nWidthOut / 2, pt.y() + nHeightOut / 2,
- pt.x() + nWidthOut / 2, pt.y() + nHeightOut / 2 - nLengthLine, 2, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() + nWidthOut / 2, pt.y() + nHeightOut / 2,
- pt.x() + nWidthOut / 2 - nLengthLine, pt.y() + nHeightOut / 2, 2, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() - nWidthOut / 2, pt.y() + nHeightOut / 2,
- pt.x() - nWidthOut / 2, pt.y() + nHeightOut / 2 - nLengthLine, 2, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() - nWidthOut / 2, pt.y() + nHeightOut / 2,
- pt.x() - nWidthOut / 2 + nLengthLine, pt.y() + nHeightOut / 2, 2, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() + nWidthOut / 2, pt.y() - nHeightOut / 2,
- pt.x() + nWidthOut / 2, pt.y() - nHeightOut / 2 + nLengthLine, 2, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() + nWidthOut / 2, pt.y() - nHeightOut / 2,
- pt.x() + nWidthOut / 2 - nLengthLine, pt.y() - nHeightOut / 2, 2, 255, 255, 255, 128);
- /*SDL_Rect rectIn = { pt.x() - nWidthIn / 2, pt.y() - nHieghtIn / 2, nWidthIn, nHieghtIn };
- rectangleRGBA(m_sdlRenderer, pt.x() - nWidthIn / 2, pt.y() - nHieghtIn / 2, pt.x() + nWidthIn / 2, pt.y() + nHieghtIn / 2, 255, 255, 255, 255);*/
- //打开字体
- if (m_pFont != nullptr)
- {
- TTF_SetFontStyle(m_pFont, TTF_STYLE_ITALIC | TTF_STYLE_BOLD);
- //创建文本表面
- SDL_Color color2 = { 255,255,255,128 };
- SDL_Surface *pTextSurface = NULL;//文本表面
- SDL_Texture *pTextTexture = NULL;//文本纹理
- pTextSurface = TTF_RenderUTF8_Solid(m_pFont, m_strText.c_str(), color2);
- //创建文本纹理
- pTextTexture = SDL_CreateTextureFromSurface(m_sdlRenderer, pTextSurface);
- SDL_Rect sdlRectFont = { pt.x() + nWidthOut / 4, pt.y() - 20, 60, TTF_FontHeight(m_pFont) };
- SDL_RenderCopy(m_sdlRenderer, pTextTexture, NULL, &sdlRectFont);
- SDL_FreeSurface(pTextSurface); //释放写有文字的surface
- SDL_DestroyTexture(pTextTexture);
- //内圈矩形
- thickLineRGBA(m_sdlRenderer, pt.x() - nWidthIn / 2, pt.y() - nHieghtIn / 2,
- pt.x() + nWidthIn / 2, pt.y() - nHieghtIn / 2, nWidthInner, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() + nWidthIn / 2, pt.y() - nHieghtIn / 2,
- pt.x() + nWidthIn / 2, pt.y() + nHieghtIn / 2, nWidthInner, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() + nWidthIn / 2, pt.y() + nHieghtIn / 2,
- pt.x() - nWidthIn / 2, pt.y() + nHieghtIn / 2, nWidthInner, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, pt.x() - nWidthIn / 2, pt.y() + nHieghtIn / 2,
- pt.x() - nWidthIn / 2, pt.y() - nHieghtIn / 2, nWidthInner, 255, 255, 255, 128);
- }
- }
- void CSdlProc::DisplayChooseAreaRect(const QPoint & ptlt, const QPoint & ptbr)
- {
- thickLineRGBA(m_sdlRenderer, ptlt.x() , ptlt.y(), ptlt.x(), ptbr.y(), 3, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, ptlt.x(), ptlt.y(), ptbr.x(), ptlt.y(), 3, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, ptbr.x(), ptlt.y(), ptbr.x(), ptbr.y(), 3, 255, 255, 255, 128);
- thickLineRGBA(m_sdlRenderer, ptlt.x(), ptbr.y(), ptbr.x(), ptbr.y(), 3, 255, 255, 255, 128);
- }
|