extern "C" { #include "util/http/http.h" #include "util/opts/fourcc.h" #include "device/buffer_list.h" #include "device/buffer_lock.h" #include "device/camera/camera.h" #include "output/rtsp/rtsp.h" #include "output/webrtc/webrtc.h" #include "output/output.h" extern camera_t *camera; extern http_server_options_t http_options; extern rtsp_options_t rtsp_options; extern webrtc_options_t webrtc_options; }; #include static nlohmann::json serialize_buf_list(buffer_list_t *buf_list) { if (!buf_list) return false; nlohmann::json output; output["name"] = buf_list->name; output["width"] = buf_list->fmt.width; output["height"] = buf_list->fmt.height; output["format"] = fourcc_to_string(buf_list->fmt.format).buf; output["nbufs"] = buf_list->nbufs; return output; } static nlohmann::json serialize_buf_lock(buffer_lock_t *buf_lock) { if (!buf_lock) return false; nlohmann::json output; output["name"] = buf_lock->name; output["enabled"] = (buf_lock->buf_list != NULL); if (buf_lock->buf_list) { output["width"] = buf_lock->buf_list->fmt.width; output["height"] = buf_lock->buf_list->fmt.height; output["source"] = buf_lock->buf_list->name; output["frames"] = buf_lock->counter; output["refs"] = buf_lock->refs; output["dropped"] = buf_lock->dropped; } return output; } static nlohmann::json devices_status_json() { nlohmann::json devices; for (int i = 0; i < MAX_DEVICES; i++) { if (!camera->devices[i]) continue; device_t *device = camera->devices[i]; nlohmann::json device_json; device_json["name"] = device->name; device_json["path"] = device->path; device_json["allow_dma"] = device->opts.allow_dma; device_json["output"] = serialize_buf_list(device->output_list); for (int j = 0; j < device->n_capture_list; j++) { device_json["captures"][j] = serialize_buf_list(device->capture_lists[j]); } devices += device_json; } return devices; } static nlohmann::json links_status_json() { nlohmann::json links; for (int i = 0; i < camera->nlinks; i++) { link_t *link = &camera->links[i]; nlohmann::json link_json; link_json["source"] = link->capture_list->name; for (int j = 0; link->output_lists[j]; j++) { link_json["sinks"][j] = link->output_lists[j]->name; } for (int j = 0; j < link->n_callbacks; j++) { link_json["callbacks"][j] = link->callbacks[j].name; } links += link_json; } return links; } static std::string strip_host_port(const char *host) { const char *sep = strchr(host, ':'); return sep ? std::string(host, sep) : host; } static nlohmann::json get_url(bool running, const char *output, const char *protocol, const char *host, int port, const char *path) { nlohmann::json endpoint; endpoint["enabled"] = running; if (running) { endpoint["output"] = output; endpoint["uri"] = std::string(protocol) + "://" + strip_host_port(host) + ":" + std::to_string(port) + path; } return endpoint; } extern "C" void camera_status_json(http_worker_t *worker, FILE *stream) { nlohmann::json message; message["outputs"]["snapshot"] = serialize_buf_lock(&snapshot_lock); message["outputs"]["stream"] = serialize_buf_lock(&stream_lock); message["outputs"]["video"] = serialize_buf_lock(&video_lock); message["devices"] = devices_status_json(); message["links"] = links_status_json(); message["endpoints"]["rtsp"] = get_url(video_lock.buf_list != NULL && rtsp_options.running, "video", "rtsp", worker->host, rtsp_options.port, "/stream.h264"); message["endpoints"]["webrtc"] = get_url(video_lock.buf_list != NULL && webrtc_options.running, "video", "http", worker->host, http_options.port, "/webrtc"); message["endpoints"]["video"] = get_url(video_lock.buf_list != NULL, "video", "http", worker->host, http_options.port, "/video"); 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"); http_write_response(stream, "200 OK", "application/json", message.dump().c_str(), 0); }