58#include "utils/autorelease_pool.h"
59extern "C" void NSApplicationLoad();
60#elif defined __linux__
67#include <SDL/SDL_syswm.h>
69#include <condition_variable>
73#define MAGIC_SDL 0x155734ae
74#define FOURCC_UYVY 0x59565955
75#define FOURCC_YUYV 0x32595559
77#define MAX_BUFFER_SIZE 1
81#define SDL_USER_NEWFRAME SDL_USEREVENT
113 void *autorelease_pool;
125 autorelease_pool(nullptr),
129 gettimeofday(&
tv, NULL);
166 if (window_w > vid_w) {
167 s->
dst_rect.x = ((int) window_w - vid_w) / 2;
168 }
else if (window_w < vid_w) {
171 if (window_h > vid_h) {
172 s->
dst_rect.y = ((int) window_h - vid_h) / 2;
173 }
else if (window_h < vid_h) {
177 double frame_aspect = (double) vid_w / vid_h;
178 double screen_aspect = (double) window_w / window_h;
179 if(screen_aspect > frame_aspect) {
181 s->
dst_rect.w = window_h * frame_aspect;
185 s->
dst_rect.h = window_w / frame_aspect;
190 fprintf(stdout,
"Setting SDL rect %dx%d - %d,%d.\n", s->
dst_rect.w,
196 unsigned int x_res_x, x_res_y;
207 fprintf(stdout,
"Setting video mode %dx%d.\n", x_res_x, x_res_y);
210 fprintf(stderr,
"Error setting video mode %dx%d!\n", x_res_x,
238 assert(decoder !=
nullptr);
243 decoder((
unsigned char *) s->
sdl_screen->pixels +
261 unsigned char *src = (
unsigned char *)
frame->
tiles[0].
data + i * src_linesize;
267 memcpy((
unsigned char *) s->
sdl_screen->pixels +
291 gettimeofday(&tv, NULL);
294 double fps = s->
frames / seconds;
305 bool should_exit_sdl =
false;
307 while (!should_exit_sdl) {
312 if (strncasecmp(msg_univ->text,
"win-title ", strlen(
"win_title ")) == 0) {
313 const char *title = msg_univ->text + strlen(
"win_title");
314 SDL_WM_SetCaption(title, title);
324 if (SDL_WaitEvent(&sdl_event)) {
325 switch (sdl_event.type) {
328 std::unique_lock<std::mutex> lk(s->
lock);
332 if (sdl_event.user.data1 != NULL) {
335 should_exit_sdl =
true;
339 case SDL_VIDEORESIZE:
340 update_size(s, sdl_event.resize.w, sdl_event.resize.h);
343 switch (sdl_event.key.keysym.sym) {
358 SDL_GetKeyName(sdl_event.key.keysym.sym));
372 printf(
"SDL options:\n");
373 printf(
"\t-d sdl[:fs|:d|:nodecorate|:fixed_size[=WxH]]* | help\n");
374 printf(
"\tfs - fullscreen\n");
375 printf(
"\td - deinterlace\n");
376 printf(
"\tnodecorate - disable WM decoration\n");
377 printf(
"\tfixed_size[=WxH] - use fixed sized window\n");
407 fprintf(stdout,
"Reconfigure to size %dx%d\n",
desc.
width,
410 uint32_t flags_common = SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_RESIZABLE;
429 SDL_WM_SetCaption(window_title, window_title);
431 SDL_WM_SetCaption(
"Ultragrid - SDL Display",
"Ultragrid");
434 SDL_ShowCursor(SDL_DISABLE);
441 printf(
"SDL_overlay initialization failed.\n");
454 const SDL_VideoInfo *video_info;
457 if (strcmp(
fmt,
"help") == 0) {
463 char *tmp = strdup(
fmt);
466 char *save_ptr = NULL;
468 while((tok = strtok_r(ptr,
":", &save_ptr)))
470 if (strcmp(tok,
"fs") == 0) {
472 }
else if (strcmp(tok,
"d") == 0) {
474 }
else if (strcmp(tok,
"nodecorate") == 0) {
476 }
else if (strncmp(tok,
"fixed_size", strlen(
"fixed_size")) == 0) {
478 if (strncmp(tok,
"fixed_size=", strlen(
"fixed_size=")) == 0) {
479 char *size = tok + strlen(
"fixed_size=");
480 if (strchr(size,
'x')) {
482 s->
fixed_h = atoi(strchr(size,
'x') + 1);
497 s->autorelease_pool = autorelease_pool_allocate();
500 ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
503 printf(
"Unable to initialize SDL.\n");
508 video_info = SDL_GetVideoInfo();
509 s->
screen_w = video_info->current_w;
510 s->
screen_h = video_info->current_h;
513 memset(&info, 0,
sizeof(SDL_SysWMinfo));
514 ret = SDL_GetWMInfo(&info);
518 }
else if (ret == 0) {
519 fprintf(stderr,
"[SDL] Warning: SDL_GetWMInfo unimplemented\n");
520 }
else if (ret == -1) {
521 fprintf(stderr,
"[SDL] Warning: SDL_GetWMInfo failure: %s\n", SDL_GetError());
568 SDL_ShowCursor(SDL_ENABLE);
570 SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
573 autorelease_pool_destroy(s->autorelease_pool);
616 std::unique_lock<std::mutex> lk(s->
lock);
620 printf(
"1 frame(s) dropped!\n");
628 event.user.data1 =
frame;
629 SDL_PushEvent(&event);
659 fprintf(stderr,
"[SDL] audio buffer underflow!!!\n");
668 SDL_Init(SDL_INIT_AUDIO);
670 if(SDL_GetAudioStatus() != SDL_AUDIO_STOPPED) {
672 fprintf(stderr,
"[SDL] Audio init failed - driver is already used (testcard?)\n");
685 SDL_AudioSpec desired, obtained;
698 fprintf(stderr,
"[SDL] audio format isn't supported: "
699 "channels: %d, samples: %d, sample rate: %d\n",
705 sample_type = AUDIO_S8;
708 sample_type = AUDIO_S16LSB;
719 desired.format=sample_type;
723 desired.samples=1024;
731 if ( SDL_OpenAudio(&desired, &obtained) < 0 ){
732 fprintf(stderr,
"Couldn't open audio: %s\n", SDL_GetError());
759 tmp = (
char *) malloc(
frame->data_len /
frame->bps * 2);
772 strcpy((*available_cards)[0].
dev,
"");
773 strcpy((*available_cards)[0].
name,
"SDL SW display");
774 (*available_cards)[0].repeatable =
true;
struct video_frame long long nonblock
struct video_frame * frame
const char unsigned int flags
int void(** deleter)(void *))
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct video_desc video_desc_from_frame(const struct video_frame *frame)
Returns struct video_desc from video frame.
int vc_get_linesize(unsigned int width, codec_t codec)
struct video_frame * vf_alloc_desc_data(struct video_desc desc)
This file contains definition of some common audio types.
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_INFO
normal reporting
#define LOG_LEVEL_ERROR
general errors
#define VIDEO_DISPLAY_ABI_VERSION
#define DISPLAY_FLAG_AUDIO_ANY
#define DISPLAY_NO_GENERIC_FPS_INDICATOR
#define DISPLAY_FLAG_AUDIO_EMBEDDED
struct video_frame * get_splashscreen()
@ DISPLAY_PROPERTY_CODECS
list of natively supported codecs - codec_t[]
void module_init_default(struct module *module_data)
void module_register(struct module *module_data, struct module *parent)
struct module * get_module(struct module *root, const char *const_path)
void module_done(struct module *module_data)
struct module * get_root_module(struct module *node)
const char * get_commandline_param(const char *key)
bool keycontrol_register_key(struct module *receiver_mod, int64_t key, const char *message, const char *description)
Registers callback message for given key.
@ LIBRARY_CLASS_VIDEO_DISPLAY
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct message * check_message(struct module *mod)
#define RESPONSE_BAD_REQUEST
decoder_t get_decoder_from_to(codec_t in, codec_t out)
decoder_func_t * decoder_t
struct ring_buffer * ring_buffer_init(int size)
int ring_buffer_read(struct ring_buffer *ring, char *out, int max_len)
void ring_buffer_write(struct ring_buffer *ring, const char *in, int len)
static void display_sdl_done(void *state)
static bool display_sdl_get_property(void *state, int property, void *val, size_t *len)
static void display_frame(struct state_sdl *s, struct video_frame *frame)
#define SDL_USER_NEWFRAME
static bool display_sdl_reconfigure(void *state, struct video_desc desc)
static void compute_dst_rect(struct state_sdl *s, int vid_w, int vid_h, int window_w, int window_h, codec_t codec)
static bool update_size(struct state_sdl *s, int win_w, int win_h)
static void display_sdl_probe(struct device_info **available_cards, int *count, void(**deleter)(void *))
static void configure_audio(struct state_sdl *s)
static const struct video_display_info display_sdl_info
static struct video_frame * display_sdl_getf(void *state)
static void display_sdl_run(void *arg)
static void display_sdl_put_audio_frame(void *state, const struct audio_frame *frame)
static void cleanup_screen(struct state_sdl *s)
static bool display_sdl_reconfigure_audio(void *state, int quant_samples, int channels, int sample_rate)
static void loadSplashscreen(struct state_sdl *s)
static bool display_sdl_putf(void *state, struct video_frame *frame, long long nonblock)
static void sdl_audio_callback(void *userdata, Uint8 *stream, int len)
static void show_help(void)
static bool display_sdl_reconfigure_real(void *state, struct video_desc desc)
static void * display_sdl_init(struct module *parent, const char *fmt, unsigned int flags)
struct used to comunicate with audio capture/playback device
struct ring_buffer * audio_buffer
struct video_desc current_desc
struct audio_frame audio_frame
int buffered_frames_count
queue< struct video_frame * > free_frame_queue
struct video_desc current_display_desc
with those desc new data frames will be generated (getf)
state_sdl(struct module *parent)
condition_variable frame_consumed_cv
char * data
Raw tile data. Pointer must be at least 4B aligned.
unsigned int data_len
length of the data
enum interlacing_t interlacing
unsigned int width
width of every tile (!)
unsigned int height
height of every tile (!)
Struct video_frame represents a video frame and contains video description.
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
double tv_diff(struct timeval curr_time, struct timeval prev_time)
@ PROGRESSIVE
progressive frame
@ YUYV
YCbCr 422 8-bit - Y0 Cb Y1 Cr.
@ RGB
RGB 8-bit (packed into 24-bit word)
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
@ RGBA
RGBA 8-bit, big-endian.
int usleep(unsigned int usec)
void change_bps(char *out, int out_bps, const char *in, int in_bps, int in_len)
This is an umbrella header for video functions.
void vc_deinterlace(unsigned char *src, long src_linesize, int lines)
Deinterlaces framebuffer.
bool codec_is_a_rgb(codec_t codec)
Returns TRUE if specified pixelformat is some form of RGB (not YUV).
double get_bpp(codec_t codec)
bool video_desc_eq(struct video_desc a, struct video_desc b)
Compares two video descriptions.
void x11_set_display(void *disp)