49#include "libgpujpeg/gpujpeg_decoder.h"
50#include "libgpujpeg/gpujpeg_version.h"
59#define MOD_NAME "[GPUJPEG to DXT] "
65 gpujpeg_decoder(0),
desc(), out_codec(), ppb(), dxt_out_buff(0),
72 struct gpujpeg_decoder *gpujpeg_decoder;
81struct msg_reconfigure :
public msg {
87struct msg_reconfigure_status :
public msg {
88 msg_reconfigure_status(
bool val) : success(
val) {}
93struct msg_frame :
public msg {
105struct state_decompresss_gpujpeg_to_dxt {
114 unsigned int occupied_count;
124 struct thread_data *s =
125 (
struct thread_data *) arg;
133 }
else if (
dynamic_cast<msg_reconfigure *
>(
message)) {
134 msg_reconfigure *reconf =
dynamic_cast<msg_reconfigure *
>(
message);
136 s->desc = reconf->desc;
137 s->out_codec = reconf->out_codec;
138 s->ppb = reconf->ppb;
140 msg_reconfigure_status *
status =
new msg_reconfigure_status(ret);
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;
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,
152 if (s->out_codec ==
DXT1) {
160 msg_frame *output_frame =
new msg_frame(s->desc.
width * s->desc.
height / s->ppb);
163 output_frame->data_len,
168 s->m_out.push(output_frame);
174 if(s->gpujpeg_decoder) {
175 gpujpeg_decoder_destroy(s->gpujpeg_decoder);
185 struct state_decompresss_gpujpeg_to_dxt *s;
187 s =
new state_decompresss_gpujpeg_to_dxt;
190 s->occupied_count = 0;
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]);
210static void flush(
struct state_decompresss_gpujpeg_to_dxt *s)
212 if (s->occupied_count > 0) {
216 struct msg_frame *completed =
217 dynamic_cast<msg_frame *
>(s->thread_data[(s->free+1)%
cuda_devices_count].m_out.pop());
220 s->occupied_count = 0;
232 int rshift,
int gshift,
int bshift,
int pitch,
codec_t out_codec)
234 struct state_decompresss_gpujpeg_to_dxt *s = (
struct state_decompresss_gpujpeg_to_dxt *)
state;
239 assert(out_codec ==
DXT1 || out_codec ==
DXT5);
240 if(out_codec ==
DXT1) {
246 assert(pitch == (
int)
desc.
width / s->ppb);
251 msg_reconfigure *reconf =
new msg_reconfigure;
253 reconf->out_codec = out_codec;
254 reconf->ppb = s->ppb;
256 s->thread_data[i].m_in.push(reconf);
258 msg_reconfigure_status *
status =
259 dynamic_cast<msg_reconfigure_status *
>(s->thread_data[i].m_out.pop());
276 if(s->gpujpeg_decoder != NULL) {
277 gpujpeg_decoder_destroy(s->gpujpeg_decoder);
278 s->gpujpeg_decoder = NULL;
280 gpujpeg_init_device(
cuda_devices[s->cuda_dev_index], 0);
283 if(s->dxt_out_buff != NULL) {
285 s->dxt_out_buff = NULL;
290 fprintf(stderr,
"Could not allocate CUDA output buffer.\n");
295#if LIBGPUJPEG_API_VERSION <= 2
296 s->gpujpeg_decoder = gpujpeg_decoder_create();
298 s->gpujpeg_decoder = gpujpeg_decoder_create(NULL);
300 if(!s->gpujpeg_decoder) {
311 struct state_decompresss_gpujpeg_to_dxt *s = (
struct state_decompresss_gpujpeg_to_dxt *)
state;
314 msg_frame *
message =
new msg_frame(src_len);
315 memcpy(
message->data, buffer, src_len);
318 s->thread_data[s->free].m_in.push(
message);
319 s->free = s->free + 1;
320 s->occupied_count += 1;
322 s->thread_data[s->free].m_in.push(
message);
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);
349 struct state_decompresss_gpujpeg_to_dxt *s = (
struct state_decompresss_gpujpeg_to_dxt *)
state;
359 s->thread_data[i].m_in.push(quit_msg);
363 pthread_join(s->thread_id[i], NULL);
370 return compression ==
JPEG && (ugc ==
DXT1 || ugc ==
DXT5) ? 900 : -1;
simple blocking synchronized queue
int cuda_rgb_to_dxt6(const void *src, void *out, int size_x, int size_y, cuda_wrapper_stream_t stream)
int cuda_rgb_to_dxt1(const void *src, void *out, int size_x, int size_y, cuda_wrapper_stream_t stream)
Interface of DXT compression CUDA implementation.
int cuda_wrapper_malloc_host(void **buffer, size_t data_len)
int cuda_wrapper_free(void *buffer)
int cuda_wrapper_memcpy(void *dst, const void *src, size_t count, int kind)
#define CUDA_WRAPPER_SUCCESS
#define CUDA_WRAPPER_MEMCPY_DEVICE_TO_HOST
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_ERROR
general errors
static int gpujpeg_to_dxt_decompress_get_property(void *state, int property, void *val, size_t *len)
static void * worker_thread(void *arg)
static const struct video_decompress_info gpujpeg_to_dxt_info
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 int reconfigure_thread(struct thread_data *s, struct video_desc desc, int ppb)
static void gpujpeg_to_dxt_decompress_done(void *state)
static void flush(struct state_decompresss_gpujpeg_to_dxt *s)
unsigned int cuda_devices_count
unsigned int cuda_devices[MAX_CUDA_DEVICES]
@ LIBRARY_CLASS_VIDEO_DECOMPRESS
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
unsigned int width
width of every tile (!)
unsigned int height
height of every tile (!)
Struct containing callbacks of a video_frame.
@ DXT1
S3 Texture Compression DXT1.
@ JPEG
JPEG image, restart intervals may be used. Compatible with GPUJPEG.
@ DXT5
S3 Texture Compression DXT5.
This is an umbrella header for video functions.
API for video decompress drivers.
#define VIDEO_DECOMPRESS_ABI_VERSION