mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 02:34:26 +08:00
替换成sdl2
This commit is contained in:
parent
6a9bc8aca5
commit
bd04b2e2ab
15
cmake/FindSDL2.cmake
Normal file
15
cmake/FindSDL2.cmake
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
find_path(SDL2_INCLUDE_DIR
|
||||||
|
NAMES SDL2/SDL.h
|
||||||
|
HINTS SDL2
|
||||||
|
PATHS $ENV{HOME}/sdl2/include)
|
||||||
|
|
||||||
|
find_library(SDL2_LIBRARY
|
||||||
|
NAMES SDL2
|
||||||
|
PATHS $ENV{HOME}/sdl2/lib/x86)
|
||||||
|
|
||||||
|
set(SDL2_LIBRARIES ${SDL2_LIBRARY})
|
||||||
|
set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
find_package_handle_standard_args(SDL2 DEFAULT_MSG SDL2_LIBRARY SDL2_INCLUDE_DIR)
|
@ -1,10 +1,10 @@
|
|||||||
#查找SDL是否安装
|
#查找SDL2是否安装
|
||||||
find_package(SDL QUIET)
|
find_package(SDL2 QUIET)
|
||||||
if(SDL_FOUND)
|
if (SDL2_FOUND)
|
||||||
include_directories(${SDL_INCLUDE_DIR})
|
include_directories(${SDL2_INCLUDE_DIR})
|
||||||
list(APPEND LINK_LIB_LIST ${SDL_LIBRARY})
|
list(APPEND LINK_LIB_LIST ${SDL2_LIBRARY})
|
||||||
message(STATUS " found SDL")
|
message(STATUS "found SDL2:${SDL2_INCLUDE_DIR},${SDL2_LIBRARY}")
|
||||||
endif()
|
endif (SDL2_FOUND)
|
||||||
|
|
||||||
#查找ffmpeg/libutil是否安装
|
#查找ffmpeg/libutil是否安装
|
||||||
find_package(AVUTIL QUIET)
|
find_package(AVUTIL QUIET)
|
||||||
@ -24,10 +24,10 @@ endif()
|
|||||||
|
|
||||||
aux_source_directory(. TEST_SRC_LIST)
|
aux_source_directory(. TEST_SRC_LIST)
|
||||||
#如果ffmpeg/libavcodec ffmpeg/libavcodec SDL 都安装了则编译 test_player
|
#如果ffmpeg/libavcodec ffmpeg/libavcodec SDL 都安装了则编译 test_player
|
||||||
if(SDL_FOUND AND AVCODEC_FOUND AND AVUTIL_FOUND)
|
if(SDL2_FOUND AND AVCODEC_FOUND AND AVUTIL_FOUND)
|
||||||
message(STATUS "test_player will be compiled")
|
message(STATUS "test_player will be compiled")
|
||||||
else()
|
else()
|
||||||
message(STATUS "test_player ingored, please install sdl ffmpeg/libavcodec ffmpeg/libavcodec")
|
message(STATUS "test_player ingored, please install sdl2 ffmpeg/libavcodec ffmpeg/libavutil")
|
||||||
list(REMOVE_ITEM TEST_SRC_LIST ./test_player.cpp)
|
list(REMOVE_ITEM TEST_SRC_LIST ./test_player.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -50,4 +50,3 @@ endforeach()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* MIT License
|
* MIT License
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016 xiongziliang <771730766@qq.com>
|
* Copyright (c) 2017 xiongziliang <771730766@qq.com>
|
||||||
*
|
|
||||||
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -23,7 +21,6 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef YUVDISPLAYER_H_
|
#ifndef YUVDISPLAYER_H_
|
||||||
#define YUVDISPLAYER_H_
|
#define YUVDISPLAYER_H_
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -31,68 +28,176 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include <SDL/SDL.h>
|
#include "SDL2/SDL.h"
|
||||||
#include <libavcodec/avcodec.h>
|
#include "libavcodec/avcodec.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ZL {
|
#if defined(_WIN32)
|
||||||
namespace Screen {
|
#pragma comment(lib,"SDL2.lib")
|
||||||
|
#endif //defined(_WIN32)
|
||||||
|
|
||||||
|
using namespace ZL::Util;
|
||||||
|
|
||||||
|
#define REFRESH_EVENT (SDL_USEREVENT + 1)
|
||||||
|
|
||||||
|
class SDLDisplayerHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static SDLDisplayerHelper &Instance(){
|
||||||
|
static SDLDisplayerHelper *instance(new SDLDisplayerHelper);
|
||||||
|
return *instance;
|
||||||
|
}
|
||||||
|
static void Destory(){
|
||||||
|
delete &Instance();
|
||||||
|
}
|
||||||
|
template<typename FUN>
|
||||||
|
void doTask(FUN &&f){
|
||||||
|
{
|
||||||
|
lock_guard<mutex> lck(_mtxTask);
|
||||||
|
_taskList.emplace_back(f);
|
||||||
|
}
|
||||||
|
SDL_Event event;
|
||||||
|
event.type = REFRESH_EVENT;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDLDisplayerHelper(){
|
||||||
|
_loopThread.reset(new std::thread(&SDLDisplayerHelper::runLoop,this));
|
||||||
|
};
|
||||||
|
~SDLDisplayerHelper(){
|
||||||
|
doTask([](){return false;});
|
||||||
|
_loopThread->join();
|
||||||
|
_loopThread.reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
void runLoop(){
|
||||||
|
bool flag = true;
|
||||||
|
std::function<bool ()> task;
|
||||||
|
SDL_Event event;
|
||||||
|
while(flag){
|
||||||
|
SDL_WaitEvent(&event);
|
||||||
|
if (event.type == REFRESH_EVENT)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
lock_guard<mutex> lck(_mtxTask);
|
||||||
|
if(_taskList.empty()){
|
||||||
|
//not reachable
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
task = _taskList.front();
|
||||||
|
_taskList.pop_front();
|
||||||
|
}
|
||||||
|
flag = task();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::deque<std::function<bool ()> > _taskList;
|
||||||
|
std::shared_ptr<thread> _loopThread;
|
||||||
|
std::mutex _mtxTask;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class YuvDisplayer {
|
class YuvDisplayer {
|
||||||
public:
|
public:
|
||||||
YuvDisplayer(){
|
YuvDisplayer(void *hwnd = nullptr,const char *title = "untitled"){
|
||||||
static onceToken token([]() {
|
|
||||||
if(SDL_Init(SDL_INIT_EVERYTHING) == -1) {
|
static onceToken token([]() {
|
||||||
throw std::runtime_error("初始化SDL失败");
|
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) == -1) {
|
||||||
}
|
string err = "初始化SDL失败:";
|
||||||
}, []() {
|
err+= SDL_GetError();
|
||||||
SDL_Quit();
|
ErrorL << err;
|
||||||
});
|
throw std::runtime_error(err);
|
||||||
|
}
|
||||||
|
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_CRITICAL);
|
||||||
|
SDL_LogSetOutputFunction([](void *userdata, int category, SDL_LogPriority priority, const char *message){
|
||||||
|
DebugL << category << " " << priority << message;
|
||||||
|
},nullptr);
|
||||||
|
InfoL << "SDL_Init";
|
||||||
|
}, []() {
|
||||||
|
SDLDisplayerHelper::Destory();
|
||||||
|
SDL_Quit();
|
||||||
|
InfoL << "SDL_Quit";
|
||||||
|
});
|
||||||
|
|
||||||
|
_title = title;
|
||||||
|
_hwnd = hwnd;
|
||||||
}
|
}
|
||||||
virtual ~YuvDisplayer(){
|
virtual ~YuvDisplayer(){
|
||||||
if(m_pOverlay){
|
if (_texture) {
|
||||||
SDL_FreeYUVOverlay(m_pOverlay);
|
SDL_DestroyTexture(_texture);
|
||||||
|
_texture = nullptr;
|
||||||
|
}
|
||||||
|
if (_render) {
|
||||||
|
SDL_DestroyRenderer(_render);
|
||||||
|
_render = nullptr;
|
||||||
|
}
|
||||||
|
if (_win) {
|
||||||
|
SDL_DestroyWindow(_win);
|
||||||
|
_win = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool displayYUV(AVFrame *pFrame){
|
bool displayYUV(AVFrame *pFrame){
|
||||||
if (!m_pScreen) {
|
if (!_win) {
|
||||||
/* Set up the screen */
|
if (_hwnd) {
|
||||||
m_pScreen = SDL_SetVideoMode(1366, 768, 16, SDL_SWSURFACE);
|
_win = SDL_CreateWindowFrom(_hwnd);
|
||||||
|
}else {
|
||||||
|
_win = SDL_CreateWindow(_title.data(),
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
pFrame->width,
|
||||||
|
pFrame->height,
|
||||||
|
SDL_WINDOW_OPENGL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (_win && ! _render){
|
||||||
if (!m_pOverlay && m_pScreen) {
|
#if 0
|
||||||
/* Create a YUV overlay */
|
SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */
|
||||||
m_pOverlay = SDL_CreateYUVOverlay(pFrame->width, pFrame->height, SDL_YV12_OVERLAY, m_pScreen);
|
SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware
|
||||||
/* Set the window caption */
|
acceleration */
|
||||||
SDL_WM_SetCaption("YUV Window", NULL);
|
SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized
|
||||||
|
with the refresh rate */
|
||||||
|
SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports
|
||||||
|
rendering to texture */
|
||||||
|
#endif
|
||||||
|
#if defined(__linux__)
|
||||||
|
_render = SDL_CreateRenderer(_win, -1, SDL_RENDERER_SOFTWARE);
|
||||||
|
#else
|
||||||
|
_render = SDL_CreateRenderer(_win, -1, SDL_RENDERER_ACCELERATED);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (m_pOverlay) {
|
if (_render && !_texture) {
|
||||||
/* Apply the image to the screen */
|
_texture = SDL_CreateTexture(_render, SDL_PIXELFORMAT_IYUV,
|
||||||
m_pOverlay->pixels[0] = pFrame->data[0];
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
m_pOverlay->pixels[2] = pFrame->data[1];
|
pFrame->width,
|
||||||
m_pOverlay->pixels[1] = pFrame->data[2];
|
pFrame->height);
|
||||||
|
}
|
||||||
|
if (_texture) {
|
||||||
|
SDL_UpdateYUVTexture(_texture, nullptr,
|
||||||
|
pFrame->data[0], pFrame->linesize[0],
|
||||||
|
pFrame->data[1], pFrame->linesize[1],
|
||||||
|
pFrame->data[2], pFrame->linesize[2]);
|
||||||
|
|
||||||
m_pOverlay->pitches[0] = pFrame->linesize[0];
|
//SDL_UpdateTexture(_texture, nullptr, pFrame->data[0], pFrame->linesize[0]);
|
||||||
m_pOverlay->pitches[2] = pFrame->linesize[1];
|
SDL_RenderClear(_render);
|
||||||
m_pOverlay->pitches[1] = pFrame->linesize[2];
|
SDL_RenderCopy(_render, _texture, nullptr, nullptr);
|
||||||
|
SDL_RenderPresent(_render);
|
||||||
/* Update the screen */
|
|
||||||
SDL_Rect rect = { 0 ,0 ,1366,768};
|
|
||||||
SDL_LockYUVOverlay(m_pOverlay);
|
|
||||||
SDL_DisplayYUVOverlay(m_pOverlay, &rect);
|
|
||||||
SDL_UnlockYUVOverlay(m_pOverlay);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SDL_Surface* m_pScreen = nullptr;
|
string _title;
|
||||||
SDL_Overlay* m_pOverlay = nullptr;
|
SDL_Window *_win = nullptr;
|
||||||
|
SDL_Renderer *_render = nullptr;
|
||||||
|
SDL_Texture *_texture = nullptr;
|
||||||
|
void *_hwnd = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace Screen */
|
#endif /* YUVDISPLAYER_H_ */
|
||||||
} /* namespace ZL */
|
|
||||||
|
|
||||||
#endif /* YUVDISPLAYER_H_ */
|
|
@ -36,7 +36,6 @@
|
|||||||
#include "Network/sockutil.h"
|
#include "Network/sockutil.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ZL::Screen;
|
|
||||||
using namespace ZL::Codec;
|
using namespace ZL::Codec;
|
||||||
using namespace ZL::Util;
|
using namespace ZL::Util;
|
||||||
using namespace ZL::Thread;
|
using namespace ZL::Thread;
|
||||||
@ -44,55 +43,55 @@ using namespace ZL::Network;
|
|||||||
using namespace ZL::Rtsp;
|
using namespace ZL::Rtsp;
|
||||||
using namespace ZL::Player;
|
using namespace ZL::Player;
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]) {
|
||||||
//设置退出信号处理函数
|
//设置退出信号处理函数
|
||||||
signal(SIGINT, [](int){EventPoller::Instance().shutdown();});
|
signal(SIGINT, [](int) { EventPoller::Instance().shutdown(); });
|
||||||
//设置日志
|
//设置日志
|
||||||
Logger::Instance().add(std::make_shared<ConsoleChannel>("stdout", LTrace));
|
Logger::Instance().add(std::make_shared<ConsoleChannel>("stdout", LTrace));
|
||||||
Logger::Instance().setWriter(std::make_shared<AsyncLogWriter>());
|
Logger::Instance().setWriter(std::make_shared<AsyncLogWriter>());
|
||||||
|
|
||||||
if(argc != 3){
|
if (argc != 3) {
|
||||||
ErrorL << "\r\n测试方法:./test_player rtxp_url rtp_type\r\n"
|
ErrorL << "\r\n测试方法:./test_player rtxp_url rtp_type\r\n"
|
||||||
<< "例如:./test_player rtsp://admin:123456@127.0.0.1/live/0 0\r\n"
|
<< "例如:./test_player rtsp://admin:123456@127.0.0.1/live/0 0\r\n"
|
||||||
<<endl;
|
<< endl;
|
||||||
Logger::Destory();
|
Logger::Destory();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPlayer::Ptr player(new MediaPlayer());
|
MediaPlayer::Ptr player(new MediaPlayer());
|
||||||
player->setOnPlayResult([](const SockException &ex) {
|
player->setOnPlayResult([](const SockException &ex) {
|
||||||
InfoL << "OnPlayResult:" << ex.what();
|
InfoL << "OnPlayResult:" << ex.what();
|
||||||
});
|
});
|
||||||
player->setOnShutdown([](const SockException &ex) {
|
player->setOnShutdown([](const SockException &ex) {
|
||||||
ErrorL << "OnShutdown:" << ex.what();
|
ErrorL << "OnShutdown:" << ex.what();
|
||||||
});
|
});
|
||||||
(*player)[RtspPlayer::kRtpType] = atoi(argv[2]);
|
(*player)[RtspPlayer::kRtpType] = atoi(argv[2]);
|
||||||
player->play(argv[1]);
|
player->play(argv[1]);
|
||||||
|
|
||||||
H264Decoder decoder;
|
H264Decoder decoder;
|
||||||
YuvDisplayer displayer;
|
YuvDisplayer displayer;
|
||||||
ThreadPool pool(1);
|
player->setOnVideoCB([&](const H264Frame &frame) {
|
||||||
player->setOnVideoCB([&](const H264Frame &frame){
|
SDLDisplayerHelper::Instance().doTask([&, frame]() {
|
||||||
pool.async([&,frame]() {
|
AVFrame *pFrame = nullptr;
|
||||||
AVFrame *pFrame = nullptr;
|
bool flag = decoder.inputVideo((unsigned char *) frame.data.data(), frame.data.size(), frame.timeStamp, &pFrame);
|
||||||
bool flag = decoder.inputVideo((unsigned char *)frame.data.data(), frame.data.size() ,frame.timeStamp, &pFrame);
|
if (flag) {
|
||||||
if(flag) {
|
//DebugL << pFrame->pkt_pts;
|
||||||
//DebugL << pFrame->pkt_pts;
|
displayer.displayYUV(pFrame);
|
||||||
displayer.displayYUV(pFrame);
|
}
|
||||||
}
|
return true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
EventPoller::Instance().runLoop();
|
EventPoller::Instance().runLoop();
|
||||||
|
|
||||||
|
|
||||||
static onceToken token(nullptr, []() {
|
static onceToken token(nullptr, []() {
|
||||||
UDPServer::Destory();
|
UDPServer::Destory();
|
||||||
EventPoller::Destory();
|
EventPoller::Destory();
|
||||||
AsyncTaskThread::Destory();
|
AsyncTaskThread::Destory();
|
||||||
Logger::Destory();
|
Logger::Destory();
|
||||||
});
|
});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user