140 lines
2.9 KiB
C++
140 lines
2.9 KiB
C++
#include "RtspPusher.h"
|
|
#include "RtspConnection.h"
|
|
#include "Logger.h"
|
|
#include "TcpSocket.h"
|
|
#include "Timestamp.h"
|
|
#include <memory>
|
|
|
|
using namespace xop;
|
|
|
|
RtspPusher::RtspPusher(xop::EventLoop *event_loop)
|
|
: event_loop_(event_loop)
|
|
{
|
|
|
|
}
|
|
|
|
RtspPusher::~RtspPusher()
|
|
{
|
|
this->Close();
|
|
}
|
|
|
|
std::shared_ptr<RtspPusher> RtspPusher::Create(xop::EventLoop* loop)
|
|
{
|
|
std::shared_ptr<RtspPusher> pusher(new RtspPusher(loop));
|
|
return pusher;
|
|
}
|
|
|
|
void RtspPusher::AddSession(MediaSession* session)
|
|
{
|
|
std::lock_guard<std::mutex> locker(mutex_);
|
|
media_session_.reset(session);
|
|
}
|
|
|
|
void RtspPusher::RemoveSession(MediaSessionId sessionId)
|
|
{
|
|
std::lock_guard<std::mutex> locker(mutex_);
|
|
media_session_ = nullptr;
|
|
}
|
|
|
|
MediaSession::Ptr RtspPusher::LookMediaSession(MediaSessionId session_id)
|
|
{
|
|
return media_session_;
|
|
}
|
|
|
|
int RtspPusher::OpenUrl(std::string url, int msec)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
static xop::Timestamp timestamp;
|
|
int timeout = msec;
|
|
if (timeout <= 0) {
|
|
timeout = 10000;
|
|
}
|
|
|
|
timestamp.Reset();
|
|
|
|
if (!this->ParseRtspUrl(url)) {
|
|
LOG_ERROR("rtsp url(%s) was illegal.\n", url.c_str());
|
|
return -1;
|
|
}
|
|
|
|
if (rtsp_conn_ != nullptr) {
|
|
std::shared_ptr<RtspConnection> rtspConn = rtsp_conn_;
|
|
SOCKET sockfd = rtspConn->GetSocket();
|
|
task_scheduler_->AddTriggerEvent([sockfd, rtspConn]() {
|
|
rtspConn->Disconnect();
|
|
});
|
|
rtsp_conn_ = nullptr;
|
|
}
|
|
|
|
TcpSocket tcpSocket;
|
|
tcpSocket.Create();
|
|
if (!tcpSocket.Connect(rtsp_url_info_.ip, rtsp_url_info_.port, timeout))
|
|
{
|
|
tcpSocket.Close();
|
|
return -1;
|
|
}
|
|
|
|
task_scheduler_ = event_loop_->GetTaskScheduler().get();
|
|
rtsp_conn_.reset(new RtspConnection(shared_from_this(), task_scheduler_, tcpSocket.GetSocket()));
|
|
event_loop_->AddTriggerEvent([this]() {
|
|
rtsp_conn_->SendOptions(RtspConnection::RTSP_PUSHER);
|
|
});
|
|
|
|
timeout -= (int)timestamp.Elapsed();
|
|
if (timeout < 0) {
|
|
timeout = 1000;
|
|
}
|
|
|
|
do
|
|
{
|
|
xop::Timer::Sleep(100);
|
|
timeout -= 100;
|
|
} while (!rtsp_conn_->IsRecord() && timeout > 0);
|
|
|
|
if (!rtsp_conn_->IsRecord()) {
|
|
std::shared_ptr<RtspConnection> rtspConn = rtsp_conn_;
|
|
SOCKET sockfd = rtspConn->GetSocket();
|
|
task_scheduler_->AddTriggerEvent([sockfd, rtspConn]() {
|
|
rtspConn->Disconnect();
|
|
});
|
|
rtsp_conn_ = nullptr;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void RtspPusher::Close()
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
if (rtsp_conn_ != nullptr) {
|
|
std::shared_ptr<RtspConnection> rtsp_conn = rtsp_conn_;
|
|
SOCKET sockfd = rtsp_conn->GetSocket();
|
|
task_scheduler_->AddTriggerEvent([sockfd, rtsp_conn]() {
|
|
rtsp_conn->Disconnect();
|
|
});
|
|
rtsp_conn_ = nullptr;
|
|
}
|
|
}
|
|
|
|
bool RtspPusher::IsConnected()
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
if (rtsp_conn_ != nullptr) {
|
|
return (!rtsp_conn_->IsClosed());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool RtspPusher::PushFrame(MediaChannelId channelId, AVFrame frame)
|
|
{
|
|
std::lock_guard<std::mutex> locker(mutex_);
|
|
if (!media_session_ || !rtsp_conn_) {
|
|
return false;
|
|
}
|
|
|
|
return media_session_->HandleFrame(channelId, frame);
|
|
} |