Move frame swapping logic to frame.c

Expose frames_offer_decoded_frame() and frames_consume_rendered_frame()
so that callers are not exposed to frame swapping (between the decoding
and rendering frames) details.
This commit is contained in:
Romain Vimont
2018-02-08 19:23:24 +01:00
parent 0d7f050389
commit 629c296207
4 changed files with 58 additions and 27 deletions

View File

@@ -1,9 +1,14 @@
#include "frames.h"
#include <SDL2/SDL_assert.h>
#include <SDL2/SDL_log.h>
#include <SDL2/SDL_mutex.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include "config.h"
#include "lockutil.h"
SDL_bool frames_init(struct frames *frames) {
if (!(frames->decoding_frame = av_frame_alloc())) {
goto error_0;
@@ -24,6 +29,8 @@ SDL_bool frames_init(struct frames *frames) {
}
#endif
// there is initially no rendering frame, so consider it has already been
// consumed
frames->rendering_frame_consumed = SDL_TRUE;
return SDL_TRUE;
@@ -45,8 +52,43 @@ void frames_destroy(struct frames *frames) {
av_frame_free(&frames->decoding_frame);
}
void frames_swap(struct frames *frames) {
static void frames_swap(struct frames *frames) {
AVFrame *tmp = frames->decoding_frame;
frames->decoding_frame = frames->rendering_frame;
frames->rendering_frame = tmp;
}
SDL_bool frames_offer_decoded_frame(struct frames *frames) {
mutex_lock(frames->mutex);
SDL_bool previous_frame_consumed;
#ifndef SKIP_FRAMES
// if SKIP_FRAMES is disabled, then the decoder must wait for the current
// frame to be consumed
while (!frames->rendering_frame_consumed) {
cond_wait(frames->rendering_frame_consumed_cond, frames->mutex);
}
// by definition, we are not skipping the frames
previous_frame_consumed = SDL_TRUE;
#else
previous_frame_consumed = frames->rendering_frame_consumed;
if (!previous_frame_consumed) {
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Skip frame");
}
#endif
frames_swap(frames);
frames->rendering_frame_consumed = SDL_FALSE;
mutex_unlock(frames->mutex);
return previous_frame_consumed;
}
const AVFrame *frames_consume_rendered_frame(struct frames *frames) {
SDL_assert(!frames->rendering_frame_consumed);
frames->rendering_frame_consumed = SDL_TRUE;
#ifndef SKIP_FRAMES
// if SKIP_FRAMES is disabled, then notify the decoder the current frame is
// consumed, so that it may push a new one
cond_signal(frames->rendering_frame_consumed_cond);
#endif
return frames->rendering_frame;
}