]> git.sesse.net Git - nageru/blobdiff - futatabi/video_stream.cpp
Switch to Matroska for Futatabi's output video stream, as it is much better at preser...
[nageru] / futatabi / video_stream.cpp
index 8738dc546fa85ab09742aaf882454c0389cef402..1957d8410d7a514618a9e51ad345ee933724d9ee 100644 (file)
@@ -107,6 +107,10 @@ vector<uint8_t> encode_jpeg(const uint8_t *y_data, const uint8_t *cb_data, const
        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) {
@@ -234,7 +238,12 @@ VideoStream::~VideoStream() {}
 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);
@@ -649,9 +658,9 @@ int VideoStream::write_packet2(uint8_t *buf, int buf_size, AVIODataMarkerType ty
 
        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;
 }