]> git.sesse.net Git - cubemap/blobdiff - server.cpp
Add a missing const.
[cubemap] / server.cpp
index 14162f58e5a960cc37e35cb18796e270c883714e..9ff4758493abf06d4268fc3a1fd5e54087366408 100644 (file)
@@ -140,7 +140,7 @@ void Server::do_work()
                }
                timeout_time.tv_sec -= REQUEST_READ_TIMEOUT_SEC;
                while (!clients_ordered_by_connect_time.empty()) {
-                       pair<timespec, int> &connect_time_and_fd = clients_ordered_by_connect_time.front();
+                       const pair<timespec, int> &connect_time_and_fd = clients_ordered_by_connect_time.front();
 
                        // See if we have reached the end of clients to process.
                        if (is_earlier(timeout_time, connect_time_and_fd.first)) {
@@ -469,20 +469,43 @@ sending_header_or_error_again:
                        return;
                }
 
-               // Start sending from the first keyframe we get. In other
-               // words, we won't send any of the backlog, but we'll start
-               // sending immediately as we get the next keyframe block.
-               // This is postcondition #3.
                Stream *stream = client->stream;
                if (client->stream_pos == size_t(-2)) {
+                       // Start sending from the beginning of the backlog.
                        client->stream_pos = std::min<size_t>(
                            stream->bytes_received - stream->backlog_size,
                            0);
                        client->state = Client::SENDING_DATA;
                        goto sending_data;
-               } else {
+               } else if (stream->prebuffering_bytes == 0) {
+                       // Start sending from the first keyframe we get. In other
+                       // words, we won't send any of the backlog, but we'll start
+                       // sending immediately as we get the next keyframe block.
+                       // Note that this is functionally identical to the next if branch,
+                       // except that we save a binary search.
                        client->stream_pos = stream->bytes_received;
                        client->state = Client::WAITING_FOR_KEYFRAME;
+               } else {
+                       // We're not going to send anything to the client before we have
+                       // N bytes. However, this wait might be boring; we can just as well
+                       // use it to send older data if we have it. We use lower_bound()
+                       // so that we are conservative and never add extra latency over just
+                       // waiting (assuming CBR or nearly so); otherwise, we could want e.g.
+                       // 100 kB prebuffer but end up sending a 10 MB GOP.
+                       deque<size_t>::const_iterator starting_point_it =
+                               lower_bound(stream->suitable_starting_points.begin(),
+                                           stream->suitable_starting_points.end(),
+                                           stream->bytes_received - stream->prebuffering_bytes);
+                       if (starting_point_it == stream->suitable_starting_points.end()) {
+                               // None found. Just put us at the end, and then wait for the
+                               // first keyframe to appear.
+                               client->stream_pos = stream->bytes_received;
+                               client->state = Client::WAITING_FOR_KEYFRAME;
+                       } else {
+                               client->stream_pos = *starting_point_it;
+                               client->state = Client::PREBUFFERING;
+                               goto prebuffering;
+                       }
                }
                // Fall through.
        }
@@ -501,6 +524,7 @@ sending_header_or_error_again:
                // Fall through.
        }
        case Client::PREBUFFERING: {
+prebuffering:
                Stream *stream = client->stream;
                size_t bytes_to_send = stream->bytes_received - client->stream_pos;
                assert(bytes_to_send <= stream->backlog_size);