using namespace std;
-Stream::Stream(const string &url, size_t backlog_size, size_t prebuffering_bytes, Encoding encoding)
+Stream::Stream(const string &url, size_t backlog_size, size_t prebuffering_bytes, Encoding encoding, Encoding src_encoding)
: url(url),
encoding(encoding),
+ src_encoding(src_encoding),
data_fd(make_tempfile("")),
backlog_size(backlog_size),
prebuffering_bytes(prebuffering_bytes),
DataElement data_element;
data_element.data.iov_base = const_cast<char *>(existing_data.data());
data_element.data.iov_len = existing_data.size();
- data_element.suitable_for_stream_start = NOT_SUITABLE_FOR_STREAM_START; // Ignored by add_data_raw().
+ data_element.metacube_flags = 0; // Ignored by add_data_raw().
vector<DataElement> data_elements;
data_elements.push_back(data_element);
Stream::DataElement data_element;
data_element.data.iov_base = reinterpret_cast<char *>(data[i].data.iov_base) + bytes_wanted;
data_element.data.iov_len = data[i].data.iov_len - bytes_wanted;
- data_element.suitable_for_stream_start = NOT_SUITABLE_FOR_STREAM_START;
+ data_element.metacube_flags = METACUBE_FLAGS_NOT_SUITABLE_FOR_STREAM_START;
ret.push_back(data_element);
bytes_wanted = 0;
}
}
}
-void Stream::add_data_deferred(const char *data, size_t bytes, StreamStartSuitability suitable_for_stream_start)
+void Stream::add_data_deferred(const char *data, size_t bytes, uint16_t metacube_flags)
{
+ // For regular output, we don't want to send the client twice
+ // (it's already sent out together with the HTTP header).
+ // However, for Metacube output, we need to send it so that
+ // the Cubemap instance in the other end has a chance to update it.
+ // It may come twice in its stream, but Cubemap doesn't care.
+ if (encoding == Stream::STREAM_ENCODING_RAW &&
+ (metacube_flags & METACUBE_FLAGS_HEADER) != 0) {
+ return;
+ }
+
MutexLock lock(&queued_data_mutex);
- assert(suitable_for_stream_start == SUITABLE_FOR_STREAM_START ||
- suitable_for_stream_start == NOT_SUITABLE_FOR_STREAM_START);
DataElement data_element;
- data_element.suitable_for_stream_start = suitable_for_stream_start;
+ data_element.metacube_flags = metacube_flags;
if (encoding == Stream::STREAM_ENCODING_METACUBE) {
// Add a Metacube block header before the data.
metacube2_block_header hdr;
memcpy(hdr.sync, METACUBE2_SYNC, sizeof(hdr.sync));
hdr.size = htonl(bytes);
- hdr.flags = htons(0);
- if (suitable_for_stream_start == NOT_SUITABLE_FOR_STREAM_START) {
- hdr.flags |= htons(METACUBE_FLAGS_NOT_SUITABLE_FOR_STREAM_START);
- }
+ hdr.flags = htons(metacube_flags);
hdr.csum = htons(metacube2_compute_crc(&hdr));
data_element.data.iov_base = new char[bytes + sizeof(hdr)];
static const int minimum_start_point_distance = 10240;
size_t byte_position = bytes_received;
for (size_t i = 0; i < queued_data_copy.size(); ++i) {
- if (queued_data_copy[i].suitable_for_stream_start == SUITABLE_FOR_STREAM_START) {
+ if ((queued_data_copy[i].metacube_flags & METACUBE_FLAGS_NOT_SUITABLE_FOR_STREAM_START) == 0) {
size_t num_points = suitable_starting_points.size();
if (num_points >= 2 &&
suitable_starting_points[num_points - 1] - suitable_starting_points[num_points - 2] < minimum_start_point_distance) {