Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/media.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,12 @@ int media_mjpeg_enable(void) {

if (ret = create_channel(index, app_config.mjpeg_width,
app_config.mjpeg_height, app_config.mjpeg_fps, 1))
{
/* nothing was created yet, so only the slot needs releasing */
chnState[index].enable = false;
HAL_ERROR("media", "Creating channel %d failed with %#x!\n%s\n",
index, ret, errstr(ret));
}

{
hal_vidconfig config;
Expand Down Expand Up @@ -582,13 +586,27 @@ int media_mjpeg_enable(void) {
}

if (ret)
{
/* The channel was created; release it before clearing the slot.
* media_*_disable() skips slots whose enable is already clear, so
* dropping the flag first would strand the channel in the HAL and
* still let take_next_free_channel() hand the index out again. */
media_video_disable(index, 1);
chnState[index].enable = false;
HAL_ERROR("media", "Creating encoder %d failed with %#x!\n%s\n",
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
index, ret, errstr(ret));
}
}

if (ret = bind_channel(index, app_config.mjpeg_fps, 1))
{
/* channel and encoder exist and nothing is bound, so drop the encoder
* (the teardown order in media_*_disable) before releasing the slot */
media_video_disable(index, 1);
chnState[index].enable = false;
HAL_ERROR("media", "Binding channel %d failed with %#x!\n%s\n",
index, ret, errstr(ret));
}

return EXIT_SUCCESS;
}
Expand Down Expand Up @@ -620,8 +638,12 @@ int media_mp4_enable(void) {

if (ret = create_channel(index, app_config.mp4_width,
app_config.mp4_height, app_config.mp4_fps, 0))
{
/* nothing was created yet, so only the slot needs releasing */
chnState[index].enable = false;
HAL_ERROR("media", "Creating channel %d failed with %#x!\n%s\n",
index, ret, errstr(ret));
}

{
hal_vidconfig config;
Expand Down Expand Up @@ -657,17 +679,31 @@ int media_mp4_enable(void) {
}

if (ret)
{
/* The channel was created; release it before clearing the slot.
* media_*_disable() skips slots whose enable is already clear, so
* dropping the flag first would strand the channel in the HAL and
* still let take_next_free_channel() hand the index out again. */
media_video_disable(index, 0);
chnState[index].enable = false;
HAL_ERROR("media", "Creating encoder %d failed with %#x!\n%s\n",
index, ret, errstr(ret));
}

mp4_set_config(app_config.mp4_width, app_config.mp4_height, app_config.mp4_fps,
app_config.audio_enable ? HAL_AUDCODEC_MP3 : HAL_AUDCODEC_UNSPEC,
app_config.audio_bitrate, 1, app_config.audio_srate);
}

if (ret = bind_channel(index, app_config.mp4_fps, 0))
{
/* channel and encoder exist and nothing is bound, so drop the encoder
* (the teardown order in media_*_disable) before releasing the slot */
media_video_disable(index, 0);
chnState[index].enable = false;
HAL_ERROR("media", "Binding channel %d failed with %#x!\n%s\n",
index, ret, errstr(ret));
}

return EXIT_SUCCESS;
}
Expand Down
4 changes: 4 additions & 0 deletions src/rtsp/rtcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ static inline int __rtcp_send_sr(struct connection_item_t *con, int track_id)
return FAILURE);
t = &con->trans[track_id];

/* A track that was never SETUP has no transport, and its fd is 0 - stdin.
* Checked after the bounds assertion so an invalid id cannot index first. */
if (!t->server_port_rtp && !t->is_tcp) return SUCCESS;

ASSERT(gettimeofday(&tv,NULL) == 0, return FAILURE);

ts_h = (unsigned int)tv.tv_sec + 2208988800U;
Expand Down
38 changes: 27 additions & 11 deletions src/server.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <errno.h>
#include "server.h"

#define HTTP_MAX_CLIENTS 50
Expand Down Expand Up @@ -218,6 +219,22 @@ void send_h26x_to_client(char index, hal_vidstream *stream) {
}
}

/* Accept a query value only when it is a complete number inside the range the
* config loader enforces. audio_bitrate and audio_srate are unsigned, so a
* negative value would wrap rather than be rejected, and strtol() alone
* accepts trailing text and saturates on overflow. */
static int query_ranged(const char *value, long min, long max, long *out) {
char *remain;
long result;
errno = 0;
result = strtol(value, &remain, 10);
if (remain == value || (remain && *remain) || errno == ERANGE ||
result < min || result > max)
return 0;
*out = result;
return 1;
}

void send_mp4_to_client(char index, hal_vidstream *stream, char isH265) {
for (unsigned int i = 0; i < stream->count; ++i) {
hal_vidpack *pack = &stream->pack[i];
Expand Down Expand Up @@ -865,30 +882,29 @@ void respond_request(http_request_t *req) {

if (EQUALS(req->uri, "/api/audio")) {
if (req->query) {
char *remain;
while (req->query) {
char *value = split(&req->query, "&");
if (!value || !*value) continue;
unescape_uri(value);
char *key = split(&value, "=");
if (!key || !*key || !value || !*value) continue;
if (EQUALS(key, "bitrate")) {
short result = strtol(value, &remain, 10);
if (remain != value)
app_config.audio_bitrate = result;
long result;
if (query_ranged(value, 32, 320, &result))
app_config.audio_bitrate = (unsigned int)result;
} else if (EQUALS(key, "enable")) {
if (EQUALS_CASE(value, "true") || EQUALS(value, "1"))
app_config.audio_enable = 1;
else if (EQUALS_CASE(value, "false") || EQUALS(value, "0"))
app_config.audio_enable = 0;
} else if (EQUALS(key, "gain")) {
short result = strtol(value, &remain, 10);
if (remain != value)
app_config.audio_gain = result;
long result;
if (query_ranged(value, -60, 30, &result))
app_config.audio_gain = (int)result;
} else if (EQUALS(key, "srate")) {
short result = strtol(value, &remain, 10);
if (remain != value)
app_config.audio_srate = result;
long result;
if (query_ranged(value, 8000, 96000, &result))
app_config.audio_srate = (unsigned int)result;
}
}

Expand Down Expand Up @@ -1265,7 +1281,7 @@ void respond_request(http_request_t *req) {
}
if (EQUALS(req->method, "POST")) {
char *type = request_header("Content-Type");
if (STARTS_WITH(type, "multipart/form-data")) {
if (type && STARTS_WITH(type, "multipart/form-data")) {
char *bound = strstr(type, "boundary=") + strlen("boundary=");

char *payloadb = strstr(req->payload, bound);
Expand Down