Skip to content

Commit

Permalink
Support switching streams (+add helper functions)
Browse files Browse the repository at this point in the history
  • Loading branch information
katajakasa committed Nov 14, 2023
1 parent 933902c commit ee447f6
Show file tree
Hide file tree
Showing 10 changed files with 436 additions and 101 deletions.
106 changes: 82 additions & 24 deletions examples/example_complex.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,43 @@
#define ATLAS_MAX 1024


void dump_audio_stream_info(const Kit_Player *player, Kit_PlayerInfo *player_info) {
if(Kit_GetPlayerAudioStream(player) >= 0) {
fprintf(
stderr,
" * Audio: %s (%s), threads=%d, %dHz, %dch, %db, %s\n",
player_info->audio_codec.name,
player_info->audio_codec.description,
player_info->video_codec.threads,
player_info->audio_format.sample_rate,
player_info->audio_format.channels,
player_info->audio_format.bytes,
player_info->audio_format.is_signed ? "signed" : "unsigned");
}
}

void dump_video_stream_info(const Kit_Player *player, Kit_PlayerInfo *player_info) {
if(Kit_GetPlayerVideoStream(player) >= 0) {
fprintf(
stderr,
" * Video: %s (%s), threads=%d, %dx%d\n",
player_info->video_codec.name,
player_info->video_codec.description,
player_info->video_codec.threads,
player_info->video_format.width,
player_info->video_format.height);
}
}

void dump_subtitle_stream_info(const Kit_Player *player, Kit_PlayerInfo *player_info) {
if(Kit_GetPlayerSubtitleStream(player) >= 0) {
fprintf(stderr, " * Subtitle: %s (%s), threads=%d\n",
player_info->subtitle_codec.name,
player_info->subtitle_codec.description,
player_info->video_codec.threads);
}
}

