mirror of
https://github.com/moonlight-stream/moonlight-embedded.git
synced 2025-07-03 16:25:31 +00:00
Buffer frame to sync with vsync in SDL
This commit is contained in:
parent
bea030c52b
commit
a85d6105b8
11
src/sdl.c
11
src/sdl.c
@ -33,7 +33,11 @@ static SDL_Texture *bmp;
|
|||||||
|
|
||||||
SDL_mutex *mutex;
|
SDL_mutex *mutex;
|
||||||
|
|
||||||
|
int sdlCurrentFrame, sdlNextFrame;
|
||||||
|
|
||||||
void sdl_init(int width, int height, bool fullscreen) {
|
void sdl_init(int width, int height, bool fullscreen) {
|
||||||
|
sdlCurrentFrame = sdlNextFrame = 0;
|
||||||
|
|
||||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
|
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
|
||||||
fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
|
fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -65,7 +69,6 @@ void sdl_init(int width, int height, bool fullscreen) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sdlinput_init();
|
sdlinput_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,14 +93,16 @@ void sdl_loop() {
|
|||||||
done = true;
|
done = true;
|
||||||
else if (event.type == SDL_USEREVENT) {
|
else if (event.type == SDL_USEREVENT) {
|
||||||
if (event.user.code == SDL_CODE_FRAME) {
|
if (event.user.code == SDL_CODE_FRAME) {
|
||||||
if (SDL_LockMutex(mutex) == 0) {
|
if (++sdlCurrentFrame <= sdlNextFrame - SDL_BUFFER_FRAMES) {
|
||||||
|
//Skip frame
|
||||||
|
} else if (SDL_LockMutex(mutex) == 0) {
|
||||||
Uint8** data = ((Uint8**) event.user.data1);
|
Uint8** data = ((Uint8**) event.user.data1);
|
||||||
int* linesize = ((int*) event.user.data2);
|
int* linesize = ((int*) event.user.data2);
|
||||||
SDL_UpdateYUVTexture(bmp, NULL, data[0], linesize[0], data[1], linesize[1], data[2], linesize[2]);
|
SDL_UpdateYUVTexture(bmp, NULL, data[0], linesize[0], data[1], linesize[1], data[2], linesize[2]);
|
||||||
|
SDL_UnlockMutex(mutex);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
SDL_RenderCopy(renderer, bmp, NULL, NULL);
|
SDL_RenderCopy(renderer, bmp, NULL, NULL);
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
SDL_UnlockMutex(mutex);
|
|
||||||
} else
|
} else
|
||||||
fprintf(stderr, "Couldn't lock mutex\n");
|
fprintf(stderr, "Couldn't lock mutex\n");
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,12 @@
|
|||||||
|
|
||||||
#define SDL_CODE_FRAME 0
|
#define SDL_CODE_FRAME 0
|
||||||
|
|
||||||
|
#define SDL_BUFFER_FRAMES 2
|
||||||
|
|
||||||
void sdl_init(int width, int height, bool fullscreen);
|
void sdl_init(int width, int height, bool fullscreen);
|
||||||
void sdl_loop();
|
void sdl_loop();
|
||||||
|
|
||||||
SDL_mutex *mutex;
|
SDL_mutex *mutex;
|
||||||
|
int sdlCurrentFrame, sdlNextFrame;
|
||||||
|
|
||||||
#endif /* HAVE_SDL */
|
#endif /* HAVE_SDL */
|
||||||
|
@ -35,7 +35,10 @@
|
|||||||
static AVPacket pkt;
|
static AVPacket pkt;
|
||||||
static AVCodec* decoder;
|
static AVCodec* decoder;
|
||||||
static AVCodecContext* decoder_ctx;
|
static AVCodecContext* decoder_ctx;
|
||||||
static AVFrame* dec_frame;
|
static AVFrame** dec_frames;
|
||||||
|
|
||||||
|
static int dec_frames_cnt;
|
||||||
|
static int current_frame, next_frame;
|
||||||
|
|
||||||
enum decoders {SOFTWARE, VDPAU};
|
enum decoders {SOFTWARE, VDPAU};
|
||||||
enum decoders decoder_system;
|
enum decoders decoder_system;
|
||||||
@ -44,7 +47,7 @@ enum decoders decoder_system;
|
|||||||
|
|
||||||
// This function must be called before
|
// This function must be called before
|
||||||
// any other decoding functions
|
// any other decoding functions
|
||||||
int ffmpeg_init(int videoFormat, int width, int height, int perf_lvl, int thread_count) {
|
int ffmpeg_init(int videoFormat, int width, int height, int perf_lvl, int buffer_count, int thread_count) {
|
||||||
// Initialize the avcodec library and register codecs
|
// Initialize the avcodec library and register codecs
|
||||||
av_log_set_level(AV_LOG_QUIET);
|
av_log_set_level(AV_LOG_QUIET);
|
||||||
avcodec_register_all();
|
avcodec_register_all();
|
||||||
@ -114,12 +117,21 @@ int ffmpeg_init(int videoFormat, int width, int height, int perf_lvl, int thread
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
dec_frame = av_frame_alloc();
|
dec_frames_cnt = buffer_count;
|
||||||
if (dec_frame == NULL) {
|
dec_frames = malloc(buffer_count * sizeof(AVFrame*));
|
||||||
printf("Couldn't allocate frame");
|
if (dec_frames == NULL) {
|
||||||
|
fprintf(stderr, "Couldn't allocate frames");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < buffer_count; i++) {
|
||||||
|
dec_frames[i] = av_frame_alloc();
|
||||||
|
if (dec_frames[i] == NULL) {
|
||||||
|
fprintf(stderr, "Couldn't allocate frame");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_VDPAU
|
#ifdef HAVE_VDPAU
|
||||||
if (decoder_system == VDPAU)
|
if (decoder_system == VDPAU)
|
||||||
vdpau_init(decoder_ctx, width, height);
|
vdpau_init(decoder_ctx, width, height);
|
||||||
@ -136,18 +148,20 @@ void ffmpeg_destroy(void) {
|
|||||||
av_free(decoder_ctx);
|
av_free(decoder_ctx);
|
||||||
decoder_ctx = NULL;
|
decoder_ctx = NULL;
|
||||||
}
|
}
|
||||||
if (dec_frame) {
|
if (dec_frames) {
|
||||||
av_frame_free(&dec_frame);
|
for (int i = 0; i < dec_frames_cnt; i++) {
|
||||||
dec_frame = NULL;
|
if (dec_frames[i])
|
||||||
|
av_frame_free(&dec_frames[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AVFrame* ffmpeg_get_frame() {
|
AVFrame* ffmpeg_get_frame() {
|
||||||
if (decoder_system == SOFTWARE)
|
if (decoder_system == SOFTWARE)
|
||||||
return dec_frame;
|
return dec_frames[current_frame];
|
||||||
#ifdef HAVE_VDPAU
|
#ifdef HAVE_VDPAU
|
||||||
else if (decoder_system == VDPAU)
|
else if (decoder_system == VDPAU)
|
||||||
return vdpau_get_frame(dec_frame);
|
return vdpau_get_frame(dec_frames[current_frame]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +176,7 @@ int ffmpeg_decode(unsigned char* indata, int inlen) {
|
|||||||
|
|
||||||
while (pkt.size > 0) {
|
while (pkt.size > 0) {
|
||||||
got_pic = 0;
|
got_pic = 0;
|
||||||
err = avcodec_decode_video2(decoder_ctx, dec_frame, &got_pic, &pkt);
|
err = avcodec_decode_video2(decoder_ctx, dec_frames[next_frame], &got_pic, &pkt);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
char errorstring[512];
|
char errorstring[512];
|
||||||
av_strerror(err, errorstring, sizeof(errorstring));
|
av_strerror(err, errorstring, sizeof(errorstring));
|
||||||
@ -176,6 +190,8 @@ int ffmpeg_decode(unsigned char* indata, int inlen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (got_pic) {
|
if (got_pic) {
|
||||||
|
current_frame = next_frame;
|
||||||
|
next_frame = (current_frame+1) % dec_frames_cnt;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
// Uses hardware acceleration
|
// Uses hardware acceleration
|
||||||
#define HARDWARE_ACCELERATION 0x40
|
#define HARDWARE_ACCELERATION 0x40
|
||||||
|
|
||||||
int ffmpeg_init(int videoFormat, int width, int height, int perf_lvl, int thread_count);
|
int ffmpeg_init(int videoFormat, int width, int height, int perf_lvl, int buffer_count, int thread_count);
|
||||||
void ffmpeg_destroy(void);
|
void ffmpeg_destroy(void);
|
||||||
|
|
||||||
int ffmpeg_draw_frame(AVFrame *pict);
|
int ffmpeg_draw_frame(AVFrame *pict);
|
||||||
|
@ -37,7 +37,7 @@ static void sdl_setup(int videoFormat, int width, int height, int redrawRate, vo
|
|||||||
if (drFlags & FORCE_HARDWARE_ACCELERATION)
|
if (drFlags & FORCE_HARDWARE_ACCELERATION)
|
||||||
avc_flags |= HARDWARE_ACCELERATION;
|
avc_flags |= HARDWARE_ACCELERATION;
|
||||||
|
|
||||||
if (ffmpeg_init(videoFormat, width, height, avc_flags, 2) < 0) {
|
if (ffmpeg_init(videoFormat, width, height, avc_flags, SDL_BUFFER_FRAMES, 2) < 0) {
|
||||||
fprintf(stderr, "Couldn't initialize video decoding\n");
|
fprintf(stderr, "Couldn't initialize video decoding\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -66,6 +66,7 @@ static int sdl_submit_decode_unit(PDECODE_UNIT decodeUnit) {
|
|||||||
if (SDL_LockMutex(mutex) == 0) {
|
if (SDL_LockMutex(mutex) == 0) {
|
||||||
int ret = ffmpeg_decode(ffmpeg_buffer, length);
|
int ret = ffmpeg_decode(ffmpeg_buffer, length);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
|
sdlNextFrame++;
|
||||||
AVFrame* frame = ffmpeg_get_frame();
|
AVFrame* frame = ffmpeg_get_frame();
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user