1 /*
2  * This file is part of Moonlight Embedded.
3  *
4  * Copyright (C) 2015-2017 Iwan Timmer
5  *
6  * Moonlight is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Moonlight is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Moonlight; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #define _GNU_SOURCE
21 
22 #include "platform.h"
23 
24 #include "util.h"
25 
26 #include "audio/audio.h"
27 #include "video/video.h"
28 
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <dlfcn.h>
33 
34 typedef bool(*ImxInit)();
35 
platform_check(char * name)36 enum platform platform_check(char* name) {
37   bool std = strcmp(name, "auto") == 0;
38   #ifdef HAVE_IMX
39   if (std || strcmp(name, "imx") == 0) {
40     void *handle = dlopen("libmoonlight-imx.so", RTLD_NOW | RTLD_GLOBAL);
41     ImxInit video_imx_init = (ImxInit) dlsym(RTLD_DEFAULT, "video_imx_init");
42     if (handle != NULL) {
43       if (video_imx_init())
44         return IMX;
45     }
46   }
47   #endif
48   #ifdef HAVE_PI
49   if (std || strcmp(name, "pi") == 0) {
50     void *handle = dlopen("libmoonlight-pi.so", RTLD_NOW | RTLD_GLOBAL);
51     if (handle != NULL && dlsym(RTLD_DEFAULT, "bcm_host_init") != NULL)
52       return PI;
53   }
54   #endif
55   #ifdef HAVE_AML
56   if (std || strcmp(name, "aml") == 0) {
57     void *handle = dlopen("libmoonlight-aml.so", RTLD_NOW | RTLD_GLOBAL);
58     if (handle != NULL && access("/dev/amvideo", F_OK) != -1)
59       return AML;
60   }
61   #endif
62   #ifdef HAVE_ROCKCHIP
63   if (std || strcmp(name, "rk") == 0) {
64     void *handle = dlopen("libmoonlight-rk.so", RTLD_NOW | RTLD_GLOBAL);
65     if (handle != NULL && dlsym(RTLD_DEFAULT, "mpp_init") != NULL)
66       return RK;
67   }
68   #endif
69   #ifdef HAVE_X11
70   bool x11 = strcmp(name, "x11") == 0;
71   bool vdpau = strcmp(name, "x11_vdpau") == 0;
72   bool vaapi = strcmp(name, "x11_vaapi") == 0;
73   if (std || x11 || vdpau || vaapi) {
74     int init = x11_init(std || vdpau, std || vaapi);
75     #ifdef HAVE_VAAPI
76     if (init == INIT_VAAPI)
77       return X11_VAAPI;
78     #endif
79     #ifdef HAVE_VDPAU
80     if (init == INIT_VDPAU)
81       return X11_VDPAU;
82     #endif
83     return X11;
84   }
85   #endif
86   #ifdef HAVE_SDL
87   if (std || strcmp(name, "sdl") == 0)
88     return SDL;
89   #endif
90   if (strcmp(name, "fake") == 0)
91     return FAKE;
92 
93   return 0;
94 }
95 
platform_start(enum platform system)96 void platform_start(enum platform system) {
97   switch (system) {
98   #ifdef HAVE_AML
99   case AML:
100     blank_fb("/sys/class/graphics/fb0/blank", true);
101     blank_fb("/sys/class/graphics/fb1/blank", true);
102     break;
103   #endif
104   #ifdef HAVE_PI
105   case PI:
106     blank_fb("/sys/class/graphics/fb0/blank", true);
107     break;
108   #endif
109   }
110 }
111 
platform_stop(enum platform system)112 void platform_stop(enum platform system) {
113   switch (system) {
114   #ifdef HAVE_AML
115   case AML:
116     blank_fb("/sys/class/graphics/fb0/blank", false);
117     blank_fb("/sys/class/graphics/fb1/blank", false);
118     break;
119   #endif
120   #ifdef HAVE_PI
121   case PI:
122     blank_fb("/sys/class/graphics/fb0/blank", false);
123     break;
124   #endif
125   }
126 }
127 
platform_get_video(enum platform system)128 DECODER_RENDERER_CALLBACKS* platform_get_video(enum platform system) {
129   switch (system) {
130   #ifdef HAVE_X11
131   case X11:
132     return &decoder_callbacks_x11;
133   #ifdef HAVE_VAAPI
134   case X11_VAAPI:
135     return &decoder_callbacks_x11_vaapi;
136   #endif
137   #ifdef HAVE_VDPAU
138   case X11_VDPAU:
139     return &decoder_callbacks_x11_vdpau;
140   #endif
141   #endif
142   #ifdef HAVE_SDL
143   case SDL:
144     return &decoder_callbacks_sdl;
145   #endif
146   #ifdef HAVE_IMX
147   case IMX:
148     return (PDECODER_RENDERER_CALLBACKS) dlsym(RTLD_DEFAULT, "decoder_callbacks_imx");
149   #endif
150   #ifdef HAVE_PI
151   case PI:
152     return (PDECODER_RENDERER_CALLBACKS) dlsym(RTLD_DEFAULT, "decoder_callbacks_pi");
153   #endif
154   #ifdef HAVE_AML
155   case AML:
156     return (PDECODER_RENDERER_CALLBACKS) dlsym(RTLD_DEFAULT, "decoder_callbacks_aml");
157   #endif
158   #ifdef HAVE_ROCKCHIP
159   case RK:
160     return (PDECODER_RENDERER_CALLBACKS) dlsym(RTLD_DEFAULT, "decoder_callbacks_rk");
161   #endif
162   }
163   return NULL;
164 }
165 
platform_get_audio(enum platform system,char * audio_device)166 AUDIO_RENDERER_CALLBACKS* platform_get_audio(enum platform system, char* audio_device) {
167   switch (system) {
168   #ifdef HAVE_SDL
169   case SDL:
170     return &audio_callbacks_sdl;
171   #endif
172   #ifdef HAVE_PI
173   case PI:
174     if (audio_device == NULL || strcmp(audio_device, "local") == 0 || strcmp(audio_device, "hdmi") == 0)
175       return (PAUDIO_RENDERER_CALLBACKS) dlsym(RTLD_DEFAULT, "audio_callbacks_omx");
176   #endif
177   }
178   return NULL;
179 }
180 
platform_supports_hevc(enum platform system)181 bool platform_supports_hevc(enum platform system) {
182   switch (system) {
183   case AML:
184   case RK:
185     return true;
186   }
187   return false;
188 }
189 
platform_name(enum platform system)190 char* platform_name(enum platform system) {
191   switch(system) {
192   case PI:
193     return "Raspberry Pi (Broadcom)";
194   case IMX:
195     return "i.MX6 (MXC Vivante)";
196   case AML:
197     return "AMLogic VPU";
198   case RK:
199     return "Rockchip VPU";
200   case X11:
201     return "X Window System (software decoding)";
202   case X11_VAAPI:
203     return "X Window System (VAAPI)";
204   case X11_VDPAU:
205     return "X Window System (VDPAU)";
206   case SDL:
207     return "SDL2 (software decoding)";
208   case FAKE:
209     return "Fake (no a/v output)";
210   default:
211     return "Unknown";
212   }
213 }
214