2024-03-16 22:56:32 +08:00
|
|
|
|
#pragma once
|
2024-04-13 20:35:59 +08:00
|
|
|
|
#if defined(ENABLE_VIDEOSTACK) && defined(ENABLE_X264) && defined(ENABLE_FFMPEG)
|
2024-03-16 22:56:32 +08:00
|
|
|
|
#include "Codec/Transcode.h"
|
|
|
|
|
#include "Common/Device.h"
|
|
|
|
|
#include "Player/MediaPlayer.h"
|
|
|
|
|
#include "json/json.h"
|
|
|
|
|
#include <mutex>
|
2024-06-19 14:06:02 +08:00
|
|
|
|
template<typename T> class RefWrapper {
|
|
|
|
|
public:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
using Ptr = std::shared_ptr<RefWrapper<T>>;
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
template<typename... Args>
|
|
|
|
|
explicit RefWrapper(Args&&... args) : _rc(0), _entity(std::forward<Args>(args)...) {}
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
T acquire() {
|
2024-03-16 22:56:32 +08:00
|
|
|
|
++_rc;
|
|
|
|
|
return _entity;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool dispose() { return --_rc <= 0; }
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
private:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
std::atomic<int> _rc;
|
2024-06-19 14:06:02 +08:00
|
|
|
|
T _entity;
|
2024-03-16 22:56:32 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class Channel;
|
|
|
|
|
|
|
|
|
|
struct Param {
|
|
|
|
|
using Ptr = std::shared_ptr<Param>;
|
|
|
|
|
|
|
|
|
|
int posX = 0;
|
|
|
|
|
int posY = 0;
|
|
|
|
|
int width = 0;
|
|
|
|
|
int height = 0;
|
|
|
|
|
AVPixelFormat pixfmt = AV_PIX_FMT_YUV420P;
|
2024-06-19 14:06:02 +08:00
|
|
|
|
std::string id{};
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
|
|
|
|
// runtime
|
|
|
|
|
std::weak_ptr<Channel> weak_chn;
|
|
|
|
|
std::weak_ptr<mediakit::FFmpegFrame> weak_buf;
|
|
|
|
|
|
|
|
|
|
~Param();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using Params = std::shared_ptr<std::vector<Param::Ptr>>;
|
|
|
|
|
|
|
|
|
|
class Channel : public std::enable_shared_from_this<Channel> {
|
2024-06-19 14:06:02 +08:00
|
|
|
|
public:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
using Ptr = std::shared_ptr<Channel>;
|
|
|
|
|
|
|
|
|
|
Channel(const std::string& id, int width, int height, AVPixelFormat pixfmt);
|
|
|
|
|
|
|
|
|
|
void addParam(const std::weak_ptr<Param>& p);
|
|
|
|
|
|
|
|
|
|
void onFrame(const mediakit::FFmpegFrame::Ptr& frame);
|
|
|
|
|
|
|
|
|
|
void fillBuffer(const Param::Ptr& p);
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
protected:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
void forEachParam(const std::function<void(const Param::Ptr&)>& func);
|
|
|
|
|
|
|
|
|
|
void copyData(const mediakit::FFmpegFrame::Ptr& buf, const Param::Ptr& p);
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
private:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
std::string _id;
|
|
|
|
|
int _width;
|
|
|
|
|
int _height;
|
|
|
|
|
AVPixelFormat _pixfmt;
|
|
|
|
|
|
|
|
|
|
mediakit::FFmpegFrame::Ptr _tmp;
|
|
|
|
|
|
|
|
|
|
std::recursive_mutex _mx;
|
|
|
|
|
std::vector<std::weak_ptr<Param>> _params;
|
|
|
|
|
|
|
|
|
|
mediakit::FFmpegSws::Ptr _sws;
|
2024-03-23 20:47:38 +08:00
|
|
|
|
toolkit::EventPoller::Ptr _poller;
|
2024-03-16 22:56:32 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class StackPlayer : public std::enable_shared_from_this<StackPlayer> {
|
2024-06-19 14:06:02 +08:00
|
|
|
|
public:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
using Ptr = std::shared_ptr<StackPlayer>;
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
StackPlayer(const std::string& url) : _url(url) {}
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
|
|
|
|
void addChannel(const std::weak_ptr<Channel>& chn);
|
|
|
|
|
|
|
|
|
|
void play();
|
|
|
|
|
|
|
|
|
|
void onFrame(const mediakit::FFmpegFrame::Ptr& frame);
|
|
|
|
|
|
|
|
|
|
void onDisconnect();
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
protected:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
void rePlay(const std::string& url);
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
private:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
std::string _url;
|
|
|
|
|
mediakit::MediaPlayer::Ptr _player;
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
// 用于断线重连
|
2024-03-16 22:56:32 +08:00
|
|
|
|
toolkit::Timer::Ptr _timer;
|
|
|
|
|
int _failedCount = 0;
|
|
|
|
|
|
|
|
|
|
std::recursive_mutex _mx;
|
|
|
|
|
std::vector<std::weak_ptr<Channel>> _channels;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class VideoStack {
|
2024-06-19 14:06:02 +08:00
|
|
|
|
public:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
using Ptr = std::shared_ptr<VideoStack>;
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
VideoStack(const std::string& url, int width = 1920, int height = 1080,
|
|
|
|
|
AVPixelFormat pixfmt = AV_PIX_FMT_YUV420P, float fps = 25.0,
|
|
|
|
|
int bitRate = 2 * 1024 * 1024);
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
|
|
|
|
~VideoStack();
|
|
|
|
|
|
|
|
|
|
void setParam(const Params& params);
|
|
|
|
|
|
|
|
|
|
void start();
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
protected:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
void initBgColor();
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
public:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
Params _params;
|
|
|
|
|
|
|
|
|
|
mediakit::FFmpegFrame::Ptr _buffer;
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
private:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
std::string _id;
|
|
|
|
|
int _width;
|
|
|
|
|
int _height;
|
|
|
|
|
AVPixelFormat _pixfmt;
|
|
|
|
|
float _fps;
|
|
|
|
|
int _bitRate;
|
|
|
|
|
|
|
|
|
|
mediakit::DevChannel::Ptr _dev;
|
|
|
|
|
|
|
|
|
|
bool _isExit;
|
|
|
|
|
|
|
|
|
|
std::thread _thread;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class VideoStackManager {
|
2024-06-19 14:06:02 +08:00
|
|
|
|
public:
|
|
|
|
|
// 创建拼接流
|
|
|
|
|
int startVideoStack(const Json::Value& json);
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
// 停止拼接流
|
|
|
|
|
int stopVideoStack(const std::string& id);
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
// 可以在不断流的情况下,修改拼接流的配置(实现切换拼接屏内容)
|
|
|
|
|
int resetVideoStack(const Json::Value& json);
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
public:
|
|
|
|
|
static VideoStackManager& Instance();
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
Channel::Ptr getChannel(const std::string& id, int width, int height, AVPixelFormat pixfmt);
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
void unrefChannel(const std::string& id, int width, int height, AVPixelFormat pixfmt);
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
|
|
|
|
bool loadBgImg(const std::string& path);
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
void clear();
|
|
|
|
|
|
2024-03-16 22:56:32 +08:00
|
|
|
|
mediakit::FFmpegFrame::Ptr getBgImg();
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
protected:
|
|
|
|
|
Params parseParams(const Json::Value& json, std::string& id, int& width, int& height);
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
protected:
|
|
|
|
|
Channel::Ptr createChannel(const std::string& id, int width, int height, AVPixelFormat pixfmt);
|
2024-03-16 22:56:32 +08:00
|
|
|
|
|
|
|
|
|
StackPlayer::Ptr createPlayer(const std::string& id);
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
private:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
mediakit::FFmpegFrame::Ptr _bgImg;
|
|
|
|
|
|
2024-06-19 14:06:02 +08:00
|
|
|
|
private:
|
2024-03-16 22:56:32 +08:00
|
|
|
|
std::recursive_mutex _mx;
|
|
|
|
|
|
|
|
|
|
std::unordered_map<std::string, VideoStack::Ptr> _stackMap;
|
|
|
|
|
|
|
|
|
|
std::unordered_map<std::string, RefWrapper<Channel::Ptr>::Ptr> _channelMap;
|
2024-06-19 14:06:02 +08:00
|
|
|
|
|
2024-03-16 22:56:32 +08:00
|
|
|
|
std::unordered_map<std::string, RefWrapper<StackPlayer::Ptr>::Ptr> _playerMap;
|
|
|
|
|
};
|
|
|
|
|
#endif
|