X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=futatabi%2Fvideo_stream.cpp;h=1957d8410d7a514618a9e51ad345ee933724d9ee;hb=1832a337468b13b513d3e77c32cca6207764bd23;hp=d425ed190b6fa3187a6f3311c3c980d7ff48c031;hpb=6e116a6bbeb2c047a3bfb084395ec601ce211e6c;p=nageru diff --git a/futatabi/video_stream.cpp b/futatabi/video_stream.cpp index d425ed1..1957d84 100644 --- a/futatabi/video_stream.cpp +++ b/futatabi/video_stream.cpp @@ -6,13 +6,13 @@ extern "C" { } #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 "mux.h" +#include "shared/mux.h" #include "player.h" #include "util.h" #include "ycbcr_converter.h" @@ -107,6 +107,10 @@ vector 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); @@ -248,8 +257,9 @@ void VideoStream::start() string video_extradata; constexpr int width = 1280, height = 720; // Doesn't matter for MJPEG. - stream_mux.reset(new Mux(avctx, width, height, video_codec, video_extradata, /*audio_codec_parameters=*/nullptr, COARSE_TIMEBASE, - /*write_callback=*/nullptr, Mux::WRITE_FOREGROUND, {})); + stream_mux.reset(new Mux(avctx, width, height, video_codec, video_extradata, /*audio_codec_parameters=*/nullptr, + AVCOL_SPC_BT709, Mux::WITHOUT_AUDIO, + COARSE_TIMEBASE, /*write_callback=*/nullptr, Mux::WRITE_FOREGROUND, {})); encode_thread = thread(&VideoStream::encode_thread_func, this); @@ -648,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; }