summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorTuomas Virtanen <katajakasa@gmail.com>2018-06-23 23:46:26 +0300
committerTuomas Virtanen <katajakasa@gmail.com>2018-06-23 23:46:26 +0300
commitdc193d1fd246af68488aa678d620e2cad7140cbd (patch)
tree6e236404bc0992b30c6edc4ee9761c65e55f8134 /examples
parent33311c1fae634f1c1530d019aebecc08edebdb5d (diff)
Sort out examples better
Diffstat (limited to 'examples')
-rw-r--r--examples/example_audio.c2
-rw-r--r--examples/example_complex.c (renamed from examples/example_video.c)2
-rw-r--r--examples/example_custom.c (renamed from examples/example_cust_video.c)173
-rw-r--r--examples/example_simple.c205
4 files changed, 211 insertions, 171 deletions
diff --git a/examples/example_audio.c b/examples/example_audio.c
index 461d54c..51bee13 100644
--- a/examples/example_audio.c
+++ b/examples/example_audio.c
@@ -37,7 +37,7 @@ int main(int argc, char *argv[]) {
// Get filename to open
if(argc != 2) {
- fprintf(stderr, "Usage: exampleplay <filename>\n");
+ fprintf(stderr, "Usage: audio <filename>\n");
return 0;
}
filename = argv[1];
diff --git a/examples/example_video.c b/examples/example_complex.c
index 1487173..b49f980 100644
--- a/examples/example_video.c
+++ b/examples/example_complex.c
@@ -76,7 +76,7 @@ int main(int argc, char *argv[]) {
// Get filename to open
if(argc != 2) {
- fprintf(stderr, "Usage: exampleplay <filename>\n");
+ fprintf(stderr, "Usage: complex <filename>\n");
return 0;
}
filename = argv[1];
diff --git a/examples/example_cust_video.c b/examples/example_custom.c
index 09f8e23..7e1d90b 100644
--- a/examples/example_cust_video.c
+++ b/examples/example_custom.c
@@ -14,37 +14,6 @@
#define ATLAS_MAX 1024
-void render_gui(SDL_Renderer *renderer, double percent) {
- // Get window size
- int size_w, size_h;
- SDL_RenderGetLogicalSize(renderer, &size_w, &size_h);
-
- // Render progress bar
- SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
- SDL_Rect progress_border;
- progress_border.x = 28;
- progress_border.y = size_h - 61;
- progress_border.w = size_w - 57;
- progress_border.h = 22;
- SDL_RenderFillRect(renderer, &progress_border);
-
- SDL_SetRenderDrawColor(renderer, 155, 155, 155, 255);
- SDL_Rect progress_bottom;
- progress_bottom.x = 30;
- progress_bottom.y = size_h - 60;
- progress_bottom.w = size_w - 60;
- progress_bottom.h = 20;
- SDL_RenderFillRect(renderer, &progress_bottom);
-
- SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255);
- SDL_Rect progress_top;
- progress_top.x = 30;
- progress_top.y = size_h - 60;
- progress_top.w = (size_w - 60) * percent;
- progress_top.h = 20;
- SDL_RenderFillRect(renderer, &progress_top);
-}
-
int read_callback(void *userdata, uint8_t *buf, int buf_size) {
FILE *fd = (FILE*)userdata;
if(!feof(fd)) {
@@ -61,38 +30,21 @@ int64_t seek_callback(void *userdata, int64_t offset, int whence) {
return ftell(fd);
}
-void find_viewport_size(int sw, int sh, int vw, int vh, int *rw, int *rh) {
- float r_x = (float)sw / (float)vw;
- float r_y = (float)sh / (float)vh;
- float r_t = r_x < r_y ? r_x : r_y;
- *rw = vw * r_t;
- *rh = vh * r_t;
-}
-
int main(int argc, char *argv[]) {
int err = 0, ret = 0;
const char* filename = NULL;
-
- // Video
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
-
- // Events
- SDL_Event event;
bool run = true;
-
- // Kitchensink
Kit_Source *src = NULL;
Kit_Player *player = NULL;
-
- // Audio playback
SDL_AudioSpec wanted_spec, audio_spec;
SDL_AudioDeviceID audio_dev;
char audiobuf[AUDIOBUFFER_SIZE];
// Get filename to open
if(argc != 2) {
- fprintf(stderr, "Usage: exampleplay <filename>\n");
+ fprintf(stderr, "Usage: custom <filename>\n");
return 0;
}
filename = argv[1];
@@ -132,26 +84,13 @@ int main(int argc, char *argv[]) {
return 1;
}
- // Open up the sourcefile.
- // This can be a local file, network url, ...
+ // Open up the custom source. Declare read & seek callbacks, and transport FD in userdata.
src = Kit_CreateSourceFromCustom(read_callback, seek_callback, fd);
if(src == NULL) {
fprintf(stderr, "Unable to load file '%s': %s\n", filename, Kit_GetError());
return 1;
}
- // Print stream information
- Kit_StreamInfo sinfo;
- fprintf(stderr, "Source streams:\n");
- for(int i = 0; i < Kit_GetSourceStreamCount(src); i++) {
- err = Kit_GetSourceStreamInfo(src, &sinfo, i);
- if(err) {
- fprintf(stderr, "Unable to fetch stream #%d information: %s.\n", i, Kit_GetError());
- return 1;
- }
- fprintf(stderr, " * Stream #%d: %s\n", i, Kit_GetKitStreamTypeString(sinfo.type));
- }
-
// Create the player. Pick best video, audio and subtitle streams, and set subtitle
// rendering resolution to screen resolution.
player = Kit_CreatePlayer(
@@ -174,28 +113,6 @@ int main(int argc, char *argv[]) {
return 1;
}
- fprintf(stderr, "Media information:\n");
- if(pinfo.audio.is_enabled) {
- fprintf(stderr, " * Audio: %s (%s), %dHz, %dch, %db, %s\n",
- pinfo.acodec,
- pinfo.acodec_name,
- pinfo.audio.samplerate,
- pinfo.audio.channels,
- pinfo.audio.bytes,
- pinfo.audio.is_signed ? "signed" : "unsigned");
- }
- fprintf(stderr, " * Video: %s (%s), %dx%d\n",
- pinfo.vcodec,
- pinfo.vcodec_name,
- pinfo.video.width,
- pinfo.video.height);
- if(pinfo.subtitle.is_enabled) {
- fprintf(stderr, " * Subtitle: %s (%s)\n",
- pinfo.scodec,
- pinfo.scodec_name);
- }
- fprintf(stderr, "Duration: %f seconds\n", Kit_GetPlayerDuration(player));
-
// Init audio
SDL_memset(&wanted_spec, 0, sizeof(wanted_spec));
wanted_spec.freq = pinfo.audio.samplerate;
@@ -204,12 +121,6 @@ int main(int argc, char *argv[]) {
audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &audio_spec, 0);
SDL_PauseAudioDevice(audio_dev, 0);
- // Print some format info
- fprintf(stderr, "Texture type: %s\n", Kit_GetSDLPixelFormatString(pinfo.video.format));
- fprintf(stderr, "Audio format: %s\n", Kit_GetSDLAudioFormatString(pinfo.audio.format));
- fprintf(stderr, "Subtitle format: %s\n", Kit_GetSDLPixelFormatString(pinfo.subtitle.format));
- fflush(stderr);
-
// Initialize video texture. This will probably end up as YV12 most of the time.
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
SDL_Texture *video_tex = SDL_CreateTexture(
@@ -238,88 +149,20 @@ int main(int argc, char *argv[]) {
// Make sure subtitle texture is in correct blendmode
SDL_SetTextureBlendMode(subtitle_tex, SDL_BLENDMODE_BLEND);
- // Set logical size for the renderer. This way when we scale, we keep aspect ratio.
- SDL_RenderSetLogicalSize(renderer, pinfo.video.width, pinfo.video.height);
-
// Start playback
Kit_PlayerPlay(player);
// Get movie area size
- int mouse_x = 0;
- int mouse_y = 0;
- int size_w = 0;
- int size_h = 0;
- int screen_w = 0;
- int screen_h = 0;
- SDL_GetWindowSize(window, &screen_w, &screen_h);
- find_viewport_size(screen_w, screen_h, pinfo.video.width, pinfo.video.height, &size_w, &size_h);
- SDL_RenderSetLogicalSize(renderer, size_w, size_h);
- Kit_SetPlayerScreenSize(player, size_w, size_h);
- bool fullscreen = false;
+ SDL_RenderSetLogicalSize(renderer, pinfo.video.width, pinfo.video.height);
while(run) {
if(Kit_GetPlayerState(player) == KIT_STOPPED) {
run = false;
continue;
}
- // Check for events
- const Uint8 *state;
+ SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
- case SDL_KEYUP:
- if(event.key.keysym.sym == SDLK_ESCAPE) {
- run = false;
- }
- break;
-
- case SDL_KEYDOWN:
- // Find alt+enter
- state = SDL_GetKeyboardState(NULL);
- if(state[SDL_SCANCODE_RETURN] && state[SDL_SCANCODE_LALT]) {
- if(!fullscreen) {
- SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
- } else {
- SDL_SetWindowFullscreen(window, 0);
- }
- fullscreen = !fullscreen;
- }
- break;
-
- case SDL_MOUSEMOTION:
- mouse_x = event.motion.x;
- mouse_y = event.motion.y;
- break;
-
- case SDL_WINDOWEVENT:
- switch(event.window.event) {
- case SDL_WINDOWEVENT_SIZE_CHANGED:
- SDL_GetWindowSize(window, &screen_w, &screen_h);
- find_viewport_size(screen_w, screen_h, pinfo.video.width, pinfo.video.height, &size_w, &size_h);
- SDL_RenderSetLogicalSize(renderer, size_w, size_h);
- Kit_SetPlayerScreenSize(player, size_w, size_h);
- break;
- }
- break;
-
- case SDL_MOUSEBUTTONUP:
- // Handle user clicking the progress bar
- if(mouse_x >= 30 && mouse_x <= size_w-30 && mouse_y >= size_h - 60 && mouse_y <= size_h - 40) {
- double pos = ((double)mouse_x - 30) / ((double)size_w - 60);
- double m_time = Kit_GetPlayerDuration(player) * pos;
- if(Kit_PlayerSeek(player, m_time) != 0) {
- fprintf(stderr, "%s\n", Kit_GetError());
- }
- SDL_ClearQueuedAudio(audio_dev);
- } else {
- // Handle pause
- if(Kit_GetPlayerState(player) == KIT_PAUSED) {
- Kit_PlayerPlay(player);
- } else {
- Kit_PlayerPause(player);
- }
- }
- break;
-
case SDL_QUIT:
run = false;
break;
@@ -359,20 +202,12 @@ int main(int argc, char *argv[]) {
// Refresh subtitle texture atlas and render subtitle frames from it
// For subtitles, use screen size instead of video size for best quality
- SDL_RenderSetLogicalSize(renderer, screen_w, screen_h);
SDL_Rect sources[ATLAS_MAX];
SDL_Rect targets[ATLAS_MAX];
int got = Kit_GetPlayerSubtitleData(player, subtitle_tex, sources, targets, ATLAS_MAX);
for(int i = 0; i < got; i++) {
SDL_RenderCopy(renderer, subtitle_tex, &sources[i], &targets[i]);
}
- SDL_RenderSetLogicalSize(renderer, pinfo.video.width, pinfo.video.height);
-
- // Enable GUI if mouse is hovering over the bottom third of the screen
- if(mouse_y >= ((size_h / 3) * 2)) {
- double percent = Kit_GetPlayerPosition(player) / Kit_GetPlayerDuration(player);
- render_gui(renderer, percent);
- }
// Render to screen + wait for vsync
SDL_RenderPresent(renderer);
diff --git a/examples/example_simple.c b/examples/example_simple.c
new file mode 100644
index 0000000..0221863
--- /dev/null
+++ b/examples/example_simple.c
@@ -0,0 +1,205 @@
+#include <kitchensink/kitchensink.h>
+#include <SDL2/SDL.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+/*
+* Note! This example does not do proper error handling etc.
+* It is for example use only!
+*/
+
+#define AUDIOBUFFER_SIZE (1024 * 64)
+#define ATLAS_WIDTH 4096
+#define ATLAS_HEIGHT 4096
+#define ATLAS_MAX 1024
+
+int main(int argc, char *argv[]) {
+ int err = 0, ret = 0;
+ const char* filename = NULL;
+ SDL_Window *window = NULL;
+ SDL_Renderer *renderer = NULL;
+ bool run = true;
+ Kit_Source *src = NULL;
+ Kit_Player *player = NULL;
+ SDL_AudioSpec wanted_spec, audio_spec;
+ SDL_AudioDeviceID audio_dev;
+ char audiobuf[AUDIOBUFFER_SIZE];
+
+ // Get filename to open
+ if(argc != 2) {
+ fprintf(stderr, "Usage: simple <filename>\n");
+ return 0;
+ }
+ filename = argv[1];
+
+ // Init SDL
+ err = SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);
+ if(err != 0) {
+ fprintf(stderr, "Unable to initialize SDL2!\n");
+ return 1;
+ }
+
+ // Create a resizable window.
+ window = SDL_CreateWindow("Example Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
+ if(window == NULL) {
+ fprintf(stderr, "Unable to create a new window!\n");
+ return 1;
+ }
+
+ // Create an accelerated renderer. Enable vsync, so we don't need to play around with SDL_Delay.
+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
+ if(window == NULL) {
+ fprintf(stderr, "Unable to create a renderer!\n");
+ return 1;
+ }
+
+ // Initialize Kitchensink with network and libass support.
+ err = Kit_Init(KIT_INIT_NETWORK|KIT_INIT_ASS);
+ if(err != 0) {
+ fprintf(stderr, "Unable to initialize Kitchensink: %s", Kit_GetError());
+ return 1;
+ }
+
+ // Open up the sourcefile.
+ // This can be a local file, network url, ...
+ src = Kit_CreateSourceFromUrl(filename);
+ if(src == NULL) {
+ fprintf(stderr, "Unable to load file '%s': %s\n", filename, Kit_GetError());
+ return 1;
+ }
+
+ // Create the player. Pick best video, audio and subtitle streams, and set subtitle
+ // rendering resolution to screen resolution.
+ player = Kit_CreatePlayer(
+ src,
+ Kit_GetBestSourceStream(src, KIT_STREAMTYPE_VIDEO),
+ Kit_GetBestSourceStream(src, KIT_STREAMTYPE_AUDIO),
+ Kit_GetBestSourceStream(src, KIT_STREAMTYPE_SUBTITLE),
+ 1280, 720);
+ if(player == NULL) {
+ fprintf(stderr, "Unable to create player: %s\n", Kit_GetError());
+ return 1;
+ }
+
+ // Print some information
+ Kit_PlayerInfo pinfo;
+ Kit_GetPlayerInfo(player, &pinfo);
+
+ if(!pinfo.video.is_enabled) {
+ fprintf(stderr, "File contains no video!\n");
+ return 1;
+ }
+
+ // Init audio
+ SDL_memset(&wanted_spec, 0, sizeof(wanted_spec));
+ wanted_spec.freq = pinfo.audio.samplerate;
+ wanted_spec.format = pinfo.audio.format;
+ wanted_spec.channels = pinfo.audio.channels;
+ audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &audio_spec, 0);
+ SDL_PauseAudioDevice(audio_dev, 0);
+
+ // Initialize video texture. This will probably end up as YV12 most of the time.
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+ SDL_Texture *video_tex = SDL_CreateTexture(
+ renderer,
+ pinfo.video.format,
+ SDL_TEXTUREACCESS_STATIC,
+ pinfo.video.width,
+ pinfo.video.height);
+ if(video_tex == NULL) {
+ fprintf(stderr, "Error while attempting to create a video texture\n");
+ return 1;
+ }
+
+ // This is the subtitle texture atlas. This contains all the subtitle image fragments.
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); // Always nearest for atlas operations
+ SDL_Texture *subtitle_tex = SDL_CreateTexture(
+ renderer,
+ pinfo.subtitle.format,
+ SDL_TEXTUREACCESS_STATIC,
+ ATLAS_WIDTH, ATLAS_HEIGHT);
+ if(subtitle_tex == NULL) {
+ fprintf(stderr, "Error while attempting to create a subtitle texture atlas\n");
+ return 1;
+ }
+
+ // Make sure subtitle texture is in correct blendmode
+ SDL_SetTextureBlendMode(subtitle_tex, SDL_BLENDMODE_BLEND);
+
+ // Start playback
+ Kit_PlayerPlay(player);
+
+ // Get movie area size
+ SDL_RenderSetLogicalSize(renderer, pinfo.video.width, pinfo.video.height);
+ while(run) {
+ if(Kit_GetPlayerState(player) == KIT_STOPPED) {
+ run = false;
+ continue;
+ }
+
+ SDL_Event event;
+ while(SDL_PollEvent(&event)) {
+ switch(event.type) {
+ case SDL_QUIT:
+ run = false;
+ break;
+ }
+ }
+
+ // Refresh audio
+ int queued = SDL_GetQueuedAudioSize(audio_dev);
+ if(queued < AUDIOBUFFER_SIZE) {
+ int need = AUDIOBUFFER_SIZE - queued;
+
+ while(need > 0) {
+ ret = Kit_GetPlayerAudioData(
+ player,
+ (unsigned char*)audiobuf,
+ AUDIOBUFFER_SIZE);
+ need -= ret;
+ if(ret > 0) {
+ SDL_QueueAudio(audio_dev, audiobuf, ret);
+ } else {
+ break;
+ }
+ }
+ // If we now have data, start playback (again)
+ if(SDL_GetQueuedAudioSize(audio_dev) > 0) {
+ SDL_PauseAudioDevice(audio_dev, 0);
+ }
+ }
+
+ // Clear screen with black
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+ SDL_RenderClear(renderer);
+
+ // Refresh videotexture and render it
+ Kit_GetPlayerVideoData(player, video_tex);
+ SDL_RenderCopy(renderer, video_tex, NULL, NULL);
+
+ // Refresh subtitle texture atlas and render subtitle frames from it
+ // For subtitles, use screen size instead of video size for best quality
+ SDL_Rect sources[ATLAS_MAX];
+ SDL_Rect targets[ATLAS_MAX];
+ int got = Kit_GetPlayerSubtitleData(player, subtitle_tex, sources, targets, ATLAS_MAX);
+ for(int i = 0; i < got; i++) {
+ SDL_RenderCopy(renderer, subtitle_tex, &sources[i], &targets[i]);
+ }
+
+ // Render to screen + wait for vsync
+ SDL_RenderPresent(renderer);
+ }
+
+ Kit_ClosePlayer(player);
+ Kit_CloseSource(src);
+ Kit_Quit();
+
+ SDL_DestroyTexture(subtitle_tex);
+ SDL_DestroyTexture(video_tex);
+ SDL_CloseAudioDevice(audio_dev);
+
+ SDL_DestroyRenderer(renderer);
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+ return 0;
+}