}
#include "chroma_subsampler.h"
-#include "context.h"
+#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"
cinfo.CCIR601_sampling = true; // Seems to be mostly ignored by libjpeg, though.
jpeg_start_compress(&cinfo, true);
+ // This comment marker is private to FFmpeg. It signals limited Y'CbCr range
+ // (and nothing else).
+ jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET *)"CS=ITU601", strlen("CS=ITU601"));
+
JSAMPROW yptr[8], cbptr[8], crptr[8];
JSAMPARRAY data[3] = { yptr, cbptr, crptr };
for (unsigned y = 0; y < height; y += 8) {
void VideoStream::start()
{
AVFormatContext *avctx = avformat_alloc_context();
- avctx->oformat = av_guess_format("nut", nullptr, nullptr);
+
+ // We use Matroska, because it's pretty much the only mux where FFmpeg
+ // allows writing chroma location to override JFIF's default center placement.
+ // (Note that at the time of writing, however, FFmpeg does not correctly
+ // _read_ this information!)
+ avctx->oformat = av_guess_format("matroska", nullptr, nullptr);
uint8_t *buf = (uint8_t *)av_malloc(MUX_BUFFER_SIZE);
avctx->pb = avio_alloc_context(buf, MUX_BUFFER_SIZE, 1, this, nullptr, nullptr, nullptr);
if (type == AVIO_DATA_MARKER_HEADER) {
stream_mux_header.append((char *)buf, buf_size);
- global_httpd->set_header(stream_mux_header);
+ global_httpd->set_header(HTTPD::MAIN_STREAM, stream_mux_header);
} else {
- global_httpd->add_data((char *)buf, buf_size, type == AVIO_DATA_MARKER_SYNC_POINT, time, AVRational{ AV_TIME_BASE, 1 });
+ global_httpd->add_data(HTTPD::MAIN_STREAM, (char *)buf, buf_size, type == AVIO_DATA_MARKER_SYNC_POINT, time, AVRational{ AV_TIME_BASE, 1 });
}
return buf_size;
}