]> git.sesse.net Git - nageru/blobdiff - nageru/mjpeg_encoder.cpp
On errors, abort() instead of exit(1); exit() in a multithreaded program just gives...
[nageru] / nageru / mjpeg_encoder.cpp
index d66ef1438a1ae24a973add5defcde6c386ec0fcc..46bb94c7639112f76b031c96c63acab9560b99ce 100644 (file)
@@ -131,7 +131,7 @@ MJPEGEncoder::MJPEGEncoder(HTTPD *httpd, const string &va_display)
                AVStream *stream = avformat_new_stream(avctx.get(), nullptr);
                if (stream == nullptr) {
                        fprintf(stderr, "avformat_new_stream() failed\n");
-                       exit(1);
+                       abort();
                }
                stream->time_base = AVRational{ 1, TIMEBASE };
                stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -159,7 +159,7 @@ MJPEGEncoder::MJPEGEncoder(HTTPD *httpd, const string &va_display)
        }
        if (avformat_write_header(avctx.get(), &options) < 0) {
                fprintf(stderr, "avformat_write_header() failed\n");
-               exit(1);
+               abort();
        }
 
        // Initialize VA-API.
@@ -304,19 +304,6 @@ void MJPEGEncoder::upload_frame(int64_t pts, unsigned card_index, RefCountedFram
        any_frames_to_be_encoded.notify_all();
 }
 
-void MJPEGEncoder::finish_frame(RefCountedFrame frame)
-{
-       PBOFrameAllocator::Userdata *userdata = (PBOFrameAllocator::Userdata *)frame->userdata;
-
-       if (userdata->data_copy_current_src == PBOFrameAllocator::Userdata::FROM_VA_API) {
-               VAResources resources __attribute__((unused)) = move(userdata->va_resources);
-               ReleaseVAResources release = move(userdata->va_resources_release);
-
-               VAStatus va_status = vaUnmapBuffer(va_dpy->va_dpy, resources.image.buf);
-               CHECK_VASTATUS(va_status, "vaUnmapBuffer");
-       }
-}
-
 int MJPEGEncoder::get_mjpeg_stream_for_card(unsigned card_index)
 {
        // Only bother doing MJPEG encoding if there are any connected clients
@@ -380,7 +367,7 @@ void MJPEGEncoder::write_mjpeg_packet(int64_t pts, unsigned card_index, const ui
 
        if (av_write_frame(avctx.get(), &pkt) < 0) {
                fprintf(stderr, "av_write_frame() failed\n");
-               exit(1);
+               abort();
        }
 }
 
@@ -456,6 +443,9 @@ void MJPEGEncoder::release_va_resources(MJPEGEncoder::VAResources resources)
                va_status = vaDestroySurfaces(va_dpy->va_dpy, &it->surface, 1);
                CHECK_VASTATUS(va_status, "vaDestroySurfaces");
 
+               va_status = vaDestroyImage(va_dpy->va_dpy, it->image.image_id);
+               CHECK_VASTATUS(va_status, "vaDestroyImage");
+
                va_resources_freelist.erase(it);
        }
 
@@ -677,9 +667,9 @@ void MJPEGEncoder::encode_jpeg_va(QueuedFrame &&qf)
        VABufferDestroyer destroy_slice_param(va_dpy->va_dpy, slice_param_buffer);
 
        if (userdata->data_copy_current_src == PBOFrameAllocator::Userdata::FROM_VA_API) {
+               // The pixel data is already put into the image by the caller.
                va_status = vaUnmapBuffer(va_dpy->va_dpy, resources.image.buf);
                CHECK_VASTATUS(va_status, "vaUnmapBuffer");
-               // The pixel data is already put into the image by the caller.
        } else {
                assert(userdata->data_copy_current_src == PBOFrameAllocator::Userdata::FROM_MALLOC);
 
@@ -700,6 +690,8 @@ void MJPEGEncoder::encode_jpeg_va(QueuedFrame &&qf)
                CHECK_VASTATUS(va_status, "vaUnmapBuffer");
        }
 
+       qf.frame->data_copy = nullptr;
+
        // Seemingly vaPutImage() (which triggers a GPU copy) is much nicer to the
        // CPU than vaDeriveImage() and copying directly into the GPU's buffers.
        // Exactly why is unclear, but it seems to involve L3 cache usage when there