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 #include <X11/Xlib.h> 39 40 #include "os/os_thread.h" 41 #include "util/u_memory.h" 42 #include "loader/loader.h" 43 44 #include "entrypoint.h" 45 #include "vid_dec.h" 46 #include "vid_enc.h" 47 48 pipe_static_mutex(omx_lock); 49 static Display *omx_display = NULL; 50 static struct vl_screen *omx_screen = NULL; 51 static unsigned omx_usecount = 0; 52 static const char *omx_render_node = NULL; 53 static int drm_fd; 54 55 int omx_component_library_Setup(stLoaderComponentType **stComponents) 56 { 57 OMX_ERRORTYPE r; 58 59 if (stComponents == NULL) 60 return 2; 61 62 /* component 0 - video decoder */ 63 r = vid_dec_LoaderComponent(stComponents[0]); 64 if (r != OMX_ErrorNone) 65 return OMX_ErrorInsufficientResources; 66 67 /* component 1 - video encoder */ 68 r = vid_enc_LoaderComponent(stComponents[1]); 69 if (r != OMX_ErrorNone) 70 return OMX_ErrorInsufficientResources; 71 72 return 2; 73 } 74 75 struct vl_screen *omx_get_screen(void) 76 { 77 static bool first_time = true; 78 pipe_mutex_lock(omx_lock); 79 80 if (!omx_screen) { 81 if (first_time) { 82 omx_render_node = debug_get_option("OMX_RENDER_NODE", NULL); 83 first_time = false; 84 } 85 if (omx_render_node) { 86 drm_fd = loader_open_device(omx_render_node); 87 if (drm_fd < 0) 88 goto error; 89 90 omx_screen = vl_drm_screen_create(drm_fd); 91 if (!omx_screen) { 92 close(drm_fd); 93 goto error; 94 } 95 } else { 96 omx_display = XOpenDisplay(NULL); 97 if (!omx_display) 98 goto error; 99 100 omx_screen = vl_dri2_screen_create(omx_display, 0); 101 if (!omx_screen) { 102 XCloseDisplay(omx_display); 103 goto error; 104 } 105 } 106 } 107 108 ++omx_usecount; 109 110 pipe_mutex_unlock(omx_lock); 111 return omx_screen; 112 113 error: 114 pipe_mutex_unlock(omx_lock); 115 return NULL; 116 } 117 118 void omx_put_screen(void) 119 { 120 pipe_mutex_lock(omx_lock); 121 if ((--omx_usecount) == 0) { 122 omx_screen->destroy(omx_screen); 123 omx_screen = NULL; 124 125 if (omx_render_node) 126 close(drm_fd); 127 else 128 XCloseDisplay(omx_display); 129 } 130 pipe_mutex_unlock(omx_lock); 131 } 132 133 OMX_ERRORTYPE omx_workaround_Destructor(OMX_COMPONENTTYPE *comp) 134 { 135 omx_base_component_PrivateType* priv = (omx_base_component_PrivateType*)comp->pComponentPrivate; 136 137 priv->state = OMX_StateInvalid; 138 tsem_up(priv->messageSem); 139 140 /* wait for thread to exit */ 141 pthread_join(priv->messageHandlerThread, NULL); 142 143 return omx_base_component_Destructor(comp); 144 } 145