rtsp: fix SIGSEGV
This commit is contained in:
parent
9db8ba5fa5
commit
43f2817442
@ -135,5 +135,12 @@ extern "C" void camera_status_json(http_worker_t *worker, FILE *stream)
|
||||
message["endpoints"]["stream"] = get_url(stream_lock.buf_list != NULL, "stream", "http", worker->host, http_options.port, "/stream");
|
||||
message["endpoints"]["snapshot"] = get_url(snapshot_lock.buf_list != NULL, "snapshot", "http", worker->host, http_options.port, "/stream");
|
||||
|
||||
if (rtsp_options.running) {
|
||||
message["endpoints"]["rtsp"]["clients"] = rtsp_options.clients;
|
||||
message["endpoints"]["rtsp"]["truncated"] = rtsp_options.truncated;
|
||||
message["endpoints"]["rtsp"]["frames"] = rtsp_options.frames;
|
||||
message["endpoints"]["rtsp"]["dropped"] = rtsp_options.dropped;
|
||||
}
|
||||
|
||||
http_write_response(stream, "200 OK", "application/json", message.dump().c_str(), 0);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ extern "C" {
|
||||
static pthread_t rtsp_thread;
|
||||
static pthread_mutex_t rtsp_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||
static class DynamicH264Stream *rtsp_streams;
|
||||
static rtsp_options_t *rtsp_options;
|
||||
|
||||
static const char *stream_name = "stream.h264";
|
||||
|
||||
@ -31,7 +32,7 @@ class DynamicH264Stream : public FramedSource
|
||||
{
|
||||
public:
|
||||
DynamicH264Stream(UsageEnvironment& env)
|
||||
: FramedSource(env), fHaveStartedReading(False)
|
||||
: FramedSource(env), fHaveStartedReading(False), fFrameWaiting(False)
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,12 +62,16 @@ public:
|
||||
}
|
||||
fHaveStartedReading = False;
|
||||
}
|
||||
fFrameWaiting = False;
|
||||
pthread_mutex_unlock(&rtsp_lock);
|
||||
}
|
||||
|
||||
void receiveData(buffer_t *buf)
|
||||
{
|
||||
if (!isCurrentlyAwaitingData()) {
|
||||
if (!isCurrentlyAwaitingData() || fFrameWaiting) {
|
||||
if (rtsp_options) {
|
||||
rtsp_options->dropped++;
|
||||
}
|
||||
return; // we're not ready for the data yet
|
||||
}
|
||||
|
||||
@ -79,27 +84,42 @@ public:
|
||||
device_video_force_key(buf->buf_list->dev);
|
||||
fRequestedKeyFrame = true;
|
||||
}
|
||||
if (rtsp_options) {
|
||||
rtsp_options->dropped++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
rtsp_options->frames++;
|
||||
|
||||
if (buf->used > fMaxSize) {
|
||||
fNumTruncatedBytes = buf->used - fMaxSize;
|
||||
fFrameSize = fMaxSize;
|
||||
if (rtsp_options) {
|
||||
rtsp_options->truncated++;
|
||||
}
|
||||
} else {
|
||||
fNumTruncatedBytes = 0;
|
||||
fFrameSize = buf->used;
|
||||
}
|
||||
|
||||
memcpy(fTo, buf->start, fFrameSize);
|
||||
fFrameWaiting = true;
|
||||
}
|
||||
|
||||
// Tell our client that we have new data
|
||||
nextTask() = envir().taskScheduler().scheduleDelayedTask(
|
||||
0, (TaskFunc*)FramedSource::afterGetting, this);
|
||||
void doFinishFrameGet()
|
||||
{
|
||||
if (fFrameWaiting) {
|
||||
// Tell our client that we have new data
|
||||
fFrameWaiting = false;
|
||||
afterGetting(this);
|
||||
}
|
||||
}
|
||||
|
||||
Boolean fHaveStartedReading;
|
||||
Boolean fHadKeyFrame;
|
||||
Boolean fRequestedKeyFrame;
|
||||
Boolean fFrameWaiting;
|
||||
|
||||
DynamicH264Stream *pNextStream;
|
||||
};
|
||||
@ -178,10 +198,29 @@ protected: // redefined virtual functions
|
||||
}
|
||||
};
|
||||
|
||||
static void rtsp_frame_finish()
|
||||
{
|
||||
pthread_mutex_lock(&rtsp_lock);
|
||||
int clients = 0;
|
||||
for (DynamicH264Stream *stream = rtsp_streams; stream; stream = stream->pNextStream) {
|
||||
stream->doFinishFrameGet();
|
||||
clients++;
|
||||
}
|
||||
if (rtsp_options) {
|
||||
rtsp_options->clients = clients;
|
||||
}
|
||||
pthread_mutex_unlock(&rtsp_lock);
|
||||
}
|
||||
|
||||
static void *rtsp_server_thread(void *opaque)
|
||||
{
|
||||
UsageEnvironment* env = (UsageEnvironment*)opaque;
|
||||
env->taskScheduler().doEventLoop(); // does not return
|
||||
BasicTaskScheduler0* taskScheduler = (BasicTaskScheduler*)&env->taskScheduler();
|
||||
|
||||
while(true) {
|
||||
rtsp_frame_finish();
|
||||
taskScheduler->SingleStep(0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -208,6 +247,8 @@ static void rtsp_h264_capture(buffer_lock_t *buf_lock, buffer_t *buf)
|
||||
|
||||
extern "C" int rtsp_server(rtsp_options_t *options)
|
||||
{
|
||||
rtsp_options = options;
|
||||
|
||||
// Begin by setting up our usage environment:
|
||||
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
|
||||
UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);
|
||||
|
@ -3,6 +3,10 @@
|
||||
typedef struct rtsp_options_s {
|
||||
bool running;
|
||||
uint port;
|
||||
int clients;
|
||||
int frames;
|
||||
int truncated;
|
||||
int dropped;
|
||||
} rtsp_options_t;
|
||||
|
||||
int rtsp_server(rtsp_options_t *options);
|
||||
|
Loading…
x
Reference in New Issue
Block a user