]> git.sesse.net Git - nageru/commitdiff
Make a separate shutdown from the destructor for the H.264 encoder.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 10 Jan 2016 13:02:40 +0000 (14:02 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 10 Jan 2016 13:02:40 +0000 (14:02 +0100)
h264encode.cpp
h264encode.h

index 6998e7503c4bbf061a6005843f85f46b15cacbf1..d5c9e8c9e70a905cb4bef7ee53144e3c1aa91836 100644 (file)
@@ -113,6 +113,7 @@ public:
        void add_audio(int64_t pts, vector<float> audio);  // Needs to come before end_frame() of same pts.
        bool begin_frame(GLuint *y_tex, GLuint *cbcr_tex);
        void end_frame(RefCountedGLsync fence, int64_t pts, const vector<RefCountedFrame> &input_frames);
+       void shutdown();
 
 private:
        struct storage_task {
@@ -155,6 +156,8 @@ private:
        void update_ReferenceFrames(int frame_type);
        int update_RefPicList(int frame_type);
 
+       bool is_shutdown = false;
+
        thread encode_thread, storage_thread;
 
        mutex storage_task_queue_mutex;
@@ -229,7 +232,6 @@ private:
        int frame_height_mbaligned;
 };
 
-
 // Supposedly vaRenderPicture() is supposed to destroy the buffer implicitly,
 // but if we don't delete it here, we get leaks. The GStreamer implementation
 // does the same.
@@ -1650,26 +1652,12 @@ H264EncoderImpl::H264EncoderImpl(QSurface *surface, int width, int height, HTTPD
 
 H264EncoderImpl::~H264EncoderImpl()
 {
-       {
-               unique_lock<mutex> lock(frame_queue_mutex);
-               encode_thread_should_quit = true;
-               frame_queue_nonempty.notify_all();
-       }
-       encode_thread.join();
-       {
-               unique_lock<mutex> lock(storage_task_queue_mutex);
-               storage_thread_should_quit = true;
-               frame_queue_nonempty.notify_all();
-               storage_task_queue_changed.notify_all();
-       }
-       storage_thread.join();
-
-       release_encode();
-       deinit_va();
+       shutdown();
 }
 
 bool H264EncoderImpl::begin_frame(GLuint *y_tex, GLuint *cbcr_tex)
 {
+       assert(!is_shutdown);
        {
                // Wait until this frame slot is done encoding.
                unique_lock<mutex> lock(storage_task_queue_mutex);
@@ -1734,6 +1722,7 @@ bool H264EncoderImpl::begin_frame(GLuint *y_tex, GLuint *cbcr_tex)
 
 void H264EncoderImpl::add_audio(int64_t pts, vector<float> audio)
 {
+       assert(!is_shutdown);
        {
                unique_lock<mutex> lock(frame_queue_mutex);
                pending_audio_frames[pts] = move(audio);
@@ -1743,6 +1732,7 @@ void H264EncoderImpl::add_audio(int64_t pts, vector<float> audio)
 
 void H264EncoderImpl::end_frame(RefCountedGLsync fence, int64_t pts, const vector<RefCountedFrame> &input_frames)
 {
+       assert(!is_shutdown);
        {
                unique_lock<mutex> lock(frame_queue_mutex);
                pending_video_frames[current_storage_frame] = PendingFrame{ fence, input_frames, pts };
@@ -1751,6 +1741,31 @@ void H264EncoderImpl::end_frame(RefCountedGLsync fence, int64_t pts, const vecto
        frame_queue_nonempty.notify_all();
 }
 
+void H264EncoderImpl::shutdown()
+{
+       if (is_shutdown) {
+               return;
+       }
+
+       {
+               unique_lock<mutex> lock(frame_queue_mutex);
+               encode_thread_should_quit = true;
+               frame_queue_nonempty.notify_all();
+       }
+       encode_thread.join();
+       {
+               unique_lock<mutex> lock(storage_task_queue_mutex);
+               storage_thread_should_quit = true;
+               frame_queue_nonempty.notify_all();
+               storage_task_queue_changed.notify_all();
+       }
+       storage_thread.join();
+
+       release_encode();
+       deinit_va();
+       is_shutdown = true;
+}
+
 void H264EncoderImpl::encode_thread_func()
 {
        int64_t last_dts = -1;
@@ -1891,4 +1906,9 @@ void H264Encoder::end_frame(RefCountedGLsync fence, int64_t pts, const vector<Re
        impl->end_frame(fence, pts, input_frames);
 }
 
+void H264Encoder::shutdown()
+{
+       impl->shutdown();
+}
+
 // Real class.
index caf33af0c8de3d2c72af8e56dcf8d57f60ef3eb0..adf957818da9200390068f96460b4b1c335725a4 100644 (file)
@@ -50,6 +50,7 @@ public:
        void add_audio(int64_t pts, std::vector<float> audio);  // Needs to come before end_frame() of same pts.
        bool begin_frame(GLuint *y_tex, GLuint *cbcr_tex);
        void end_frame(RefCountedGLsync fence, int64_t pts, const std::vector<RefCountedFrame> &input_frames);
+       void shutdown();  // Blocking.
 
 private:
        std::unique_ptr<H264EncoderImpl> impl;