]> git.sesse.net Git - nageru/commitdiff
If we have waiting B-frames at the end of the encode, encode them as such.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 8 Jan 2016 00:23:35 +0000 (01:23 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 8 Jan 2016 00:23:35 +0000 (01:23 +0100)
h264encode.cpp
h264encode.h

index 54f72666df31930c727048e19e1d4171cc384487..d0da39d08c0925e79ab9c9cef418257c3b95bb2e 100644 (file)
@@ -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)
 {
index 748fa5170812f387c819208b2059dee819db89c5..53c6c569feab9724f5fd8c0780a6ebbc54814946 100644 (file)
@@ -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();