]> git.sesse.net Git - nageru/blob - x264_dynamic.cpp
Support audio-only FFmpeg inputs. Somewhat wonky, though.
[nageru] / x264_dynamic.cpp
1 #include "x264_dynamic.h"
2
3 #include <assert.h>
4 #include <dlfcn.h>
5 #include <link.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include <string>
11
12 using namespace std;
13
14 X264Dynamic load_x264_for_bit_depth(unsigned depth)
15 {
16         X264Dynamic dyn;
17         if (unsigned(x264_bit_depth) >= depth) {
18                 // Just use the one we are linked to.
19                 dyn.handle = nullptr;
20                 dyn.x264_encoder_close = x264_encoder_close;
21                 dyn.x264_encoder_delayed_frames = x264_encoder_delayed_frames;
22                 dyn.x264_encoder_encode = x264_encoder_encode;
23                 dyn.x264_encoder_headers = x264_encoder_headers;
24                 dyn.x264_encoder_open = x264_encoder_open;
25                 dyn.x264_encoder_parameters = x264_encoder_parameters;
26                 dyn.x264_encoder_reconfig = x264_encoder_reconfig;
27                 dyn.x264_param_apply_profile = x264_param_apply_profile;
28                 dyn.x264_param_default_preset = x264_param_default_preset;
29                 dyn.x264_param_parse = x264_param_parse;
30                 dyn.x264_picture_init = x264_picture_init;
31                 return dyn;
32         }
33
34         // Uh-oh, our currently loaded library doesn't have the required support.
35         // Let's try to dynamically load a 10-bit version; in particular, Debian
36         // has a version in /usr/lib/x86_64-linux-gnu/x264-10bit/libx264.so.<soname>,
37         // so we try to figure out where our libx264 comes from, and modify that path.
38         string x264_dir, x264_suffix;
39         void *handle = dlopen(nullptr, RTLD_NOW);
40         link_map *m;
41         int err = dlinfo(handle, RTLD_DI_LINKMAP, &m);
42         assert(err != -1);
43         for ( ; m != nullptr; m = m->l_next) {
44                 if (m->l_name == nullptr) {
45                         continue;
46                 }
47                 const char *ptr = strstr(m->l_name, "/libx264.so.");
48                 if (ptr != nullptr) {
49                         x264_dir = string(m->l_name, ptr - m->l_name);
50                         x264_suffix = string(ptr, (m->l_name + strlen(m->l_name)) - ptr);
51                         break;
52                 }
53         }
54         dlclose(handle);
55
56         if (x264_dir.empty()) {
57                 fprintf(stderr, "ERROR: Requested %d-bit x264, but is not linked to such an x264, and could not find one.\n",
58                         depth);
59                 exit(1);
60         }
61
62         string x264_10b_string = x264_dir + "/x264-10bit" + x264_suffix;
63         void *x264_dlhandle = dlopen(x264_10b_string.c_str(), RTLD_NOW);
64         if (x264_dlhandle == nullptr) {
65                 fprintf(stderr, "ERROR: Requested %d-bit x264, but is not linked to such an x264, and %s would not load.\n",
66                         depth, x264_10b_string.c_str());
67                 exit(1);
68         }
69
70         dyn.handle = x264_dlhandle;
71         dyn.x264_encoder_close = (decltype(::x264_encoder_close) *)dlsym(x264_dlhandle, "x264_encoder_close");
72         dyn.x264_encoder_delayed_frames = (decltype(::x264_encoder_delayed_frames) *)dlsym(x264_dlhandle, "x264_encoder_delayed_frames");
73         dyn.x264_encoder_encode = (decltype(::x264_encoder_encode) *)dlsym(x264_dlhandle, "x264_encoder_encode");
74         dyn.x264_encoder_headers = (decltype(::x264_encoder_headers) *)dlsym(x264_dlhandle, "x264_encoder_headers");
75         char x264_encoder_open_symname[256];
76         snprintf(x264_encoder_open_symname, sizeof(x264_encoder_open_symname), "x264_encoder_open_%d", X264_BUILD);
77         dyn.x264_encoder_open = (decltype(::x264_encoder_open) *)dlsym(x264_dlhandle, x264_encoder_open_symname);
78         dyn.x264_encoder_parameters = (decltype(::x264_encoder_parameters) *)dlsym(x264_dlhandle, "x264_encoder_parameters");
79         dyn.x264_encoder_reconfig = (decltype(::x264_encoder_reconfig) *)dlsym(x264_dlhandle, "x264_encoder_reconfig");
80         dyn.x264_param_apply_profile = (decltype(::x264_param_apply_profile) *)dlsym(x264_dlhandle, "x264_param_apply_profile");
81         dyn.x264_param_default_preset = (decltype(::x264_param_default_preset) *)dlsym(x264_dlhandle, "x264_param_default_preset");
82         dyn.x264_param_parse = (decltype(::x264_param_parse) *)dlsym(x264_dlhandle, "x264_param_parse");
83         dyn.x264_picture_init = (decltype(::x264_picture_init) *)dlsym(x264_dlhandle, "x264_picture_init");
84         return dyn;
85 }