UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
gpujpeg_to_dxt.cpp File Reference
#include "cuda_dxt/cuda_dxt.h"
#include <pthread.h>
#include <stdlib.h>
#include "libgpujpeg/gpujpeg_decoder.h"
#include "libgpujpeg/gpujpeg_version.h"
#include "debug.h"
#include "lib_common.h"
#include "host.h"
#include "utils/synchronized_queue.h"
#include "video.h"
#include "video_decompress.h"
Include dependency graph for gpujpeg_to_dxt.cpp:

Go to the source code of this file.

Macros

#define MOD_NAME   "[GPUJPEG to DXT] "
 

Functions

static void flush (struct state_decompresss_gpujpeg_to_dxt *s)
 
static decompress_status gpujpeg_to_dxt_decompress (void *state, unsigned char *dst, unsigned char *buffer, unsigned int src_len, int frame_seq, video_frame_callbacks *, codec_t *)
 
static void gpujpeg_to_dxt_decompress_done (void *state)
 
static int gpujpeg_to_dxt_decompress_get_priority (codec_t compression, struct pixfmt_desc internal, codec_t ugc)
 
static int gpujpeg_to_dxt_decompress_get_property (void *state, int property, void *val, size_t *len)
 
static void * gpujpeg_to_dxt_decompress_init (void)
 
static int gpujpeg_to_dxt_decompress_reconfigure (void *state, struct video_desc desc, int rshift, int gshift, int bshift, int pitch, codec_t out_codec)
 
static int reconfigure_thread (struct thread_data *s, struct video_desc desc, int ppb)
 
 REGISTER_MODULE (gpujpeg_to_dxt, &gpujpeg_to_dxt_info, LIBRARY_CLASS_VIDEO_DECOMPRESS, VIDEO_DECOMPRESS_ABI_VERSION)
 
static void * worker_thread (void *arg)
 

Variables

static const struct video_decompress_info gpujpeg_to_dxt_info
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file gpujpeg_to_dxt.cpp.

Macro Definition Documentation

◆ MOD_NAME

#define MOD_NAME   "[GPUJPEG to DXT] "

Definition at line 59 of file gpujpeg_to_dxt.cpp.

Referenced by gpujpeg_to_dxt_decompress_init(), and worker_thread().

Function Documentation

◆ flush()

static void flush ( struct state_decompresss_gpujpeg_to_dxt * s)
static

Definition at line 210 of file gpujpeg_to_dxt.cpp.

211{
212 if (s->occupied_count > 0) {
213 for (unsigned int i = 0; i < cuda_devices_count; ++i) {
214 if (i == s->free)
215 continue;
216 struct msg_frame *completed =
217 dynamic_cast<msg_frame *>(s->thread_data[(s->free+1)%cuda_devices_count].m_out.pop());
218 delete completed;
219 }
220 s->occupied_count = 0;
221 }
222 s->free = 0;
223}
unsigned int cuda_devices_count
Definition host.cpp:168

References cuda_devices_count.

Referenced by gpujpeg_to_dxt_decompress_done(), and gpujpeg_to_dxt_decompress_reconfigure().

◆ gpujpeg_to_dxt_decompress()

static decompress_status gpujpeg_to_dxt_decompress ( void * state,
unsigned char * dst,
unsigned char * buffer,
unsigned int src_len,
int frame_seq,
video_frame_callbacks * ,
codec_t *  )
static

Definition at line 308 of file gpujpeg_to_dxt.cpp.

310{
311 struct state_decompresss_gpujpeg_to_dxt *s = (struct state_decompresss_gpujpeg_to_dxt *) state;
312 UNUSED(frame_seq);
313
314 msg_frame *message = new msg_frame(src_len);
315 memcpy(message->data, buffer, src_len);
316
317 if(s->occupied_count < cuda_devices_count - 1) {
318 s->thread_data[s->free].m_in.push(message);
319 s->free = s->free + 1; // should not exceed cuda_device_count
320 s->occupied_count += 1;
321 } else {
322 s->thread_data[s->free].m_in.push(message);
323
324 s->free = (s->free + 1) % cuda_devices_count;
325
326 struct msg_frame *completed =
327 dynamic_cast<msg_frame *>(s->thread_data[s->free].m_out.pop());
328 assert(completed != NULL);
329 memcpy(dst, completed->data, s->desc.width * s->desc.height / s->ppb);
330
331 delete completed;
332 }
333
334 return DECODER_GOT_FRAME;
335}
#define UNUSED(x)
void ** state
@ DECODER_GOT_FRAME
unsigned int width
width of every tile (!)
Definition types.h:179
unsigned int height
height of every tile (!)
Definition types.h:180

