1 /************************************************************************** 2 * 3 * Copyright 2013 Advanced Micro Devices, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* 29 * Authors: 30 * Christian Knig <christian.koenig (at) amd.com> 31 * 32 */ 33 34 #include <assert.h> 35 #include <string.h> 36 #include <stdbool.h> 37 38 #if defined(HAVE_X11_PLATFORM) 39 #include <X11/Xlib.h> 40 #else 41 #define XOpenDisplay(x) NULL 42 #define XCloseDisplay(x) 43 #define Display void 44 #endif 45 46 #include "os/os_thread.h" 47 #include "util/u_memory.h" 48 #include "loader/loader.h" 49 50 #include "entrypoint.h" 51 #include "vid_dec.h" 52 #include "vid_enc.h" 53 54 static mtx_t omx_lock = _MTX_INITIALIZER_NP; 55 static Display *omx_display = NULL; 56 static struct vl_screen *omx_screen = NULL; 57 static unsigned omx_usecount = 0; 58 static const char *omx_render_node = NULL; 59 static int drm_fd; 60 61 int omx_component_library_Setup(stLoaderComponentType **stComponents) 62 { 63 OMX_ERRORTYPE r; 64 65 if (stComponents == NULL) 66 return 2; 67 68 /* component 0 - video decoder */ 69 r = vid_dec_LoaderComponent(stComponents[0]); 70 if (r != OMX_ErrorNone) 71 return OMX_ErrorInsufficientResources; 72 73 /* component 1 - video encoder */ 74 r = vid_enc_LoaderComponent(stComponents[1]); 75 if (r != OMX_ErrorNone) 76 return OMX_ErrorInsufficientResources; 77 78 return 2; 79 } 80 81 struct vl_screen *omx_get_screen(void) 82 { 83 static bool first_time = true; 84 mtx_lock(&omx_lock); 85 86 if (!omx_screen) { 87 if (first_time) { 88 omx_render_node = debug_get_option("OMX_RENDER_NODE", NULL); 89 first_time = false; 90 } 91 if (omx_render_node) { 92 drm_fd = loader_open_device(omx_render_node); 93 if (drm_fd < 0) 94 goto error; 95 96 omx_screen = vl_drm_screen_create(drm_fd); 97 if (!omx_screen) { 98 close(drm_fd); 99 goto error; 100 } 101 } else { 102 omx_display = XOpenDisplay(NULL); 103 if (!omx_display) 104 goto error; 105 106 omx_screen = vl_dri3_screen_create(omx_display, 0); 107 if (!omx_screen) 108 omx_screen = vl_dri2_screen_create(omx_display, 0); 109 if (!omx_screen) { 110 XCloseDisplay(omx_display); 111 goto error; 112 } 113 } 114 } 115 116 ++omx_usecount; 117 118 mtx_unlock(&omx_lock); 119 return omx_screen; 120 121 error: 122 mtx_unlock(&omx_lock); 123 return NULL; 124 } 125 126 void omx_put_screen(void) 127 { 128 mtx_lock(&omx_lock); 129 if ((--omx_usecount) == 0) { 130 omx_screen->destroy(omx_screen); 131 omx_screen = NULL; 132 133 if (omx_render_node) 134 close(drm_fd); 135 else 136 XCloseDisplay(omx_display); 137 } 138 mtx_unlock(&omx_lock); 139 } 140 141 OMX_ERRORTYPE omx_workaround_Destructor(OMX_COMPONENTTYPE *comp) 142 { 143 omx_base_component_PrivateType* priv = (omx_base_component_PrivateType*)comp->pComponentPrivate; 144 145 priv->state = OMX_StateInvalid; 146 tsem_up(priv->messageSem); 147 148 /* wait for thread to exit */ 149 pthread_join(priv->messageHandlerThread, NULL); 150 151 return omx_base_component_Destructor(comp); 152 } 153