- destination->setFrame(stream_idx, *it);
-}
-
-void Player::open_output_stream()
-{
- AVFormatContext *avctx = avformat_alloc_context();
- avctx->oformat = av_guess_format("nut", 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);
- avctx->pb->write_data_type = &Player::write_packet2_thunk;
- avctx->pb->ignore_boundary_point = 1;
-
- Mux::Codec video_codec = Mux::CODEC_MJPEG;
-
- avctx->flags = AVFMT_FLAG_CUSTOM_IO;
-
- 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, {}));
-}
-
-int Player::write_packet2_thunk(void *opaque, uint8_t *buf, int buf_size, AVIODataMarkerType type, int64_t time)
-{
- Player *player = (Player *)opaque;
- return player->write_packet2(buf, buf_size, type, time);
-}
-
-int Player::write_packet2(uint8_t *buf, int buf_size, AVIODataMarkerType type, int64_t time)
-{
- if (type == AVIO_DATA_MARKER_SYNC_POINT || type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
- seen_sync_markers = true;
- } else if (type == AVIO_DATA_MARKER_UNKNOWN && !seen_sync_markers) {
- // We don't know if this is a keyframe or not (the muxer could
- // avoid marking it), so we just have to make the best of it.
- type = AVIO_DATA_MARKER_SYNC_POINT;
- }
-
- if (type == AVIO_DATA_MARKER_HEADER) {
- stream_mux_header.append((char *)buf, buf_size);
- global_httpd->set_header(stream_mux_header);
- } else {
- global_httpd->add_data((char *)buf, buf_size, type == AVIO_DATA_MARKER_SYNC_POINT, time, AVRational{ AV_TIME_BASE, 1 });
- }
- return buf_size;