References cuda_devices_count, DECODER_GOT_FRAME, video_desc::height, state, UNUSED, and video_desc::width.

◆ gpujpeg_to_dxt_decompress_done()

static void gpujpeg_to_dxt_decompress_done ( void * state)
static

Definition at line 347 of file gpujpeg_to_dxt.cpp.

348{
349 struct state_decompresss_gpujpeg_to_dxt *s = (struct state_decompresss_gpujpeg_to_dxt *) state;
350
351 if(!state) {
352 return;
353 }
354
355 flush(s);
356
357 for(unsigned int i = 0; i < cuda_devices_count; ++i) {
358 msg_quit *quit_msg = new msg_quit;
359 s->thread_data[i].m_in.push(quit_msg);
360 }
361
362 for(unsigned int i = 0; i < cuda_devices_count; ++i) {
363 pthread_join(s->thread_id[i], NULL);
364 }
365
366 delete s;
367}
static void flush(struct state_decompresss_gpujpeg_to_dxt *s)

References cuda_devices_count, flush(), and state.

Here is the call graph for this function:

◆ gpujpeg_to_dxt_decompress_get_priority()

static int gpujpeg_to_dxt_decompress_get_priority ( codec_t compression,
struct pixfmt_desc internal,
codec_t ugc )
static

Definition at line 369 of file gpujpeg_to_dxt.cpp.

369 {
370 return compression == JPEG && (ugc == DXT1 || ugc == DXT5) ? 900 : -1;
371}
@ DXT1
S3 Texture Compression DXT1.
Definition types.h:77
@ JPEG
JPEG image, restart intervals may be used. Compatible with GPUJPEG.
Definition types.h:81
@ DXT5
S3 Texture Compression DXT5.
Definition types.h:79

References DXT1, DXT5, and JPEG.

◆ gpujpeg_to_dxt_decompress_get_property()

static int gpujpeg_to_dxt_decompress_get_property ( void * state,
int property,
void * val,
size_t * len )
static

Definition at line 337 of file gpujpeg_to_dxt.cpp.

338{
339 UNUSED(state);
341 UNUSED(val);
342 UNUSED(len);
343
344 return FALSE;
345}
int void * val
int void size_t * len
int property
#define FALSE

References FALSE, len, property, state, UNUSED, and val.

◆ gpujpeg_to_dxt_decompress_init()

static void * gpujpeg_to_dxt_decompress_init ( void )
static

Definition at line 183 of file gpujpeg_to_dxt.cpp.

184{
185 struct state_decompresss_gpujpeg_to_dxt *s;
186
187 s = new state_decompresss_gpujpeg_to_dxt;
188
189 s->free = 0;
190 s->occupied_count = 0;
191
192 for(unsigned int i = 0; i < cuda_devices_count; ++i) {
193 int ret = gpujpeg_init_device(cuda_devices[i], TRUE);
194 if(ret != 0) {
195 log_msg(LOG_LEVEL_ERROR, MOD_NAME "initializing CUDA device %d failed.\n", cuda_devices[0]);
196 delete s;
197 return NULL;
198 }
199 }
200
201 for(unsigned int i = 0; i < cuda_devices_count; ++i) {
202 s->thread_data[i].cuda_dev_index = i;
203 int ret = pthread_create(&s->thread_id[i], NULL, worker_thread, &s->thread_data[i]);
204 assert(ret == 0);
205 }
206
207 return s;
208}
#define TRUE
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
static void * worker_thread(void *arg)
#define MOD_NAME
unsigned int cuda_devices[MAX_CUDA_DEVICES]
Definition host.cpp:167

References cuda_devices, cuda_devices_count, LOG_LEVEL_ERROR, log_msg(), MOD_NAME, TRUE, and worker_thread().

Here is the call graph for this function:

◆ gpujpeg_to_dxt_decompress_reconfigure()

