diff --git a/.gitignore b/.gitignore index 610e7f7..a2fce26 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ build/ -buildpi/ .vscode/ .directory .cache/ *.AppImage squashfs-root/ + +buildpi/ +rpi-ffmpeg/ diff --git a/rpi/drm.c b/rpi/drm.c index c5417f7..75f1eff 100644 --- a/rpi/drm.c +++ b/rpi/drm.c @@ -1,15 +1,38 @@ #include "drm.h" #include +#include #include +#include #include #include +#include #include #include #define DRM_FORMAT_MAX_PLANES 4u #define ALIGN(x, a) ((x) + (a - 1)) & (~(a - 1)) +int set_tty(int mode) +{ + /*int tty_fd = open("/dev/tty", O_RDWR); + if (tty_fd == -1) { + fprintf(stderr, "Failed to open /dev/tty\n"); + return 0; + } + if (ioctl(tty_fd, KDSETMODE, mode) < 0) { + fprintf(stderr, "Failed to set KDSETMODE: %s (%i)\n", strerror(errno), errno); + return 0; + } + close(tty_fd);*/ + + if (ioctl(STDIN_FILENO, KDSETMODE, mode) < 0) { + fprintf(stderr, "Failed to set KDSETMODE: %s (%i)\n", strerror(errno), errno); + return 0; + } + return 1; +} + int initialize_drm(vanilla_drm_ctx_t *ctx) { // Open DRM @@ -18,6 +41,10 @@ int initialize_drm(vanilla_drm_ctx_t *ctx) return 0; } + if (!set_tty(KD_GRAPHICS)) { + return 0; + } + int ret = 0; // Find DRM output @@ -54,7 +81,6 @@ int initialize_drm(vanilla_drm_ctx_t *ctx) ctx->got_plane = 0; ctx->got_fb = 0; - ctx->frame = av_frame_alloc();; return ret; } @@ -65,9 +91,7 @@ int free_drm(vanilla_drm_ctx_t *ctx) drmModeRmFB(ctx->fd, ctx->fb_id); } - if (ctx->frame) { - av_frame_free(&ctx->frame); - } + set_tty(KD_TEXT); // Close DRM drmClose(ctx->fd); @@ -123,11 +147,12 @@ static int find_plane(const int drmfd, const int crtcidx, const uint32_t format, extern int running; int display_drm(vanilla_drm_ctx_t *ctx, AVFrame *frame) { - av_frame_unref(ctx->frame); - av_frame_ref(ctx->frame, frame); - const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *) frame->data[0]; - const uint32_t format = desc->layers[0].format; + /*if (!desc) { + return 1; + }*/ + + const uint32_t format = desc->layers[0].format; if (!ctx->got_plane) { if (find_plane(ctx->fd, ctx->crtc_index, format, &ctx->plane_id) < 0) { @@ -143,7 +168,10 @@ int display_drm(vanilla_drm_ctx_t *ctx, AVFrame *frame) vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; while (running && drmWaitVBlank(ctx->fd, &vbl)) { - // TODO: Break if not EINTR? + // Not sure what this does, stole it from hello_drmprime + if (errno != EINTR) { + break; + } } } @@ -194,7 +222,7 @@ int display_drm(vanilla_drm_ctx_t *ctx, AVFrame *frame) } } - fprintf(stderr, "%dx%d, fmt: %x, boh=%d,%d,%d,%d, pitch=%d,%d,%d,%d," + /*fprintf(stderr, "%dx%d, fmt: %x, boh=%d,%d,%d,%d, pitch=%d,%d,%d,%d," " offset=%d,%d,%d,%d, mod=%llx,%llx,%llx,%llx\n", frame->width, frame->height, @@ -215,7 +243,7 @@ int display_drm(vanilla_drm_ctx_t *ctx, AVFrame *frame) (long long)modifiers[1], (long long)modifiers[2], (long long)modifiers[3] - ); + );*/ if (drmModeAddFB2WithModifiers(ctx->fd, @@ -235,7 +263,5 @@ int display_drm(vanilla_drm_ctx_t *ctx, AVFrame *frame) return 0; } - printf("Set planes!!!\n"); - return 1; } \ No newline at end of file diff --git a/rpi/drm.h b/rpi/drm.h index ff8370c..9434d03 100644 --- a/rpi/drm.h +++ b/rpi/drm.h @@ -2,6 +2,7 @@ #define VANILLA_PI_DRM_H #include +#include #include typedef struct { @@ -12,9 +13,9 @@ typedef struct { int got_plane; uint32_t fb_id; int got_fb; - AVFrame *frame; } vanilla_drm_ctx_t; +int set_tty(int mode); int initialize_drm(vanilla_drm_ctx_t *ctx); int free_drm(vanilla_drm_ctx_t *ctx); int display_drm(vanilla_drm_ctx_t *ctx, AVFrame *frame); diff --git a/rpi/main.c b/rpi/main.c index c83ccd9..3921967 100644 --- a/rpi/main.c +++ b/rpi/main.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -18,8 +19,8 @@ AVFrame *present_frame; AVFrame *decoding_frame; +sem_t decoding_sem; SDL_mutex *decoding_mutex; -int decoding_ready = 0; AVCodecContext *video_codec_ctx; AVCodecParserContext *video_parser; AVPacket *video_packet; @@ -47,7 +48,7 @@ int decode_frame(const void *data, size_t size) int err; // Parse this data for packets - err = av_packet_from_data(video_packet, data, size); + err = av_packet_from_data(video_packet, (uint8_t *) data, size); if (err < 0) { fprintf(stderr, "Failed to initialize AVPacket from data: %s (%i)\n", av_err2str(err), err); return 0; @@ -72,23 +73,27 @@ int decode_frame(const void *data, size_t size) fprintf(stderr, "Failed to receive frame from decoder: %i\n", err); ret = 0; break; + } else if (!decoding_frame->data[0]) { + fprintf(stderr, "WE GOT A NULL DATA[0] STRAIGHT FROM THE DECODER?????\n"); + abort(); + } else if ((decoding_frame->flags & AV_FRAME_FLAG_CORRUPT) != 0) { + fprintf(stderr, "GOT A CORRUPT FRAME??????\n"); + abort(); } else { SDL_LockMutex(decoding_mutex); // Swap frames - AVFrame *tmp = decoding_frame; - decoding_frame = present_frame; - present_frame = tmp; + av_frame_unref(present_frame); + av_frame_ref(present_frame, decoding_frame); - printf("Frame decoded (%i), sent to display...\n", present_frame->format); - - // Signal we have a frame - decoding_ready = 1; - - SDL_UnlockMutex(decoding_mutex); + // printf("Frame decoded (%i), sent to display...\n", present_frame->format); // Un-ref frame av_frame_unref(decoding_frame); + + SDL_UnlockMutex(decoding_mutex); + + sem_post(&decoding_sem); } } @@ -123,14 +128,19 @@ int display_loop(void *data) Uint32 tick_deltas[TICK_MAX]; size_t tick_delta_index = 0; + AVFrame *frame = av_frame_alloc(); + while (running) { + sem_wait(&decoding_sem); + // If a frame is available, present it here SDL_LockMutex(decoding_mutex); - if (decoding_ready) { - display_drm(drm_ctx, present_frame); - } + av_frame_unref(frame); + av_frame_ref(frame, present_frame); SDL_UnlockMutex(decoding_mutex); + display_drm(drm_ctx, frame); + // FPS counter stuff Uint32 now = SDL_GetTicks(); tick_deltas[tick_delta_index] = (now - start_ticks); @@ -149,6 +159,8 @@ int display_loop(void *data) } } + av_frame_free(&frame); + return 0; } @@ -166,6 +178,8 @@ SDL_GameController *find_valid_controller() void sigint_handler(int signum) { + set_tty(KD_TEXT); + printf("Received SIGINT...\n"); running = 0; @@ -173,6 +187,8 @@ void sigint_handler(int signum) ev.type = SDL_QUIT; ev.timestamp = SDL_GetTicks(); SDL_PushEvent((SDL_Event *) &ev); + + sem_post(&decoding_sem); } int main(int argc, const char **argv) @@ -256,6 +272,8 @@ int main(int argc, const char **argv) running = 1; signal(SIGINT, sigint_handler); + sem_init(&decoding_sem, 0, 0); + // Start background threads SDL_Thread *backend_thread = SDL_CreateThread(run_backend, "Backend", NULL); SDL_Thread *display_thread = SDL_CreateThread(display_loop, "Display", &drm_ctx); @@ -332,6 +350,8 @@ int main(int argc, const char **argv) SDL_WaitThread(backend_thread, NULL); SDL_WaitThread(display_thread, NULL); + sem_destroy(&decoding_sem); + av_parser_close(video_parser); av_frame_free(&present_frame); av_frame_free(&decoding_frame);