1 #ifndef __LIBRETRO_SDK_VIDEOBUFFER_H__ 2 #define __LIBRETRO_SDK_VIDEOBUFFER_H__ 3 4 #include <retro_common_api.h> 5 6 #include <boolean.h> 7 #include <stdint.h> 8 9 #ifdef RARCH_INTERNAL 10 #ifdef HAVE_CONFIG_H 11 #include "config.h" 12 #endif 13 #endif 14 15 #ifdef HAVE_SSA 16 #include <ass/ass.h> 17 #endif 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #include <libavutil/frame.h> 24 #include <libswscale/swscale.h> 25 26 #ifdef __cplusplus 27 } 28 #endif 29 30 #include <retro_miscellaneous.h> 31 32 RETRO_BEGIN_DECLS 33 34 #ifndef PIX_FMT_RGB32 35 #define PIX_FMT_RGB32 AV_PIX_FMT_RGB32 36 #endif 37 38 /** 39 * video_decoder_context 40 * 41 * Context object for the sws worker threads. 42 * 43 */ 44 struct video_decoder_context 45 { 46 int64_t pts; 47 struct SwsContext *sws; 48 AVFrame *source; 49 #if LIBAVUTIL_VERSION_MAJOR > 55 50 AVFrame *hw_source; 51 #endif 52 AVFrame *target; 53 #ifdef HAVE_SSA 54 ASS_Track *ass_track_active; 55 #endif 56 uint8_t *frame_buf; 57 int index; 58 }; 59 typedef struct video_decoder_context video_decoder_context_t; 60 61 /** 62 * video_buffer 63 * 64 * The video buffer is a ring buffer, that can be used as a 65 * buffer for many workers while keeping the order. 66 * 67 * It is thread safe in a sensem that it is designed to work 68 * with one work coordinator, that allocates work slots for 69 * workers threads to work on and later collect the work 70 * product in the same order, as the slots were allocated. 71 * 72 */ 73 struct video_buffer; 74 typedef struct video_buffer video_buffer_t; 75 76 /** 77 * video_buffer_create: 78 * @capacity : Size of the buffer. 79 * @frame_size : Size of the target frame. 80 * @width : Width of the target frame. 81 * @height : Height of the target frame. 82 * 83 * Create a video buffer. 84 * 85 * Returns: A video buffer. 86 */ 87 video_buffer_t *video_buffer_create(size_t capacity, int frame_size, int width, int height); 88 89 /** 90 * video_buffer_destroy: 91 * @video_buffer : video buffer. 92 * 93 * Destroys a video buffer. 94 * 95 * Does also free the buffer allocated with video_buffer_create(). 96 * User has to shut down any external worker threads that may have 97 * a reference to this video buffer. 98 * 99 **/ 100 void video_buffer_destroy(video_buffer_t *video_buffer); 101 102 /** 103 * video_buffer_clear: 104 * @video_buffer : video buffer. 105 * 106 * Clears a video buffer. 107 * 108 **/ 109 void video_buffer_clear(video_buffer_t *video_buffer); 110 111 /** 112 * video_buffer_get_open_slot: 113 * @video_buffer : video buffer. 114 * @context : sws context. 115 * 116 * Returns the next open context inside the ring buffer 117 * and it's index. The status of the slot will be marked as 118 * 'in progress' until slot is marked as finished with 119 * video_buffer_finish_slot(); 120 * 121 **/ 122 void video_buffer_get_open_slot(video_buffer_t *video_buffer, video_decoder_context_t **context); 123 124 /** 125 * video_buffer_return_open_slot: 126 * @video_buffer : video buffer. 127 * @context : sws context. 128 * 129 * Marks the given sws context that is "in progress" as "open" again. 130 * 131 **/ 132 void video_buffer_return_open_slot(video_buffer_t *video_buffer, video_decoder_context_t *context); 133 134 /** 135 * video_buffer_open_slot: 136 * @video_buffer : video buffer. 137 * @context : sws context. 138 * 139 * Sets the status of the given context from "finished" to "open". 140 * The slot is then available for producers to claim again with video_buffer_get_open_slot(). 141 **/ 142 void video_buffer_open_slot(video_buffer_t *video_buffer, video_decoder_context_t *context); 143 144 /** 145 * video_buffer_get_finished_slot: 146 * @video_buffer : video buffer. 147 * @context : sws context. 148 * 149 * Returns a reference for the next context inside 150 * the ring buffer. User needs to use video_buffer_open_slot() 151 * to open the slot in the ringbuffer for the next 152 * work assignment. User is free to re-allocate or 153 * re-use the context. 154 */ 155 void video_buffer_get_finished_slot(video_buffer_t *video_buffer, video_decoder_context_t **context); 156 157 /** 158 * video_buffer_finish_slot: 159 * @video_buffer : video buffer. 160 * @context : sws context. 161 * 162 * Sets the status of the given context from "in progress" to "finished". 163 * This is normally done by a producer. User can then retrieve the finished work 164 * context by calling video_buffer_get_finished_slot(). 165 */ 166 void video_buffer_finish_slot(video_buffer_t *video_buffer, video_decoder_context_t *context); 167 168 /** 169 * video_buffer_wait_for_open_slot: 170 * @video_buffer : video buffer. 171 * 172 * Blocks until open slot is available. 173 * 174 * Returns true if the buffer has a open slot available. 175 */ 176 bool video_buffer_wait_for_open_slot(video_buffer_t *video_buffer); 177 178 /** 179 * video_buffer_wait_for_finished_slot: 180 * @video_buffer : video buffer. 181 * 182 * Blocks until finished slot is available. 183 * 184 * Returns true if the buffers next slot is finished and a 185 * context available. 186 */ 187 bool video_buffer_wait_for_finished_slot(video_buffer_t *video_buffer); 188 189 /** 190 * bool video_buffer_has_open_slot(video_buffer_t *video_buffer) 191 : 192 * @video_buffer : video buffer. 193 * 194 * Returns true if the buffer has a open slot available. 195 */ 196 bool video_buffer_has_open_slot(video_buffer_t *video_buffer); 197 198 /** 199 * video_buffer_has_finished_slot: 200 * @video_buffer : video buffer. 201 * 202 * Returns true if the buffers next slot is finished and a 203 * context available. 204 */ 205 bool video_buffer_has_finished_slot(video_buffer_t *video_buffer); 206 207 RETRO_END_DECLS 208 209 #endif 210