]> git.sesse.net Git - nageru/blobdiff - futatabi/video_stream.cpp
Make the preview light blink and be solid like the play light is.
[nageru] / futatabi / video_stream.cpp
index 745da27486971b13414549033b3270fa00a37174..a820411064234bef2d29aa9c7a95f91a1cd0771d 100644 (file)
@@ -241,6 +241,30 @@ VideoStream::~VideoStream()
        if (last_flow_tex != 0) {
                compute_flow->release_texture(last_flow_tex);
        }
+
+       for (const unique_ptr<InterpolatedFrameResources> &resource : interpolate_resources) {
+               glUnmapNamedBuffer(resource->pbo);
+               check_error();
+               glDeleteBuffers(1, &resource->pbo);
+               check_error();
+               glDeleteFramebuffers(2, resource->input_fbos);
+               check_error();
+               glDeleteFramebuffers(1, &resource->fade_fbo);
+               check_error();
+               glDeleteTextures(1, &resource->input_tex);
+               check_error();
+               glDeleteTextures(1, &resource->gray_tex);
+               check_error();
+               glDeleteTextures(1, &resource->fade_y_output_tex);
+               check_error();
+               glDeleteTextures(1, &resource->fade_cbcr_output_tex);
+               check_error();
+               glDeleteTextures(1, &resource->cb_tex);
+               check_error();
+               glDeleteTextures(1, &resource->cr_tex);
+               check_error();
+       }
+       assert(interpolate_resources.size() == num_interpolate_slots);
 }
 
 void VideoStream::start()
@@ -311,18 +335,14 @@ void VideoStream::schedule_original_frame(steady_clock::time_point local_pts,
 {
        fprintf(stderr, "output_pts=%ld  original      input_pts=%ld\n", output_pts, frame.pts);
 
-       // Preload the file from disk, so that the encoder thread does not get stalled.
-       // TODO: Consider sending it through the queue instead.
-       (void)frame_reader.read_frame(frame);
-
        QueuedFrame qf;
        qf.local_pts = local_pts;
        qf.type = QueuedFrame::ORIGINAL;
        qf.output_pts = output_pts;
-       qf.frame1 = frame;
        qf.display_func = move(display_func);
        qf.queue_spot_holder = move(queue_spot_holder);
        qf.subtitle = subtitle;
+       qf.encoded_jpeg.reset(new string(frame_reader.read_frame(frame)));
 
        lock_guard<mutex> lock(queue_lock);
        frame_queue.push_back(move(qf));
@@ -615,9 +635,23 @@ void VideoStream::encode_thread_func()
                        frame_queue.pop_front();
                }
 
+               // Hack: We mux the subtitle packet one time unit before the actual frame,
+               // so that Nageru is sure to get it first.
+               if (!qf.subtitle.empty()) {
+                       AVPacket pkt;
+                       av_init_packet(&pkt);
+                       pkt.stream_index = mux->get_subtitle_stream_idx();
+                       assert(pkt.stream_index != -1);
+                       pkt.data = (uint8_t *)qf.subtitle.data();
+                       pkt.size = qf.subtitle.size();
+                       pkt.flags = 0;
+                       pkt.duration = lrint(TIMEBASE / global_flags.output_framerate);  // Doesn't really matter for Nageru.
+                       mux->add_packet(pkt, qf.output_pts - 1, qf.output_pts - 1);
+               }
+
                if (qf.type == QueuedFrame::ORIGINAL) {
                        // Send the JPEG frame on, unchanged.
-                       string jpeg = frame_reader.read_frame(qf.frame1);
+                       string jpeg = move(*qf.encoded_jpeg);
                        AVPacket pkt;
                        av_init_packet(&pkt);
                        pkt.stream_index = 0;
@@ -681,19 +715,6 @@ void VideoStream::encode_thread_func()
                } else {
                        assert(false);
                }
-
-               if (!qf.subtitle.empty()) {
-                       AVPacket pkt;
-                       av_init_packet(&pkt);
-                       pkt.stream_index = mux->get_subtitle_stream_idx();
-                       assert(pkt.stream_index != -1);
-                       pkt.data = (uint8_t *)qf.subtitle.data();
-                       pkt.size = qf.subtitle.size();
-                       pkt.flags = 0;
-                       pkt.duration = lrint(TIMEBASE / global_flags.output_framerate);  // Doesn't really matter for Nageru.
-                       mux->add_packet(pkt, qf.output_pts, qf.output_pts);
-               }
-
                if (qf.display_func != nullptr) {
                        qf.display_func();
                }