]> git.sesse.net Git - nageru/commitdiff
Add support for opening VA-API via DRM instead of X11.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 7 Feb 2016 17:03:59 +0000 (18:03 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 7 Feb 2016 17:03:59 +0000 (18:03 +0100)
flags.cpp
flags.h
h264encode.cpp
h264encode.h
mixer.cpp

index 56ca799cea36967d95a55bb79086659c8870c602..21e71e99208765ee1122e6900fa3464f98b3839a 100644 (file)
--- a/flags.cpp
+++ b/flags.cpp
@@ -10,6 +10,7 @@ void parse_flags(int argc, char * const argv[])
 {
        static const option long_options[] = {
                { "num-cards", required_argument, 0, 'c' },
+               { "va-display", required_argument, 0, 1000 },
                { 0, 0, 0, 0 }
        };
        for ( ;; ) {
@@ -23,6 +24,9 @@ void parse_flags(int argc, char * const argv[])
                case 'c':
                        global_flags.num_cards = atoi(optarg);
                        break;
+               case 1000:
+                       global_flags.va_display = optarg;
+                       break;
                default:
                        fprintf(stderr, "Unknown option '%s'\n", argv[option_index]);
                        exit(1);
diff --git a/flags.h b/flags.h
index bfb51daca0cfcea3bef6c6b7d957e880a65d3fe8..52a9a50dff680c0a71f2dd208e86620396dd7342 100644 (file)
--- a/flags.h
+++ b/flags.h
@@ -1,8 +1,11 @@
 #ifndef _FLAGS_H
 #define _FLAGS_H
 
+#include <string>
+
 struct Flags {
        int num_cards = 2;
+       std::string va_display;
 };
 extern Flags global_flags;
 
index 78e34474b80e07a397c41dbaf3a0cf70d1807a3d..e8087adc6f21134161c65f35d1bf305afc1fb4f1 100644 (file)
@@ -18,7 +18,9 @@ extern "C" {
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
 #include <va/va.h>
+#include <va/va_drm.h>
 #include <va/va_drmcommon.h>
 #include <va/va_enc_h264.h>
 #include <va/va_x11.h>
@@ -108,7 +110,7 @@ using namespace std;
 
 class H264EncoderImpl {
 public:
-       H264EncoderImpl(QSurface *surface, int width, int height, HTTPD *httpd);
+       H264EncoderImpl(QSurface *surface, const string &va_display, int width, int height, HTTPD *httpd);
        ~H264EncoderImpl();
        void add_audio(int64_t pts, vector<float> audio);
        bool begin_frame(GLuint *y_tex, GLuint *cbcr_tex);
@@ -147,9 +149,9 @@ private:
        void slice_header(bitstream *bs);
        int build_packed_seq_buffer(unsigned char **header_buffer);
        int build_packed_slice_buffer(unsigned char **header_buffer);
-       int init_va();
+       int init_va(const string &va_display);
        int deinit_va();
-       VADisplay va_open_display(void);
+       VADisplay va_open_display(const string &va_display);
        void va_close_display(VADisplay va_dpy);
        int setup_encode();
        int release_encode();
@@ -157,6 +159,8 @@ private:
        int update_RefPicList(int frame_type);
 
        bool is_shutdown = false;
+       bool use_drm;
+       int drm_fd = -1;
 
        thread encode_thread, storage_thread;
 
@@ -831,14 +835,33 @@ static const char *rc_to_string(int rc_mode)
     }
 }
 
-VADisplay H264EncoderImpl::va_open_display(void)
+VADisplay H264EncoderImpl::va_open_display(const string &va_display)
 {
-    x11_display = XOpenDisplay(NULL);
-    if (!x11_display) {
-        fprintf(stderr, "error: can't connect to X server!\n");
-        return NULL;
-    }
-    return vaGetDisplay(x11_display);
+       if (va_display.empty()) {
+               x11_display = XOpenDisplay(NULL);
+               if (!x11_display) {
+                       fprintf(stderr, "error: can't connect to X server!\n");
+                       return NULL;
+               }
+               use_drm = false;
+               return vaGetDisplay(x11_display);
+       } else if (va_display[0] != '/') {
+               x11_display = XOpenDisplay(va_display.c_str());
+               if (!x11_display) {
+                       fprintf(stderr, "error: can't connect to X server!\n");
+                       return NULL;
+               }
+               use_drm = false;
+               return vaGetDisplay(x11_display);
+       } else {
+               drm_fd = open(va_display.c_str(), O_RDWR);
+               if (drm_fd == -1) {
+                       perror(va_display.c_str());
+                       return NULL;
+               }
+               use_drm = true;
+               return vaGetDisplayDRM(drm_fd);
+       }
 }
 
 void H264EncoderImpl::va_close_display(VADisplay va_dpy)
@@ -855,7 +878,7 @@ void H264EncoderImpl::va_close_display(VADisplay va_dpy)
     x11_display = NULL;
 }
 
-int H264EncoderImpl::init_va()
+int H264EncoderImpl::init_va(const string &va_display)
 {
     VAProfile profile_list[]={VAProfileH264High, VAProfileH264Main, VAProfileH264Baseline, VAProfileH264ConstrainedBaseline};
     VAEntrypoint *entrypoints;
@@ -865,7 +888,7 @@ int H264EncoderImpl::init_va()
     VAStatus va_status;
     unsigned int i;
 
-    va_dpy = va_open_display();
+    va_dpy = va_open_display(va_display);
     va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
     CHECK_VASTATUS(va_status, "vaInitialize");
 
@@ -1606,7 +1629,7 @@ int H264EncoderImpl::deinit_va()
 }
 
 
-H264EncoderImpl::H264EncoderImpl(QSurface *surface, int width, int height, HTTPD *httpd)
+H264EncoderImpl::H264EncoderImpl(QSurface *surface, const string &va_display, int width, int height, HTTPD *httpd)
        : current_storage_frame(0), surface(surface), httpd(httpd)
 {
        AVCodec *codec_audio = avcodec_find_encoder(AUDIO_OUTPUT_CODEC);
@@ -1629,7 +1652,7 @@ H264EncoderImpl::H264EncoderImpl(QSurface *surface, int width, int height, HTTPD
 
        //print_input();
 
-       init_va();
+       init_va(va_display);
        setup_encode();
 
        // No frames are ready yet.
@@ -1889,8 +1912,8 @@ void H264EncoderImpl::encode_frame(H264EncoderImpl::PendingFrame frame, int enco
 }
 
 // Proxy object.
-H264Encoder::H264Encoder(QSurface *surface, int width, int height, HTTPD *httpd)
-       : impl(new H264EncoderImpl(surface, width, height, httpd)) {}
+H264Encoder::H264Encoder(QSurface *surface, const string &va_display, int width, int height, HTTPD *httpd)
+       : impl(new H264EncoderImpl(surface, va_display, width, height, httpd)) {}
 
 // Must be defined here because unique_ptr<> destructor needs to know the impl.
 H264Encoder::~H264Encoder() {}
index f0fcfae0309828b1fbe4826e6dd1d186a1e92ed8..0d70524e76d5a73d01977e1852a434a59280e947 100644 (file)
@@ -30,6 +30,7 @@
 #include <stdint.h>
 #include <atomic>
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "ref_counted_frame.h"
@@ -44,7 +45,7 @@ class QSurface;
 // .cpp file.
 class H264Encoder {
 public:
-        H264Encoder(QSurface *surface, int width, int height, HTTPD *httpd);
+        H264Encoder(QSurface *surface, const std::string &va_display, int width, int height, HTTPD *httpd);
         ~H264Encoder();
 
        void add_audio(int64_t pts, std::vector<float> audio);
index 16a07540d442097deab64bcc60a094d47a31e5ce..b3950a1c829f7f7ebfd7ab355af8488597a56350 100644 (file)
--- a/mixer.cpp
+++ b/mixer.cpp
@@ -30,6 +30,7 @@
 #include "bmusb/bmusb.h"
 #include "context.h"
 #include "defs.h"
+#include "flags.h"
 #include "h264encode.h"
 #include "pbo_frame_allocator.h"
 #include "ref_counted_gl_sync.h"
@@ -132,7 +133,7 @@ Mixer::Mixer(const QSurfaceFormat &format, unsigned num_cards)
        display_chain->set_dither_bits(0);  // Don't bother.
        display_chain->finalize();
 
-       h264_encoder.reset(new H264Encoder(h264_encoder_surface, WIDTH, HEIGHT, &httpd));
+       h264_encoder.reset(new H264Encoder(h264_encoder_surface, global_flags.va_display, WIDTH, HEIGHT, &httpd));
 
        for (unsigned card_index = 0; card_index < num_cards; ++card_index) {
                printf("Configuring card %d...\n", card_index);
@@ -675,7 +676,7 @@ void Mixer::thread_func()
                        h264_encoder->shutdown();
                        httpd.close_output_file();
                        httpd.open_output_file(filename.c_str());
-                       h264_encoder.reset(new H264Encoder(h264_encoder_surface, WIDTH, HEIGHT, &httpd));
+                       h264_encoder.reset(new H264Encoder(h264_encoder_surface, global_flags.va_display, WIDTH, HEIGHT, &httpd));
                }
 
 #if 0