From fec3f686bf239f9d98782603616613c16f8025b1 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Fri, 8 Jan 2016 01:23:35 +0100 Subject: [PATCH] If we have waiting B-frames at the end of the encode, encode them as such. --- h264encode.cpp | 25 ++++++++++++++++++++++++- h264encode.h | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/h264encode.cpp b/h264encode.cpp index 54f7266..d0da39d 100644 --- a/h264encode.cpp +++ b/h264encode.cpp @@ -1914,7 +1914,13 @@ void H264Encoder::encode_thread_func() frame_queue_nonempty.wait(lock, [this, display_frame_num]{ return encode_thread_should_quit || pending_video_frames.count(display_frame_num) != 0; }); - if (encode_thread_should_quit) { + if (encode_thread_should_quit && pending_video_frames.count(display_frame_num) == 0) { + // We have queued frames that were supposed to be B-frames, + // but will be no P-frame to encode them against. Encode them all + // as P-frames instead. Note that this happens under the mutex, + // but nobody else uses it at this point, since we're shutting down, + // so there's no contention. + encode_remaining_frames_as_p(encoding_frame_num, gop_start_display_frame_num, last_dts); return; } else { frame = move(pending_video_frames[display_frame_num]); @@ -1936,6 +1942,23 @@ void H264Encoder::encode_thread_func() } } +void H264Encoder::encode_remaining_frames_as_p(int encoding_frame_num, int gop_start_display_frame_num, int64_t last_dts) +{ + if (pending_video_frames.empty()) { + return; + } + + for (auto &pending_frame : pending_video_frames) { + int display_frame_num = pending_frame.first; + assert(display_frame_num > 0); + PendingFrame frame = move(pending_frame.second); + int64_t dts = last_dts + (TIMEBASE / MAX_FPS); + printf("Finalizing encode: Encoding leftover frame %d as P-frame instead of B-frame.\n", display_frame_num); + encode_frame(frame, encoding_frame_num++, display_frame_num, gop_start_display_frame_num, FRAME_P, frame.pts, dts); + last_dts = dts; + } +} + void H264Encoder::encode_frame(H264Encoder::PendingFrame frame, int encoding_frame_num, int display_frame_num, int gop_start_display_frame_num, int frame_type, int64_t pts, int64_t dts) { diff --git a/h264encode.h b/h264encode.h index 748fa51..53c6c56 100644 --- a/h264encode.h +++ b/h264encode.h @@ -88,6 +88,7 @@ private: }; void encode_thread_func(); + void encode_remaining_frames_as_p(int encoding_frame_num, int gop_start_display_frame_num, int64_t last_dts); void encode_frame(PendingFrame frame, int encoding_frame_num, int display_frame_num, int gop_start_display_frame_num, int frame_type, int64_t pts, int64_t dts); void storage_task_thread(); -- 2.39.2