X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=futatabi%2Fvideo_stream.cpp;h=4b0336ce3b8384a68673e7a5cf6fd7a0f603e9b2;hb=33b86069c755119da2a35af63fbd580ca9abfa7c;hp=59ab8bfc936d989e9ebc7b2250788c69a8a84df4;hpb=cb0dcfa84f9529ee371ff41ee6813c9bea71766a;p=nageru diff --git a/futatabi/video_stream.cpp b/futatabi/video_stream.cpp index 59ab8bf..4b0336c 100644 --- a/futatabi/video_stream.cpp +++ b/futatabi/video_stream.cpp @@ -28,7 +28,7 @@ extern HTTPD *global_httpd; struct VectorDestinationManager { jpeg_destination_mgr pub; - std::vector dest; + string dest; VectorDestinationManager() { @@ -62,7 +62,7 @@ struct VectorDestinationManager { { dest.resize(bytes_used + 4096); dest.resize(dest.capacity()); - pub.next_output_byte = dest.data() + bytes_used; + pub.next_output_byte = (uint8_t *)dest.data() + bytes_used; pub.free_in_buffer = dest.size() - bytes_used; } @@ -78,7 +78,7 @@ struct VectorDestinationManager { }; static_assert(std::is_standard_layout::value, ""); -vector encode_jpeg(const uint8_t *y_data, const uint8_t *cb_data, const uint8_t *cr_data, unsigned width, unsigned height) +string encode_jpeg(const uint8_t *y_data, const uint8_t *cb_data, const uint8_t *cr_data, unsigned width, unsigned height) { VectorDestinationManager dest; @@ -241,6 +241,30 @@ VideoStream::~VideoStream() if (last_flow_tex != 0) { compute_flow->release_texture(last_flow_tex); } + + for (const unique_ptr &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() @@ -309,20 +333,16 @@ void VideoStream::schedule_original_frame(steady_clock::time_point local_pts, QueueSpotHolder &&queue_spot_holder, FrameOnDisk frame, const string &subtitle) { - 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); + fprintf(stderr, "output_pts=%" PRId64 " original input_pts=%" PRId64 "\n", output_pts, frame.pts); 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 lock(queue_lock); frame_queue.push_back(move(qf)); @@ -335,7 +355,7 @@ void VideoStream::schedule_faded_frame(steady_clock::time_point local_pts, int64 FrameOnDisk frame1_spec, FrameOnDisk frame2_spec, float fade_alpha, const string &subtitle) { - fprintf(stderr, "output_pts=%ld faded input_pts=%ld,%ld fade_alpha=%.2f\n", output_pts, frame1_spec.pts, frame2_spec.pts, fade_alpha); + fprintf(stderr, "output_pts=%" PRId64 " faded input_pts=%" PRId64 ",%" PRId64 " fade_alpha=%.2f\n", output_pts, frame1_spec.pts, frame2_spec.pts, fade_alpha); // Get the temporary OpenGL resources we need for doing the fade. // (We share these with interpolated frames, which is slightly @@ -405,9 +425,9 @@ void VideoStream::schedule_interpolated_frame(steady_clock::time_point local_pts float alpha, FrameOnDisk secondary_frame, float fade_alpha, const string &subtitle) { if (secondary_frame.pts != -1) { - fprintf(stderr, "output_pts=%ld interpolated input_pts1=%ld input_pts2=%ld alpha=%.3f secondary_pts=%ld fade_alpha=%.2f\n", output_pts, frame1.pts, frame2.pts, alpha, secondary_frame.pts, fade_alpha); + fprintf(stderr, "output_pts=%" PRId64 " interpolated input_pts1=%" PRId64 " input_pts2=%" PRId64 " alpha=%.3f secondary_pts=%" PRId64 " fade_alpha=%.2f\n", output_pts, frame1.pts, frame2.pts, alpha, secondary_frame.pts, fade_alpha); } else { - fprintf(stderr, "output_pts=%ld interpolated input_pts1=%ld input_pts2=%ld alpha=%.3f\n", output_pts, frame1.pts, frame2.pts, alpha); + fprintf(stderr, "output_pts=%" PRId64 " interpolated input_pts1=%" PRId64 " input_pts2=%" PRId64 " alpha=%.3f\n", output_pts, frame1.pts, frame2.pts, alpha); } // Get the temporary OpenGL resources we need for doing the interpolation. @@ -580,7 +600,7 @@ void VideoStream::encode_thread_func() bool ok = make_current(context, surface); if (!ok) { fprintf(stderr, "Video stream couldn't get an OpenGL context\n"); - exit(1); + abort(); } while (!should_quit) { @@ -631,7 +651,7 @@ void VideoStream::encode_thread_func() 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; @@ -639,15 +659,14 @@ void VideoStream::encode_thread_func() pkt.size = jpeg.size(); pkt.flags = AV_PKT_FLAG_KEY; mux->add_packet(pkt, qf.output_pts, qf.output_pts); - - last_frame.assign(&jpeg[0], &jpeg[0] + jpeg.size()); + last_frame = move(jpeg); } else if (qf.type == QueuedFrame::FADED) { glClientWaitSync(qf.fence.get(), /*flags=*/0, GL_TIMEOUT_IGNORED); shared_ptr frame = frame_from_pbo(qf.resources->pbo_contents, global_flags.width, global_flags.height); // Now JPEG encode it, and send it on to the stream. - vector jpeg = encode_jpeg(frame->y.get(), frame->cb.get(), frame->cr.get(), global_flags.width, global_flags.height); + string jpeg = encode_jpeg(frame->y.get(), frame->cb.get(), frame->cr.get(), global_flags.width, global_flags.height); AVPacket pkt; av_init_packet(&pkt); @@ -667,7 +686,7 @@ void VideoStream::encode_thread_func() } // Now JPEG encode it, and send it on to the stream. - vector jpeg = encode_jpeg(frame->y.get(), frame->cb.get(), frame->cr.get(), global_flags.width, global_flags.height); + string jpeg = encode_jpeg(frame->y.get(), frame->cb.get(), frame->cr.get(), global_flags.width, global_flags.height); if (qf.flow_tex != 0) { compute_flow->release_texture(qf.flow_tex); }