]> git.sesse.net Git - nageru/blobdiff - player.cpp
Move stream generation into a new class VideoStream, which will also soon deal with...
[nageru] / player.cpp
index e3998914cb8173fd0070c0bd6ed9b19f73359133..1533977b283df0108c2b1f2246232941c89743ee 100644 (file)
@@ -7,11 +7,6 @@
 
 #include <stdio.h>
 
-extern "C" {
-#include <libavformat/avformat.h>
-#include <libavformat/avio.h>
-}
-
 #include "clip_list.h"
 #include "defs.h"
 #include "ffmpeg_raii.h"
@@ -27,29 +22,6 @@ extern mutex frame_mu;
 extern vector<int64_t> frames[MAX_STREAMS];
 extern HTTPD *global_httpd;
 
-namespace {
-
-string read_file(const string &filename)
-{
-       FILE *fp = fopen(filename.c_str(), "rb");
-       if (fp == nullptr) {
-               perror(filename.c_str());
-               return "";
-       }
-
-       fseek(fp, 0, SEEK_END);
-       long len = ftell(fp);
-       rewind(fp);
-
-       string ret;
-       ret.resize(len);
-       fread(&ret[0], len, 1, fp);
-       fclose(fp);
-       return ret;
-}
-
-}  // namespace
-
 void Player::thread_func()
 {
        for ( ;; ) {
@@ -114,13 +86,7 @@ void Player::thread_func()
                        // FIXME: Vaguely less crazy pts, perhaps.
                        double pts_float = fmod(duration<double>(next_frame_start.time_since_epoch()).count(), 86400.0f);
                        int64_t pts = lrint(pts_float * TIMEBASE);
-                       string jpeg = read_file(filename_for_frame(stream_idx, next_pts));
-                       AVPacket pkt;
-                       av_init_packet(&pkt);
-                       pkt.stream_index = 0;
-                       pkt.data = (uint8_t *)jpeg.data();
-                       pkt.size = jpeg.size();
-                       stream_mux->add_packet(pkt, pts, pts);
+                       video_stream.schedule_original_frame(pts, stream_idx, next_pts);
                }
 
                {
@@ -136,7 +102,7 @@ void Player::thread_func()
 Player::Player(JPEGFrameView *destination)
        : destination(destination)
 {
-       open_output_stream();
+       video_stream.start();
        thread(&Player::thread_func, this).detach();
 }
 
@@ -197,49 +163,3 @@ void Player::override_angle(unsigned stream_idx)
        }
        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;
-}