]> git.sesse.net Git - nageru/commitdiff
Unify httpd.cpp from Nageru and Futatabi (whitespace differences, and metrics support).
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 3 Dec 2018 08:32:51 +0000 (09:32 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 3 Dec 2018 08:32:51 +0000 (09:32 +0100)
15 files changed:
futatabi/httpd.cpp [deleted file]
futatabi/main.cpp
futatabi/meson.build
futatabi/player.cpp
futatabi/video_stream.cpp
nageru/defs.h
nageru/httpd.h [deleted file]
nageru/meson.build
nageru/mixer.h
nageru/video_encoder.cpp
shared/httpd.cpp [moved from nageru/httpd.cpp with 96% similarity]
shared/httpd.h [moved from futatabi/httpd.h with 95% similarity]
shared/meson.build
shared/mux.cpp
shared/shared_defs.h [moved from shared/mux_opts.h with 62% similarity]

diff --git a/futatabi/httpd.cpp b/futatabi/httpd.cpp
deleted file mode 100644 (file)
index c9399d8..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-#include "httpd.h"
-
-#include <assert.h>
-#include <byteswap.h>
-#include <endian.h>
-#include <memory>
-#include <microhttpd.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-extern "C" {
-#include <libavutil/avutil.h>
-}
-
-#include "defs.h"
-#include "shared/metacube2.h"
-
-struct MHD_Connection;
-struct MHD_Response;
-
-using namespace std;
-
-HTTPD::HTTPD()
-{
-}
-
-HTTPD::~HTTPD()
-{
-       stop();
-}
-
-void HTTPD::start(int port)
-{
-       mhd = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_POLL_INTERNALLY | MHD_USE_DUAL_STACK,
-                              port,
-                              nullptr, nullptr,
-                              &answer_to_connection_thunk, this,
-                              MHD_OPTION_NOTIFY_COMPLETED, nullptr, this,
-                              MHD_OPTION_END);
-       if (mhd == nullptr) {
-               fprintf(stderr, "Warning: Could not open HTTP server. (Port already in use?)\n");
-       }
-}
-
-void HTTPD::stop()
-{
-       if (mhd) {
-               MHD_quiesce_daemon(mhd);
-               for (Stream *stream : streams) {
-                       stream->stop();
-               }
-               MHD_stop_daemon(mhd);
-               mhd = nullptr;
-       }
-}
-
-void HTTPD::add_data(const char *buf, size_t size, bool keyframe, int64_t time, AVRational timebase)
-{
-       unique_lock<mutex> lock(streams_mutex);
-       for (Stream *stream : streams) {
-               stream->add_data(buf, size, keyframe ? Stream::DATA_TYPE_KEYFRAME : Stream::DATA_TYPE_OTHER, time, timebase);
-       }
-}
-
-int HTTPD::answer_to_connection_thunk(void *cls, MHD_Connection *connection,
-                                      const char *url, const char *method,
-                                      const char *version, const char *upload_data,
-                                      size_t *upload_data_size, void **con_cls)
-{
-       HTTPD *httpd = (HTTPD *)cls;
-       return httpd->answer_to_connection(connection, url, method, version, upload_data, upload_data_size, con_cls);
-}
-
-int HTTPD::answer_to_connection(MHD_Connection *connection,
-                                const char *url, const char *method,
-                                const char *version, const char *upload_data,
-                                size_t *upload_data_size, void **con_cls)
-{
-       // See if the URL ends in “.metacube”.
-       HTTPD::Stream::Framing framing;
-       if (strstr(url, ".metacube") == url + strlen(url) - strlen(".metacube")) {
-               framing = HTTPD::Stream::FRAMING_METACUBE;
-       } else {
-               framing = HTTPD::Stream::FRAMING_RAW;
-       }
-
-       if (endpoints.count(url)) {
-               pair<string, string> contents_and_type = endpoints[url].callback();
-               MHD_Response *response = MHD_create_response_from_buffer(
-                       contents_and_type.first.size(), &contents_and_type.first[0], MHD_RESPMEM_MUST_COPY);
-               MHD_add_response_header(response, "Content-type", contents_and_type.second.c_str());
-               if (endpoints[url].cors_policy == ALLOW_ALL_ORIGINS) {
-                       MHD_add_response_header(response, "Access-Control-Allow-Origin", "*");
-               }
-               int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
-               MHD_destroy_response(response);  // Only decreases the refcount; actual free is after the request is done.
-               return ret;
-       }
-
-       // Small hack; reject unknown /channels/foo.
-       if (string(url).find("/channels/") == 0) {
-               string contents = "Not found.";
-               MHD_Response *response = MHD_create_response_from_buffer(
-                       contents.size(), &contents[0], MHD_RESPMEM_MUST_COPY);
-               MHD_add_response_header(response, "Content-type", "text/plain");
-               int ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response);
-               MHD_destroy_response(response);  // Only decreases the refcount; actual free is after the request is done.
-               return ret;
-       }
-
-       HTTPD::Stream *stream = new HTTPD::Stream(this, framing);
-       stream->add_data(header.data(), header.size(), Stream::DATA_TYPE_HEADER, AV_NOPTS_VALUE, AVRational{ 1, 0 });
-       {
-               unique_lock<mutex> lock(streams_mutex);
-               streams.insert(stream);
-       }
-       ++metric_num_connected_clients;
-       *con_cls = stream;
-
-       // Does not strictly have to be equal to MUX_BUFFER_SIZE.
-       MHD_Response *response = MHD_create_response_from_callback(
-               (size_t)-1, MUX_BUFFER_SIZE, &HTTPD::Stream::reader_callback_thunk, stream, &HTTPD::free_stream);
-       // TODO: Content-type?
-       if (framing == HTTPD::Stream::FRAMING_METACUBE) {
-               MHD_add_response_header(response, "Content-encoding", "metacube");
-       }
-
-       int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
-       MHD_destroy_response(response);  // Only decreases the refcount; actual free is after the request is done.
-
-       return ret;
-}
-
-void HTTPD::free_stream(void *cls)
-{
-       HTTPD::Stream *stream = (HTTPD::Stream *)cls;
-       HTTPD *httpd = stream->get_parent();
-       {
-               unique_lock<mutex> lock(httpd->streams_mutex);
-               delete stream;
-               httpd->streams.erase(stream);
-       }
-       --httpd->metric_num_connected_clients;
-}
-
-ssize_t HTTPD::Stream::reader_callback_thunk(void *cls, uint64_t pos, char *buf, size_t max)
-{
-       HTTPD::Stream *stream = (HTTPD::Stream *)cls;
-       return stream->reader_callback(pos, buf, max);
-}
-
-ssize_t HTTPD::Stream::reader_callback(uint64_t pos, char *buf, size_t max)
-{
-       unique_lock<mutex> lock(buffer_mutex);
-       has_buffered_data.wait(lock, [this] { return should_quit || !buffered_data.empty(); });
-       if (should_quit) {
-               return 0;
-       }
-
-       ssize_t ret = 0;
-       while (max > 0 && !buffered_data.empty()) {
-               const string &s = buffered_data.front();
-               assert(s.size() > used_of_buffered_data);
-               size_t len = s.size() - used_of_buffered_data;
-               if (max >= len) {
-                       // Consume the entire (rest of the) string.
-                       memcpy(buf, s.data() + used_of_buffered_data, len);
-                       buf += len;
-                       ret += len;
-                       max -= len;
-                       buffered_data.pop_front();
-                       used_of_buffered_data = 0;
-               } else {
-                       // We don't need the entire string; just use the first part of it.
-                       memcpy(buf, s.data() + used_of_buffered_data, max);
-                       buf += max;
-                       used_of_buffered_data += max;
-                       ret += max;
-                       max = 0;
-               }
-       }
-
-       return ret;
-}
-
-void HTTPD::Stream::add_data(const char *buf, size_t buf_size, HTTPD::Stream::DataType data_type, int64_t time, AVRational timebase)
-{
-       if (buf_size == 0) {
-               return;
-       }
-       if (data_type == DATA_TYPE_KEYFRAME) {
-               seen_keyframe = true;
-       } else if (data_type == DATA_TYPE_OTHER && !seen_keyframe) {
-               // Start sending only once we see a keyframe.
-               return;
-       }
-
-       unique_lock<mutex> lock(buffer_mutex);
-
-       if (framing == FRAMING_METACUBE) {
-               int flags = 0;
-               if (data_type == DATA_TYPE_HEADER) {
-                       flags |= METACUBE_FLAGS_HEADER;
-               } else if (data_type == DATA_TYPE_OTHER) {
-                       flags |= METACUBE_FLAGS_NOT_SUITABLE_FOR_STREAM_START;
-               }
-
-               // If we're about to send a keyframe, send a pts metadata block
-               // to mark its time.
-               if ((flags & METACUBE_FLAGS_NOT_SUITABLE_FOR_STREAM_START) == 0 && time != AV_NOPTS_VALUE) {
-                       metacube2_pts_packet packet;
-                       packet.type = htobe64(METACUBE_METADATA_TYPE_NEXT_BLOCK_PTS);
-                       packet.pts = htobe64(time);
-                       packet.timebase_num = htobe64(timebase.num);
-                       packet.timebase_den = htobe64(timebase.den);
-
-                       metacube2_block_header hdr;
-                       memcpy(hdr.sync, METACUBE2_SYNC, sizeof(hdr.sync));
-                       hdr.size = htonl(sizeof(packet));
-                       hdr.flags = htons(METACUBE_FLAGS_METADATA);
-                       hdr.csum = htons(metacube2_compute_crc(&hdr));
-                       buffered_data.emplace_back((char *)&hdr, sizeof(hdr));
-                       buffered_data.emplace_back((char *)&packet, sizeof(packet));
-               }
-
-               metacube2_block_header hdr;
-               memcpy(hdr.sync, METACUBE2_SYNC, sizeof(hdr.sync));
-               hdr.size = htonl(buf_size);
-               hdr.flags = htons(flags);
-               hdr.csum = htons(metacube2_compute_crc(&hdr));
-               buffered_data.emplace_back((char *)&hdr, sizeof(hdr));
-       }
-       buffered_data.emplace_back(buf, buf_size);
-
-       // Send a Metacube2 timestamp every keyframe.
-       if (framing == FRAMING_METACUBE && data_type == DATA_TYPE_KEYFRAME) {
-               timespec now;
-               clock_gettime(CLOCK_REALTIME, &now);
-
-               metacube2_timestamp_packet packet;
-               packet.type = htobe64(METACUBE_METADATA_TYPE_ENCODER_TIMESTAMP);
-               packet.tv_sec = htobe64(now.tv_sec);
-               packet.tv_nsec = htobe64(now.tv_nsec);
-
-               metacube2_block_header hdr;
-               memcpy(hdr.sync, METACUBE2_SYNC, sizeof(hdr.sync));
-               hdr.size = htonl(sizeof(packet));
-               hdr.flags = htons(METACUBE_FLAGS_METADATA);
-               hdr.csum = htons(metacube2_compute_crc(&hdr));
-               buffered_data.emplace_back((char *)&hdr, sizeof(hdr));
-               buffered_data.emplace_back((char *)&packet, sizeof(packet));
-       }
-
-       has_buffered_data.notify_all();
-}
-
-void HTTPD::Stream::stop()
-{
-       unique_lock<mutex> lock(buffer_mutex);
-       should_quit = true;
-       has_buffered_data.notify_all();
-}
index b885c81d82858af66253d6156c99cc748d9a7129..46fb200eb149f47eba370d7a23697d992eda463d 100644 (file)
@@ -27,7 +27,7 @@ extern "C" {
 #include "flags.h"
 #include "frame_on_disk.h"
 #include "frame.pb.h"
-#include "httpd.h"
+#include "shared/httpd.h"
 #include "mainwindow.h"
 #include "player.h"
 #include "shared/post_to_main_thread.h"
index 3f82d8d72bf7dad74566669e828716a6129ac882..aa58291db76d66ec2e67a7d85ffda9e93a8b6dc9 100644 (file)
@@ -6,7 +6,6 @@ libavcodecdep = dependency('libavcodec')
 libavformatdep = dependency('libavformat')
 libavutildep = dependency('libavutil')
 libjpegdep = dependency('libjpeg')
-libmicrohttpddep = dependency('libmicrohttpd')
 libswscaledep = dependency('libswscale')
 movitdep = dependency('movit')
 protobufdep = dependency('protobuf')
@@ -34,7 +33,7 @@ moc_files = qt5.preprocess(
 srcs = ['flow.cpp', 'gpu_timers.cpp']
 
 # All the other files.
-srcs += ['main.cpp', 'player.cpp', 'httpd.cpp', 'video_stream.cpp', 'chroma_subsampler.cpp']
+srcs += ['main.cpp', 'player.cpp', 'video_stream.cpp', 'chroma_subsampler.cpp']
 srcs += ['vaapi_jpeg_decoder.cpp', 'db.cpp', 'disk_space_estimator.cpp', 'ycbcr_converter.cpp', 'flags.cpp']
 srcs += ['mainwindow.cpp', 'jpeg_frame_view.cpp', 'clip_list.cpp', 'frame_on_disk.cpp']
 srcs += moc_files
index 816f72d216662169ba79e688da6f1b054bb30613..b88aa56267e7b7e87f9747be3db8d96e25280e5a 100644 (file)
@@ -5,7 +5,7 @@
 #include "defs.h"
 #include "shared/ffmpeg_raii.h"
 #include "frame_on_disk.h"
-#include "httpd.h"
+#include "shared/httpd.h"
 #include "jpeg_frame_view.h"
 #include "shared/mux.h"
 #include "shared/timebase.h"
index 52612e2f53996756a3c2d67f8fccf9cc13a3b3cc..8738dc546fa85ab09742aaf882454c0389cef402 100644 (file)
@@ -9,7 +9,7 @@ extern "C" {
 #include "shared/context.h"
 #include "flags.h"
 #include "flow.h"
-#include "httpd.h"
+#include "shared/httpd.h"
 #include "jpeg_frame_view.h"
 #include "movit/util.h"
 #include "shared/mux.h"
index ae07be004ff16de3120c732466b7323232fdd4a3..a990330759348796474d219bd1a7b3c4d405effa 100644 (file)
 #define DEFAULT_STREAM_MUX_NAME "nut"  // Only for HTTP. Local dump guesses from LOCAL_DUMP_SUFFIX.
 #define DEFAULT_HTTPD_PORT 9095
 
-#include "shared/mux_opts.h"
-
-// In bytes. Beware, if too small, stream clients will start dropping data.
-// For mov, you want this at 10MB or so (for the reason mentioned above),
-// but for nut, there's no flushing, so such a large mux buffer would cause
-// the output to be very uneven.
-#define MUX_BUFFER_SIZE 10485760
+#include "shared/shared_defs.h"
 
 // In number of frames. Comes in addition to any internal queues in x264
 // (frame threading, lookahead, etc.).
diff --git a/nageru/httpd.h b/nageru/httpd.h
deleted file mode 100644 (file)
index 57c649b..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#ifndef _HTTPD_H
-#define _HTTPD_H
-
-// A class dealing with stream output to HTTP.
-
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <atomic>
-#include <condition_variable>
-#include <deque>
-#include <functional>
-#include <mutex>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <utility>
-
-extern "C" {
-#include <libavutil/rational.h>
-}
-
-struct MHD_Connection;
-struct MHD_Daemon;
-
-class HTTPD {
-public:
-       // Returns a pair of content and content-type.
-       using EndpointCallback = std::function<std::pair<std::string, std::string>()>;
-
-       HTTPD();
-       ~HTTPD();
-
-       // Should be called before start().
-       void set_header(const std::string &data) {
-               header = data;
-       }
-
-       // Should be called before start() (due to threading issues).
-       enum CORSPolicy {
-               NO_CORS_POLICY,
-               ALLOW_ALL_ORIGINS
-       };
-       void add_endpoint(const std::string &url, const EndpointCallback &callback, CORSPolicy cors_policy) {
-               endpoints[url] = Endpoint{ callback, cors_policy };
-       }
-
-       void start(int port);
-       void stop();
-       void add_data(const char *buf, size_t size, bool keyframe, int64_t time, AVRational timebase);
-       int64_t get_num_connected_clients() const {
-               return metric_num_connected_clients.load();
-       }
-
-private:
-       static int answer_to_connection_thunk(void *cls, MHD_Connection *connection,
-                                             const char *url, const char *method,
-                                             const char *version, const char *upload_data,
-                                             size_t *upload_data_size, void **con_cls);
-
-       int answer_to_connection(MHD_Connection *connection,
-                                const char *url, const char *method,
-                                const char *version, const char *upload_data,
-                                size_t *upload_data_size, void **con_cls);
-
-       static void free_stream(void *cls);
-
-
-       class Stream {
-       public:
-               enum Framing {
-                       FRAMING_RAW,
-                       FRAMING_METACUBE
-               };
-               Stream(HTTPD *parent, Framing framing) : parent(parent), framing(framing) {}
-
-               static ssize_t reader_callback_thunk(void *cls, uint64_t pos, char *buf, size_t max);
-               ssize_t reader_callback(uint64_t pos, char *buf, size_t max);
-
-               enum DataType {
-                       DATA_TYPE_HEADER,
-                       DATA_TYPE_KEYFRAME,
-                       DATA_TYPE_OTHER
-               };
-               void add_data(const char *buf, size_t size, DataType data_type, int64_t time, AVRational timebase);
-               void stop();
-               HTTPD *get_parent() const { return parent; }
-
-       private:
-               HTTPD *parent;
-               Framing framing;
-
-               std::mutex buffer_mutex;
-               bool should_quit = false;  // Under <buffer_mutex>.
-               std::condition_variable has_buffered_data;
-               std::deque<std::string> buffered_data;  // Protected by <buffer_mutex>.
-               size_t used_of_buffered_data = 0;  // How many bytes of the first element of <buffered_data> that is already used. Protected by <mutex>.
-               size_t seen_keyframe = false;
-       };
-
-       MHD_Daemon *mhd = nullptr;
-       std::mutex streams_mutex;
-       std::set<Stream *> streams;  // Not owned.
-       struct Endpoint {
-               EndpointCallback callback;
-               CORSPolicy cors_policy;
-       };
-       std::unordered_map<std::string, Endpoint> endpoints;
-       std::string header;
-
-       // Metrics.
-       std::atomic<int64_t> metric_num_connected_clients{0};
-};
-
-#endif  // !defined(_HTTPD_H)
index 1fb60e674f591bee7afc8af97103d48133a55f6b..737d889cbe30bc6ec6ef3f3bc827e6dda399d4f3 100644 (file)
@@ -13,7 +13,6 @@ libavformatdep = dependency('libavformat')
 libavresampledep = dependency('libavresample')
 libavutildep = dependency('libavutil')
 libjpegdep = dependency('libjpeg')
-libmicrohttpddep = dependency('libmicrohttpd')
 libswscaledep = dependency('libswscale')
 libusbdep = dependency('libusb-1.0')
 luajitdep = dependency('luajit')
@@ -29,7 +28,7 @@ x264dep = dependency('x264')
 zitaresamplerdep = cxx.find_library('zita-resampler')
 
 srcs = []
-nageru_deps = [shareddep, qt5deps, libjpegdep, movitdep, libmicrohttpddep, protobufdep,
+nageru_deps = [shareddep, qt5deps, libjpegdep, movitdep, protobufdep,
        vax11dep, vadrmdep, x11dep, libavformatdep, libavresampledep, libavcodecdep, libavutildep,
        libswscaledep, libusbdep, luajitdep, dldep, x264dep, alsadep, zitaresamplerdep,
        qcustomplotdep, threaddep]
@@ -166,7 +165,7 @@ srcs += ['chroma_subsampler.cpp', 'v210_converter.cpp', 'mixer.cpp', 'pbo_frame_
 
 # Streaming and encoding objects (largely the set that is shared between Nageru and Kaeru).
 stream_srcs = ['quicksync_encoder.cpp', 'x264_encoder.cpp', 'x264_dynamic.cpp', 'x264_speed_control.cpp', 'video_encoder.cpp',
-       'audio_encoder.cpp', 'ffmpeg_util.cpp', 'httpd.cpp', 'ffmpeg_capture.cpp',
+       'audio_encoder.cpp', 'ffmpeg_util.cpp', 'ffmpeg_capture.cpp',
        'print_latency.cpp', 'basic_stats.cpp', 'ref_counted_frame.cpp']
 stream = static_library('stream', stream_srcs, dependencies: nageru_deps, include_directories: nageru_include_dirs)
 nageru_link_with += stream
index 2c394494a932561bdd99499e921295c8eeda6fe4..3ed6c5f5c9baac664fc48d6a31f40cc60498155a 100644 (file)
@@ -28,7 +28,7 @@
 #include "audio_mixer.h"
 #include "bmusb/bmusb.h"
 #include "defs.h"
-#include "httpd.h"
+#include "shared/httpd.h"
 #include "input_state.h"
 #include "libusb.h"
 #include "pbo_frame_allocator.h"
index 5f5b975feb175497316f3590b407bab42b5a0e22..6749f3579f2fbe137819b6b976c872d580c3447a 100644 (file)
@@ -15,7 +15,7 @@ extern "C" {
 #include "defs.h"
 #include "shared/ffmpeg_raii.h"
 #include "flags.h"
-#include "httpd.h"
+#include "shared/httpd.h"
 #include "shared/mux.h"
 #include "quicksync_encoder.h"
 #include "shared/timebase.h"
similarity index 96%
rename from nageru/httpd.cpp
rename to shared/httpd.cpp
index eebf6eba8d5a56678a9d18a738bd06c88dc393ff..28ed783872ff2ab18bf1b1bf8e175b0dd520835c 100644 (file)
@@ -1,20 +1,20 @@
-#include "httpd.h"
+#include "shared/httpd.h"
 
 #include <assert.h>
 #include <byteswap.h>
 #include <endian.h>
+#include <memory>
 #include <microhttpd.h>
 #include <netinet/in.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/time.h>
 #include <time.h>
-#include <memory>
 extern "C" {
 #include <libavutil/avutil.h>
 }
 
-#include "defs.h"
+#include "shared/shared_defs.h"
 #include "shared/metacube2.h"
 #include "shared/metrics.h"
 
@@ -77,8 +77,8 @@ int HTTPD::answer_to_connection_thunk(void *cls, MHD_Connection *connection,
 
 int HTTPD::answer_to_connection(MHD_Connection *connection,
                                 const char *url, const char *method,
-                               const char *version, const char *upload_data,
-                               size_t *upload_data_size, void **con_cls)
+                                const char *version, const char *upload_data,
+                                size_t *upload_data_size, void **con_cls)
 {
        // See if the URL ends in “.metacube”.
        HTTPD::Stream::Framing framing;
@@ -165,7 +165,7 @@ ssize_t HTTPD::Stream::reader_callback_thunk(void *cls, uint64_t pos, char *buf,
 ssize_t HTTPD::Stream::reader_callback(uint64_t pos, char *buf, size_t max)
 {
        unique_lock<mutex> lock(buffer_mutex);
-       has_buffered_data.wait(lock, [this]{ return should_quit || !buffered_data.empty(); });
+       has_buffered_data.wait(lock, [this] { return should_quit || !buffered_data.empty(); });
        if (should_quit) {
                return 0;
        }
@@ -264,7 +264,7 @@ void HTTPD::Stream::add_data(const char *buf, size_t buf_size, HTTPD::Stream::Da
                buffered_data.emplace_back((char *)&packet, sizeof(packet));
        }
 
-       has_buffered_data.notify_all(); 
+       has_buffered_data.notify_all();
 }
 
 void HTTPD::Stream::stop()
similarity index 95%
rename from futatabi/httpd.h
rename to shared/httpd.h
index 9901814586cb913ca06c7f6afc4f39364561f5ac..5b2b266c36e70788b2daabe018251d50392fcd7a 100644 (file)
@@ -68,14 +68,14 @@ private:
 
        static void free_stream(void *cls);
 
-
        class Stream {
        public:
                enum Framing {
                        FRAMING_RAW,
                        FRAMING_METACUBE
                };
-               Stream(HTTPD *parent, Framing framing) : parent(parent), framing(framing) {}
+               Stream(HTTPD *parent, Framing framing)
+                       : parent(parent), framing(framing) {}
 
                static ssize_t reader_callback_thunk(void *cls, uint64_t pos, char *buf, size_t max);
                ssize_t reader_callback(uint64_t pos, char *buf, size_t max);
@@ -112,7 +112,7 @@ private:
        std::string header;
 
        // Metrics.
-       std::atomic<int64_t> metric_num_connected_clients{0};
+       std::atomic<int64_t> metric_num_connected_clients{ 0 };
 };
 
 #endif  // !defined(_HTTPD_H)
index 8d1b203c7cd56e65feecd9eceea757f3dc3926f4..1bb183b9a2e8107dc0753091421a269637b077c3 100644 (file)
@@ -1,8 +1,9 @@
 qt5 = import('qt5')
 qt5deps = dependency('qt5', modules: ['OpenGL'])
+libmicrohttpddep = dependency('libmicrohttpd')
 
-srcs = ['memcpy_interleaved.cpp', 'metacube2.cpp', 'ffmpeg_raii.cpp', 'mux.cpp', 'metrics.cpp', 'context.cpp']
-shared = static_library('shared', srcs, include_directories: top_include, dependencies: qt5deps)
+srcs = ['memcpy_interleaved.cpp', 'metacube2.cpp', 'ffmpeg_raii.cpp', 'mux.cpp', 'metrics.cpp', 'context.cpp', 'httpd.cpp']
+shared = static_library('shared', srcs, include_directories: top_include, dependencies: [qt5deps, libmicrohttpddep])
 shareddep = declare_dependency(
    include_directories: top_include,
    link_with: shared)
index da618e0c6bbc1066ef4c3db110f935c48c0bde45..4970bcea81bcd684eb019d5484586d888c757a80 100644 (file)
@@ -22,7 +22,7 @@ extern "C" {
 }
 
 #include "shared/metrics.h"
-#include "shared/mux_opts.h"
+#include "shared/shared_defs.h"
 #include "shared/timebase.h"
 
 using namespace std;
similarity index 62%
rename from shared/mux_opts.h
rename to shared/shared_defs.h
index 0315fb884f264e77f349dffa47a8e86f181eae8a..fc3daa1a3b0785608ed2255ca537b40772dc3ef1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _MUX_OPTS_H
-#define _MUX_OPTS_H 1
+#ifndef _SHARED_DEFS_H
+#define _SHARED_DEFS_H 1
 
 // This flag is only supported in FFmpeg 3.3 and up, and we only require 3.1.
 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 71, 100)
        { "write_index", "0" } \
 }
 
-#endif  // !defined(_MUX_OPTS_H)
+// In bytes. Beware, if too small, stream clients will start dropping data.
+// For mov, you want this at 10MB or so (for the reason mentioned above),
+// but for nut, there's no flushing, so such a large mux buffer would cause
+// the output to be very uneven.
+#define MUX_BUFFER_SIZE 10485760
+
+#endif  // !defined(_SHARED_DEFS_H)