static int gpujpeg_to_dxt_decompress_reconfigure ( void * state,
struct video_desc desc,
int rshift,
int gshift,
int bshift,
int pitch,
codec_t out_codec )
static

Reconfigureation function

Returns
0 to indicate error otherwise maximal buffer size which ins needed for image of given codec, width, and height

Definition at line 231 of file gpujpeg_to_dxt.cpp.

233{
234 struct state_decompresss_gpujpeg_to_dxt *s = (struct state_decompresss_gpujpeg_to_dxt *) state;
235
236 UNUSED(rshift);
237 UNUSED(gshift);
238 UNUSED(bshift);
239 assert(out_codec == DXT1 || out_codec == DXT5);
240 if(out_codec == DXT1) {
241 s->ppb = 2;
242 } else { // DXT5
243 s->ppb = 1;
244 }
245 s->desc = desc;
246 assert(pitch == (int) desc.width / s->ppb); // default for DXT1
247
248 flush(s);
249
250 for(unsigned int i = 0; i < cuda_devices_count; ++i) {
251 msg_reconfigure *reconf = new msg_reconfigure;
252 reconf->desc = desc;
253 reconf->out_codec = out_codec;
254 reconf->ppb = s->ppb;
255
256 s->thread_data[i].m_in.push(reconf);
257
258 msg_reconfigure_status *status =
259 dynamic_cast<msg_reconfigure_status *>(s->thread_data[i].m_out.pop());
260 assert(status != NULL);
261 if (!status->success) {
262 delete status;
263 return FALSE;
264 }
265 delete status;
266 }
267
268 return TRUE;
269}
struct video_desc desc

References cuda_devices_count, desc, DXT1, DXT5, FALSE, flush(), state, TRUE, UNUSED, and video_desc::width.

Here is the call graph for this function:

◆ reconfigure_thread()

static int reconfigure_thread ( struct thread_data * s,
struct video_desc desc,
int ppb )
static
Returns
maximal buffer size needed to image with such a properties

Definition at line 274 of file gpujpeg_to_dxt.cpp.

275{
276 if(s->gpujpeg_decoder != NULL) {
277 gpujpeg_decoder_destroy(s->gpujpeg_decoder);
278 s->gpujpeg_decoder = NULL;
279 } else {
280 gpujpeg_init_device(cuda_devices[s->cuda_dev_index], 0);
281 }
282
283 if(s->dxt_out_buff != NULL) {
284 cuda_wrapper_free(s->dxt_out_buff);
285 s->dxt_out_buff = NULL;
286 }
287
288 if(cuda_wrapper_malloc_host((void **) &s->dxt_out_buff, desc.width * desc.height / ppb)
290 fprintf(stderr, "Could not allocate CUDA output buffer.\n");
291 return false;
292 }
293 //gpujpeg_init_device(cuda_device, GPUJPEG_OPENGL_INTEROPERABILITY);
294
295#if LIBGPUJPEG_API_VERSION <= 2
296 s->gpujpeg_decoder = gpujpeg_decoder_create();
297#else
298 s->gpujpeg_decoder = gpujpeg_decoder_create(NULL);
299#endif
300 if(!s->gpujpeg_decoder) {
301 log_msg(LOG_LEVEL_ERROR, "Creating GPUJPEG decoder failed.\n");
302 return false;
303 }
304
305 return true;
306}
int cuda_wrapper_malloc_host(void **buffer, size_t data_len)
int cuda_wrapper_free(void *buffer)
#define CUDA_WRAPPER_SUCCESS

References cuda_devices, cuda_wrapper_free(), cuda_wrapper_malloc_host(), CUDA_WRAPPER_SUCCESS, desc, video_desc::height, LOG_LEVEL_ERROR, log_msg(), and video_desc::width.

Referenced by worker_thread().

Here is the call graph for this function:

◆ REGISTER_MODULE()

REGISTER_MODULE ( gpujpeg_to_dxt ,
& gpujpeg_to_dxt_info,
LIBRARY_CLASS_VIDEO_DECOMPRESS ,
VIDEO_DECOMPRESS_ABI_VERSION  )

◆ worker_thread()

static void * worker_thread ( void * arg)
static

Definition at line 122 of file gpujpeg_to_dxt.cpp.

