#include "PL_RTSPClient.h" #include void rtsp_client_sdp_callback(void* arg, const char* val); void rtsp_client_fmtp_callback(void* arg, const char* val); void rtsp_client_frame_callback(void* arg, uint8_t* buffer, size_t buffSize); void rtsp_client_continue_callback(void* arg); #include "RTSPClient.hpp" struct RTSPClient_Internal { PL_RTSPClient* client; RTSPConfig rtspConfig; pthread_t live_daemon_thid; char eventLoopWatchVariable; bool live_daemon_running; pthread_mutex_t* frame_mutex; pthread_mutex_t* continue_mutex; uint8_t* lastBuffer; size_t lastBuffSize; RTSPClient_Internal() : client(nullptr), rtspConfig(), live_daemon_thid(0), eventLoopWatchVariable(0), live_daemon_running(false), frame_mutex(new pthread_mutex_t), continue_mutex(new pthread_mutex_t), lastBuffer(nullptr), lastBuffSize(0) { pthread_mutex_init(frame_mutex, NULL); pthread_mutex_init(continue_mutex, NULL); } ~RTSPClient_Internal() { if (frame_mutex != nullptr) { pthread_mutex_destroy(frame_mutex); delete frame_mutex; } if (continue_mutex != nullptr) { pthread_mutex_destroy(continue_mutex); delete continue_mutex; } } void reset() { client = nullptr; rtspConfig.progName = ""; rtspConfig.rtspURL = ""; live_daemon_thid = 0; eventLoopWatchVariable = 0; live_daemon_running = false; if (frame_mutex != nullptr) { pthread_mutex_destroy(frame_mutex); delete frame_mutex; } frame_mutex = new pthread_mutex_t; pthread_mutex_init(frame_mutex, NULL); if (continue_mutex != nullptr) { pthread_mutex_destroy(continue_mutex); delete continue_mutex; } continue_mutex = new pthread_mutex_t; pthread_mutex_init(continue_mutex, NULL); lastBuffer = nullptr; lastBuffSize = 0; } }; void* live_daemon_thd(void* arg) { RTSPClient_Internal* in = (RTSPClient_Internal*)arg; TaskScheduler* scheduler = BasicTaskScheduler::createNew(); UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); usage(*env, in->rtspConfig.progName.c_str()); openURL(*env, in->client, in->rtspConfig.progName.c_str(), in->rtspConfig.rtspURL.c_str()); in->live_daemon_running = true; env->taskScheduler().doEventLoop(&(in->eventLoopWatchVariable)); in->live_daemon_running = false; } PipeLineElem* create_PL_RTSPClient() { return new PL_RTSPClient; } PL_RTSPClient::PL_RTSPClient() : internal(new RTSPClient_Internal) { } PL_RTSPClient::~PL_RTSPClient() { delete (RTSPClient_Internal*)internal; internal= nullptr; } bool PL_RTSPClient::init(void* args) { if (args == nullptr) return false; const RTSPConfig* config = reinterpret_cast(args); RTSPClient_Internal* in = (RTSPClient_Internal*)internal; in->reset(); in->client = this; in->rtspConfig = *config; int ret = pthread_mutex_lock(in->frame_mutex); if(ret != 0) { printf("pthread_mutex_lock frame_mutex: %s/n", strerror(ret)); return false; } ret = pthread_mutex_lock(in->continue_mutex); if(ret != 0) { printf("pthread_mutex_lock continue_mutex: %s/n", strerror(ret)); return false; } ret = pthread_create(&(in->live_daemon_thid), NULL, live_daemon_thd, in); if(ret != 0) { printf("pthread_create: %s/n", strerror(ret)); return false; } return true; } void PL_RTSPClient::finit() { RTSPClient_Internal* in = (RTSPClient_Internal*)internal; in->eventLoopWatchVariable = 1; pthread_join(in->live_daemon_thid, NULL); } bool PL_RTSPClient::pay(const PipeMaterial& pm) { RTSPClient_Internal* in = (RTSPClient_Internal*)internal; return in->live_daemon_running; } bool PL_RTSPClient::gain(PipeMaterial& pm) { RTSPClient_Internal* in = (RTSPClient_Internal*)internal; int ret = pthread_mutex_unlock(in->continue_mutex); if(ret != 0) { printf("pthread_mutex_unlock continue_mutex: %s/n", strerror(ret)); return false; } ret = pthread_mutex_lock(in->frame_mutex); if(ret != 0) { printf("pthread_mutex_lock: %s/n", strerror(ret)); return false; } pm.buffer = in->lastBuffer; pm.buffSize = in->lastBuffSize; pm.former = this; return true; } void rtsp_client_sdp_callback(void* arg, const char* val) { if (arg == nullptr || val == nullptr) return; PL_RTSPClient* client = (PL_RTSPClient*)arg; if (client->manager == nullptr) return; client->manager->set_global_param(PLGP_RTSP_SDP, val); } void rtsp_client_fmtp_callback(void* arg, const char* val) { if (arg == nullptr || val == nullptr) return; PL_RTSPClient* client = (PL_RTSPClient*)arg; if (client->manager == nullptr) return; client->manager->set_global_param(PLGP_RTSP_FMTP, val); } void rtsp_client_frame_callback(void* arg, uint8_t* buffer, size_t buffSize) { if (arg == nullptr || buffer == nullptr || buffSize == 0) return; PL_RTSPClient* client = (PL_RTSPClient*)arg; RTSPClient_Internal* in = (RTSPClient_Internal*)(client->internal); in->lastBuffer = buffer; in->lastBuffSize = buffSize; int ret = pthread_mutex_unlock(in->frame_mutex); if(ret != 0) { printf("pthread_mutex_unlock frame_mutex: %s/n", strerror(ret)); } } void rtsp_client_continue_callback(void* arg) { if (arg == nullptr) return; PL_RTSPClient* client = (PL_RTSPClient*)arg; RTSPClient_Internal* in = (RTSPClient_Internal*)(client->internal); int ret = pthread_mutex_lock(in->continue_mutex); if(ret != 0) { printf("pthread_mutex_unlock continue_mutex: %s/n", strerror(ret)); } }