]> git.sesse.net Git - nageru/blobdiff - h264encode.cpp
Tiny alias cleanup.
[nageru] / h264encode.cpp
index db68418c9fd3fbc96b292cce141cbfae68931b7f..913c8886ab52e22305d0cc0224887fac8365b38c 100644 (file)
@@ -1,6 +1,7 @@
 //#include "sysdeps.h"
 #include "h264encode.h"
 
+#include <movit/util.h>
 #include <EGL/eglplatform.h>
 #include <X11/X.h>
 #include <X11/Xlib.h>
@@ -51,6 +52,8 @@ class QSurface;
         exit(1);                                                        \
     }
 
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
 //#include "loadsurface.h"
 
 #define NAL_REF_IDC_NONE        0
@@ -202,9 +205,9 @@ private:
                EGLImage y_egl_image, cbcr_egl_image;
 
                // Only if use_zerocopy == false.
-               RefCountedGLsync readback_done_fence;
                GLuint pbo;
                uint8_t *y_ptr, *cbcr_ptr;
+               size_t y_offset, cbcr_offset;
        };
        GLSurface gl_surfaces[SURFACE_NUM];
 
@@ -921,7 +924,7 @@ int H264EncoderImpl::init_va(const string &va_display)
     
     if (support_encode == 0) {
         printf("Can't find VAEntrypointEncSlice for H264 profiles. If you are using a non-Intel GPU\n");
-        printf("but have one in your system, try launching Nageru with --va-display /dev/dri/card0\n");
+        printf("but have one in your system, try launching Nageru with --va-display /dev/dri/renderD128\n");
         printf("to use VA-API against DRM instead of X11.\n");
         exit(1);
     } else {
@@ -1106,10 +1109,12 @@ int H264EncoderImpl::setup_encode()
             // buffers, due to potentially differing pitch.
             glGenBuffers(1, &gl_surfaces[i].pbo);
             glBindBuffer(GL_PIXEL_PACK_BUFFER, gl_surfaces[i].pbo);
-            glBufferStorage(GL_PIXEL_PACK_BUFFER, frame_width * frame_height * 2, nullptr, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
+            glBufferStorage(GL_PIXEL_PACK_BUFFER, frame_width * frame_height * 2, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
             uint8_t *ptr = (uint8_t *)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, frame_width * frame_height * 2, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
-            gl_surfaces[i].y_ptr = ptr;
-            gl_surfaces[i].cbcr_ptr = ptr + frame_width * frame_height;
+            gl_surfaces[i].y_offset = 0;
+            gl_surfaces[i].cbcr_offset = frame_width * frame_height;
+            gl_surfaces[i].y_ptr = ptr + gl_surfaces[i].y_offset;
+            gl_surfaces[i].cbcr_ptr = ptr + gl_surfaces[i].cbcr_offset;
             glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
         }
     }
@@ -1533,7 +1538,7 @@ void H264EncoderImpl::save_codeddata(storage_task task)
              pending_audio_frames.erase(it); 
         }
 
-        AVFrame *frame = avcodec_alloc_frame();
+        AVFrame *frame = av_frame_alloc();
         frame->nb_samples = audio.size() / 2;
         frame->format = AV_SAMPLE_FMT_S32;
         frame->channel_layout = AV_CH_LAYOUT_STEREO;
@@ -1565,7 +1570,7 @@ void H264EncoderImpl::save_codeddata(storage_task task)
             httpd->add_packet(pkt, audio_pts + global_delay, audio_pts + global_delay);
         }
         // TODO: Delayed frames.
-        avcodec_free_frame(&frame);
+        av_frame_unref(frame);
         av_free_packet(&pkt);
         if (audio_pts == task.pts) break;
     }
@@ -1796,18 +1801,32 @@ void H264EncoderImpl::end_frame(RefCountedGLsync fence, int64_t pts, const vecto
 
        if (!use_zerocopy) {
                GLSurface *surf = &gl_surfaces[current_storage_frame % SURFACE_NUM];
+
                glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+               check_error();
+
+               glBindBuffer(GL_PIXEL_PACK_BUFFER, surf->pbo);
+               check_error();
 
                glBindTexture(GL_TEXTURE_2D, surf->y_tex);
-               glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, surf->y_ptr);
+               check_error();
+               glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, BUFFER_OFFSET(surf->y_offset));
+               check_error();
 
                glBindTexture(GL_TEXTURE_2D, surf->cbcr_tex);
-               glGetTexImage(GL_TEXTURE_2D, 0, GL_RG, GL_UNSIGNED_BYTE, surf->cbcr_ptr);
+               check_error();
+               glGetTexImage(GL_TEXTURE_2D, 0, GL_RG, GL_UNSIGNED_BYTE, BUFFER_OFFSET(surf->cbcr_offset));
+               check_error();
 
                glBindTexture(GL_TEXTURE_2D, 0);
+               check_error();
+               glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+               check_error();
 
-               glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
+               glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT | GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
+               check_error();
                fence = RefCountedGLsync(GL_SYNC_GPU_COMMANDS_COMPLETE, /*flags=*/0);
+               check_error();
        }
 
        {
@@ -1930,7 +1949,12 @@ void H264EncoderImpl::encode_frame(H264EncoderImpl::PendingFrame frame, int enco
                                    int frame_type, int64_t pts, int64_t dts)
 {
        // Wait for the GPU to be done with the frame.
-       glClientWaitSync(frame.fence.get(), 0, 0);
+       GLenum sync_status;
+       do {
+               sync_status = glClientWaitSync(frame.fence.get(), 0, 1000000000);
+               check_error();
+       } while (sync_status == GL_TIMEOUT_EXPIRED);
+       assert(sync_status != GL_WAIT_FAILED);
 
        // Release back any input frames we needed to render this frame.
        frame.input_frames.clear();
@@ -1947,11 +1971,11 @@ void H264EncoderImpl::encode_frame(H264EncoderImpl::PendingFrame frame, int enco
                unsigned char *surface_p = nullptr;
                vaMapBuffer(va_dpy, surf->surface_image.buf, (void **)&surface_p);
 
-               unsigned char *y_ptr = (unsigned char *)surface_p;
-               memcpy_with_pitch(y_ptr, surf->y_ptr, frame_width, surf->surface_image.pitches[0], frame_height);
+               unsigned char *va_y_ptr = (unsigned char *)surface_p + surf->surface_image.offsets[0];
+               memcpy_with_pitch(va_y_ptr, surf->y_ptr, frame_width, surf->surface_image.pitches[0], frame_height);
 
-               unsigned char *cbcr_ptr = (unsigned char *)surface_p + surf->surface_image.offsets[1];
-               memcpy_with_pitch(cbcr_ptr, surf->cbcr_ptr, (frame_width / 2) * sizeof(uint16_t), surf->surface_image.pitches[1], frame_height / 2);
+               unsigned char *va_cbcr_ptr = (unsigned char *)surface_p + surf->surface_image.offsets[1];
+               memcpy_with_pitch(va_cbcr_ptr, surf->cbcr_ptr, (frame_width / 2) * sizeof(uint16_t), surf->surface_image.pitches[1], frame_height / 2);
 
                va_status = vaUnmapBuffer(va_dpy, surf->surface_image.buf);
                CHECK_VASTATUS(va_status, "vaUnmapBuffer");