|
|
|
|
@@ -48,6 +48,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool _http_get_param_true(struct evkeyvalq *params, const char *key);
|
|
|
|
|
static char *_http_get_param_uri(struct evkeyvalq *params, const char *key);
|
|
|
|
|
|
|
|
|
|
static void _http_callback_root(struct evhttp_request *request, void *arg);
|
|
|
|
|
static void _http_callback_ping(struct evhttp_request *request, void *v_server);
|
|
|
|
|
@@ -157,6 +158,15 @@ static bool _http_get_param_true(struct evkeyvalq *params, const char *key) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *_http_get_param_uri(struct evkeyvalq *params, const char *key) {
|
|
|
|
|
const char *value_str;
|
|
|
|
|
|
|
|
|
|
if ((value_str = evhttp_find_header(params, key)) != NULL) {
|
|
|
|
|
return evhttp_encode_uri(value_str);
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define ADD_HEADER(_key, _value) \
|
|
|
|
|
assert(!evhttp_add_header(evhttp_request_get_output_headers(request), _key, _value))
|
|
|
|
|
|
|
|
|
|
@@ -219,7 +229,7 @@ static void _http_callback_ping(struct evhttp_request *request, void *v_server)
|
|
|
|
|
static void _http_callback_snapshot(struct evhttp_request *request, void *v_server) {
|
|
|
|
|
struct http_server_t *server = (struct http_server_t *)v_server;
|
|
|
|
|
struct evbuffer *buf;
|
|
|
|
|
char time_buf[64];
|
|
|
|
|
char header_buf[64];
|
|
|
|
|
|
|
|
|
|
PROCESS_HEAD_REQUEST;
|
|
|
|
|
|
|
|
|
|
@@ -234,11 +244,16 @@ static void _http_callback_snapshot(struct evhttp_request *request, void *v_serv
|
|
|
|
|
ADD_HEADER("Expires", "Mon, 3 Jan 2000 12:34:56 GMT");
|
|
|
|
|
|
|
|
|
|
# define ADD_TIME_HEADER(_key, _value) \
|
|
|
|
|
{ sprintf(time_buf, "%.06Lf", _value); ADD_HEADER(_key, time_buf); }
|
|
|
|
|
{ sprintf(header_buf, "%.06Lf", _value); ADD_HEADER(_key, header_buf); }
|
|
|
|
|
|
|
|
|
|
# define ADD_UNSIGNED_HEADER(_key, _value) \
|
|
|
|
|
{ sprintf(header_buf, "%u", _value); ADD_HEADER(_key, header_buf); }
|
|
|
|
|
|
|
|
|
|
ADD_TIME_HEADER("X-Timestamp", get_now_real());
|
|
|
|
|
|
|
|
|
|
ADD_HEADER("X-UStreamer-Online", bool_to_string(EXPOSED(online)));
|
|
|
|
|
ADD_UNSIGNED_HEADER("X-UStreamer-Width", EXPOSED(width));
|
|
|
|
|
ADD_UNSIGNED_HEADER("X-UStreamer-Height", EXPOSED(height));
|
|
|
|
|
ADD_TIME_HEADER("X-UStreamer-Grab-Time", EXPOSED(picture.grab_time));
|
|
|
|
|
ADD_TIME_HEADER("X-UStreamer-Encode-Begin-Time", EXPOSED(picture.encode_begin_time));
|
|
|
|
|
ADD_TIME_HEADER("X-UStreamer-Encode-End-Time", EXPOSED(picture.encode_end_time));
|
|
|
|
|
@@ -247,6 +262,7 @@ static void _http_callback_snapshot(struct evhttp_request *request, void *v_serv
|
|
|
|
|
ADD_TIME_HEADER("X-UStreamer-Expose-End-Time", EXPOSED(expose_end_time));
|
|
|
|
|
ADD_TIME_HEADER("X-UStreamer-Send-Time", get_now_monotonic());
|
|
|
|
|
|
|
|
|
|
# undef ADD_UNSUGNED_HEADER
|
|
|
|
|
# undef ADD_TIME_HEADER
|
|
|
|
|
|
|
|
|
|
ADD_HEADER("Content-Type", "image/jpeg");
|
|
|
|
|
@@ -286,6 +302,7 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server
|
|
|
|
|
client->need_first_frame = true;
|
|
|
|
|
|
|
|
|
|
evhttp_parse_query(evhttp_request_get_uri(request), ¶ms);
|
|
|
|
|
client->key = _http_get_param_uri(¶ms, "key");
|
|
|
|
|
client->extra_headers = _http_get_param_true(¶ms, "extra_headers");
|
|
|
|
|
client->advance_headers = _http_get_param_true(¶ms, "advance_headers");
|
|
|
|
|
client->dual_final_frames = _http_get_param_true(¶ms, "dual_final_frames");
|
|
|
|
|
@@ -375,10 +392,11 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
|
|
|
|
"Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0" RN
|
|
|
|
|
"Pragma: no-cache" RN
|
|
|
|
|
"Expires: Mon, 3 Jan 2000 12:34:56 GMT" RN
|
|
|
|
|
"Set-Cookie: stream_client_id=%s; path=/; max-age=30" RN
|
|
|
|
|
"Set-Cookie: stream_client_key=%s; stream_client_id=%s; path=/; max-age=30" RN
|
|
|
|
|
"Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY RN
|
|
|
|
|
RN
|
|
|
|
|
"--" BOUNDARY RN,
|
|
|
|
|
(client->key != NULL ? client->key : "0"),
|
|
|
|
|
client->id
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
@@ -404,6 +422,8 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
|
|
|
|
if (client->extra_headers) {
|
|
|
|
|
assert(evbuffer_add_printf(buf,
|
|
|
|
|
"X-UStreamer-Online: %s" RN
|
|
|
|
|
"X-UStreamer-Width: %u" RN
|
|
|
|
|
"X-UStreamer-Height: %u" RN
|
|
|
|
|
"X-UStreamer-Client-FPS: %u" RN
|
|
|
|
|
"X-UStreamer-Grab-Time: %.06Lf" RN
|
|
|
|
|
"X-UStreamer-Encode-Begin-Time: %.06Lf" RN
|
|
|
|
|
@@ -414,6 +434,8 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
|
|
|
|
"X-UStreamer-Send-Time: %.06Lf" RN
|
|
|
|
|
RN,
|
|
|
|
|
bool_to_string(EXPOSED(online)),
|
|
|
|
|
EXPOSED(width),
|
|
|
|
|
EXPOSED(height),
|
|
|
|
|
client->fps,
|
|
|
|
|
EXPOSED(picture.grab_time),
|
|
|
|
|
EXPOSED(picture.encode_begin_time),
|
|
|
|
|
@@ -442,10 +464,10 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
|
|
|
|
bufferevent_setcb(buf_event, NULL, NULL, _http_callback_stream_error, (void *)client);
|
|
|
|
|
bufferevent_enable(buf_event, EV_READ);
|
|
|
|
|
|
|
|
|
|
# undef BOUNDARY
|
|
|
|
|
# undef RN
|
|
|
|
|
# undef ADD_ADVANCE_HEADERS
|
|
|
|
|
# undef EXPOSED
|
|
|
|
|
# undef ADD_ADVANCE_HEADERS
|
|
|
|
|
# undef RN
|
|
|
|
|
# undef BOUNDARY
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UNUSED short what, void *v_client) {
|
|
|
|
|
@@ -476,6 +498,7 @@ static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UN
|
|
|
|
|
if (client->next != NULL) {
|
|
|
|
|
client->next->prev = client->prev;
|
|
|
|
|
}
|
|
|
|
|
free(client->key);
|
|
|
|
|
free(client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -621,8 +644,8 @@ static bool _expose_new_picture(struct http_server_t *server) {
|
|
|
|
|
EXPOSED(expose_end_time) - EXPOSED(expose_begin_time)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
# undef STREAM
|
|
|
|
|
# undef EXPOSED
|
|
|
|
|
# undef STREAM
|
|
|
|
|
return true; // Updated
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|