void render_gui(SDL_Renderer *renderer, double percent) {
// Get window size
int size_w, size_h;
Expand Down Expand Up @@ -157,30 +194,10 @@ int main(int argc, char *argv[]) {
}

fprintf(stderr, "Media information:\n");
if(Kit_GetPlayerAudioStream(player) >= 0) {
fprintf(stderr, " * Audio: %s (%s), threads=%d, %dHz, %dch, %db, %s\n",
player_info.audio_codec.name,
player_info.audio_codec.description,
player_info.video_codec.threads,
player_info.audio_format.sample_rate,
player_info.audio_format.channels,
player_info.audio_format.bytes,
player_info.audio_format.is_signed ? "signed" : "unsigned");
}
if(Kit_GetPlayerVideoStream(player) >= 0) {
fprintf(stderr, " * Video: %s (%s), threads=%d, %dx%d\n",
player_info.video_codec.name,
player_info.video_codec.description,
player_info.video_codec.threads,
player_info.video_format.width,
player_info.video_format.height);
}
if(Kit_GetPlayerSubtitleStream(player) >= 0) {
fprintf(stderr, " * Subtitle: %s (%s), threads=%d\n",
player_info.subtitle_codec.name,
player_info.subtitle_codec.description,
player_info.video_codec.threads);
}
dump_audio_stream_info(player, &player_info);
dump_video_stream_info(player, &player_info);
dump_subtitle_stream_info(player, &player_info);

int num, den;
if(Kit_GetPlayerAspectRatio(player, &num, &den) == 0) {
fprintf(stderr, "Aspect ratio: %d:%d\n", num, den);
Expand Down Expand Up @@ -243,6 +260,8 @@ int main(int argc, char *argv[]) {
int size_h = 0;
int screen_w = 0;
int screen_h = 0;
int current_index = 0;
int next_index = 0;
bool fullscreen = false;
SDL_Rect video_area;

Expand All @@ -269,9 +288,48 @@ int main(int argc, char *argv[]) {
case SDL_KEYUP:
if(event.key.keysym.sym == SDLK_ESCAPE) {
run = false;
} else if(event.key.keysym.sym == SDLK_s) {
current_index = Kit_GetPlayerStream(player, KIT_STREAMTYPE_SUBTITLE);
next_index = Kit_GetNextSourceStream(src, KIT_STREAMTYPE_SUBTITLE, current_index, 1);
if(Kit_SetPlayerStream(player, KIT_STREAMTYPE_SUBTITLE, next_index) != 0) {
fprintf(stderr, "Failed to set subtitle stream %d: %s\n", next_index, Kit_GetError());
} else {
fprintf(stderr, "Setting subtitle stream %d\n", next_index);
}
fflush(stderr);
}
else if(event.key.keysym.sym == SDLK_v) {
current_index = Kit_GetPlayerStream(player, KIT_STREAMTYPE_VIDEO);
next_index = Kit_GetNextSourceStream(src, KIT_STREAMTYPE_VIDEO, current_index, 1);
if(Kit_SetPlayerStream(player, KIT_STREAMTYPE_VIDEO, next_index) != 0) {
fprintf(stderr, "Failed to set video stream %d: %s\n", next_index, Kit_GetError());
} else {
fprintf(stderr, "Setting video stream %d\n", next_index);
}
fflush(stderr);
}
else if(event.key.keysym.sym == SDLK_a) {
current_index = Kit_GetPlayerStream(player, KIT_STREAMTYPE_AUDIO);
next_index = Kit_GetNextSourceStream(src, KIT_STREAMTYPE_AUDIO, current_index, 1);
if(Kit_SetPlayerStream(player, KIT_STREAMTYPE_AUDIO, next_index) != 0) {
fprintf(stderr, "Failed to set audio stream %d: %s\n", next_index, Kit_GetError());
} else {
fprintf(stderr, "Setting audio stream %d\n", next_index);
Kit_GetPlayerInfo(player, &player_info);
SDL_memset(&wanted_spec, 0, sizeof(wanted_spec));
wanted_spec.freq = player_info.audio_format.sample_rate;
wanted_spec.format = player_info.audio_format.format;
wanted_spec.channels = player_info.audio_format.channels;
SDL_CloseAudioDevice(audio_dev);
audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &audio_spec, 0);
dump_audio_stream_info(player, &player_info);
SDL_PauseAudioDevice(audio_dev, 0);
}
fflush(stderr);
}
break;


case SDL_KEYDOWN:
// Find alt+enter
state = SDL_GetKeyboardState(NULL);
Expand Down
2 changes: 1 addition & 1 deletion include/kitchensink/internal/kitbufferindex.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ typedef enum KitBufferIndex {
KIT_AUDIO_INDEX,
KIT_SUBTITLE_INDEX,
KIT_INDEX_COUNT
} KitBufferIndex;
} Kit_BufferIndex;

#endif // KITBUFFERINDEX
3 changes: 2 additions & 1 deletion include/kitchensink/internal/kitdemuxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ KIT_LOCAL Kit_Demuxer* Kit_CreateDemuxer(
);
KIT_LOCAL void Kit_CloseDemuxer(Kit_Demuxer **demuxer);
KIT_LOCAL bool Kit_RunDemuxer(Kit_Demuxer *demuxer);
KIT_LOCAL Kit_PacketBuffer* Kit_GetDemuxerPacketBuffer(const Kit_Demuxer *demuxer, KitBufferIndex buffer_index);
KIT_LOCAL Kit_PacketBuffer* Kit_GetDemuxerPacketBuffer(const Kit_Demuxer *demuxer, Kit_BufferIndex buffer_index);
KIT_LOCAL void Kit_ClearDemuxerBuffers(const Kit_Demuxer *demuxer);
KIT_LOCAL void Kit_SignalDemuxer(const Kit_Demuxer *demuxer);
KIT_LOCAL bool Kit_DemuxerSeek(Kit_Demuxer *demuxer, int64_t seek_target);
KIT_LOCAL void Kit_SetDemuxerStreamIndex(Kit_Demuxer *demuxer, Kit_BufferIndex index, int stream_index);

#endif // KITDEMUXER_H
2 changes: 1 addition & 1 deletion include/kitchensink/internal/kitdemuxerthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ KIT_LOCAL Kit_DemuxerThread* Kit_CreateDemuxerThread(Kit_Demuxer *demuxer);
KIT_LOCAL void Kit_CloseDemuxerThread(Kit_DemuxerThread **demuxer);

KIT_LOCAL void Kit_SeekDemuxerThread(Kit_DemuxerThread *demuxer_thread, int64_t seek_target);
KIT_LOCAL Kit_PacketBuffer* Kit_GetDemuxerThreadPacketBuffer(const Kit_DemuxerThread *demuxer_thread, KitBufferIndex buffer_index);
KIT_LOCAL Kit_PacketBuffer* Kit_GetDemuxerThreadPacketBuffer(const Kit_DemuxerThread *demuxer_thread, Kit_BufferIndex buffer_index);

KIT_LOCAL void Kit_StartDemuxerThread(Kit_DemuxerThread *demuxer_thread);
KIT_LOCAL void Kit_StopDemuxerThread(Kit_DemuxerThread *demuxer_thread);
Expand Down
22 changes: 22 additions & 0 deletions include/kitchensink/kitplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,28 @@ KIT_API double Kit_GetPlayerPosition(const Kit_Player *player);
*/
KIT_API int Kit_GetPlayerAspectRatio(const Kit_Player *player, int *num, int *den);

/**
* @brief Selects stream index for specified stream type.
*
* This allows switching streams during or outside playback. Handy for eg.
* switching subtitle track.
*
* @param player Player instance
* @param type Stream to switch
* @param index Index to use (list can be queried from the source)
* @return 0 on success, 1 on failure.
*/
KIT_API int Kit_SetPlayerStream(Kit_Player *player, const Kit_StreamType type, int index);

/**
* @brief Returns the current index of the specified stream type
*
* @param player Player instance
* @param type Stream to switch
* @return Stream index or -1 on error or if stream is not set
*/
KIT_API int Kit_GetPlayerStream(const Kit_Player *player, const Kit_StreamType type);

#ifdef __cplusplus
}
#endif
Expand Down
26 changes: 26 additions & 0 deletions include/kitchensink/kitsource.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,32 @@ KIT_API int Kit_GetBestSourceStream(const Kit_Source *src, const Kit_StreamType
*/
KIT_API double Kit_GetSourceDuration(const Kit_Source *src);

/**
* @brief Makes a list of stream indexes with requested type
*
* This can be used to get all stream indexes of certain type, eg. all video streams.
*
* @param src Source to query from
* @param type Stream type to search
* @param list Integer list to insert into
* @param size Maximum size of the list
* @return Number of elements found
*/
KIT_API int Kit_GetSourceStreamList(const Kit_Source *src, const Kit_StreamType type, int *list, int size);

/**
* @brief Gets the next stream index of given type
*
* This can be used to get the next stream index of a certain type, eg. a video stream.
*
* @param src Source to query from
* @param type Stream type to search
* @param current Index to to start iterating from
* @param loop Start looping from the start of the stream list if we go past the end.
* @return Index number if found, -1 if no more streams of given type were found.
*/
KIT_API int Kit_GetNextSourceStream(const Kit_Source *src, const Kit_StreamType type, int current_index, int loop);

#ifdef __cplusplus
}
#endif
Expand Down
7 changes: 6 additions & 1 deletion src/internal/kitdemuxer.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,19 @@ void Kit_ClearDemuxerBuffers(const Kit_Demuxer *demuxer) {
Kit_FlushPacketBuffer(demuxer->buffers[i]);
}

void Kit_SetDemuxerStreamIndex(Kit_Demuxer *demuxer, Kit_BufferIndex index, int stream_index) {
Kit_FlushPacketBuffer(demuxer->buffers[index]);
demuxer->stream_indexes[index] = stream_index;
}

void Kit_SignalDemuxer(const Kit_Demuxer *demuxer) {
if (!demuxer)
return;
for (int i = 0; i < KIT_INDEX_COUNT; i++)
Kit_SignalPacketBuffer(demuxer->buffers[i]);
}

Kit_PacketBuffer* Kit_GetDemuxerPacketBuffer(const Kit_Demuxer *demuxer, KitBufferIndex buffer_index) {
Kit_PacketBuffer* Kit_GetDemuxerPacketBuffer(const Kit_Demuxer *demuxer, Kit_BufferIndex buffer_index) {
assert(demuxer);
return demuxer->buffers[buffer_index];
}
Expand Down
2 changes: 1 addition & 1 deletion src/internal/kitdemuxerthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void Kit_WaitDemuxerThread(Kit_DemuxerThread *demuxer_thread) {
demuxer_thread->thread = NULL;
}

Kit_PacketBuffer* Kit_GetDemuxerThreadPacketBuffer(const Kit_DemuxerThread *demuxer_thread, KitBufferIndex buffer_index) {
Kit_PacketBuffer* Kit_GetDemuxerThreadPacketBuffer(const Kit_DemuxerThread *demuxer_thread, Kit_BufferIndex buffer_index) {
assert(demuxer_thread);
return Kit_GetDemuxerPacketBuffer(demuxer_thread->demuxer, buffer_index);
}
Expand Down
Loading

0 comments on commit ee447f6

Please sign in to comment.