123{
124 struct thread_data *s =
125 (struct thread_data *) arg;
126
127 while(1) {
128 msg *message = s->m_in.pop();
129
130 if (dynamic_cast<msg_quit *>(message)) {
131 delete message;
132 break;
133 } else if (dynamic_cast<msg_reconfigure *>(message)) {
134 msg_reconfigure *reconf = dynamic_cast<msg_reconfigure *>(message);
135 bool ret = reconfigure_thread(s, reconf->desc, reconf->ppb);
136 s->desc = reconf->desc;
137 s->out_codec = reconf->out_codec;
138 s->ppb = reconf->ppb;
139
140 msg_reconfigure_status *status = new msg_reconfigure_status(ret);
141 s->m_out.push(status);
142
143 delete message;
144 } else if (dynamic_cast<msg_frame *>(message)) {
145 msg_frame *frame_msg = dynamic_cast<msg_frame *>(message);
146 struct gpujpeg_decoder_output decoder_output;
147
148 gpujpeg_decoder_output_set_cuda_buffer(&decoder_output);
149 gpujpeg_decoder_decode(s->gpujpeg_decoder, (uint8_t *) frame_msg->data, frame_msg->data_len,
150 &decoder_output);
151
152 if (s->out_codec == DXT1) {
153 cuda_rgb_to_dxt1(decoder_output.data, s->dxt_out_buff, s->desc.width,
154 -s->desc.height, 0);
155 } else {
156 cuda_rgb_to_dxt6(decoder_output.data, s->dxt_out_buff, s->desc.width,
157 -s->desc.height, 0);
158 }
159
160 msg_frame *output_frame = new msg_frame(s->desc.width * s->desc.height / s->ppb);
161
162 if (cuda_wrapper_memcpy((char*) output_frame->data, s->dxt_out_buff,
163 output_frame->data_len,
166 log_msg(LOG_LEVEL_ERROR, MOD_NAME "unable to copy from device.");
167 }
168 s->m_out.push(output_frame);
169
170 delete frame_msg;
171 }
172 }
173
174 if(s->gpujpeg_decoder) {
175 gpujpeg_decoder_destroy(s->gpujpeg_decoder);
176 }
177
178 cuda_wrapper_free(s->dxt_out_buff);
179
180 return NULL;
181}
int cuda_rgb_to_dxt6(const void *src, void *out, int size_x, int size_y, cuda_wrapper_stream_t stream)
Definition cuda_dxt.cu:816
int cuda_rgb_to_dxt1(const void *src, void *out, int size_x, int size_y, cuda_wrapper_stream_t stream)
Definition cuda_dxt.cu:782
int cuda_wrapper_memcpy(void *dst, const void *src, size_t count, int kind)
#define CUDA_WRAPPER_MEMCPY_DEVICE_TO_HOST
static int reconfigure_thread(struct thread_data *s, struct video_desc desc, int ppb)

References cuda_rgb_to_dxt1(), cuda_rgb_to_dxt6(), cuda_wrapper_free(), cuda_wrapper_memcpy(), CUDA_WRAPPER_MEMCPY_DEVICE_TO_HOST, CUDA_WRAPPER_SUCCESS, DXT1, video_desc::height, LOG_LEVEL_ERROR, log_msg(), MOD_NAME, reconfigure_thread(), and video_desc::width.

Referenced by display_xrgl_run(), and gpujpeg_to_dxt_decompress_init().

Here is the call graph for this function:

Variable Documentation

◆ gpujpeg_to_dxt_info

const struct video_decompress_info gpujpeg_to_dxt_info
static
Initial value:
= {
}
static int gpujpeg_to_dxt_decompress_get_property(void *state, int property, void *val, size_t *len)
static int gpujpeg_to_dxt_decompress_get_priority(codec_t compression, struct pixfmt_desc internal, codec_t ugc)
static decompress_status gpujpeg_to_dxt_decompress(void *state, unsigned char *dst, unsigned char *buffer, unsigned int src_len, int frame_seq, video_frame_callbacks *, codec_t *)
static int gpujpeg_to_dxt_decompress_reconfigure(void *state, struct video_desc desc, int rshift, int gshift, int bshift, int pitch, codec_t out_codec)
static void * gpujpeg_to_dxt_decompress_init(void)
static void gpujpeg_to_dxt_decompress_done(void *state)

Definition at line 373 of file gpujpeg_to_dxt.cpp.