This commit is contained in:
itsmattkc 2024-10-23 20:47:03 -07:00
parent 02879479e5
commit 9b4620f0e0
4 changed files with 78 additions and 29 deletions

4
.gitignore vendored
View file

@ -1,7 +1,9 @@
build/
buildpi/
.vscode/
.directory
.cache/
*.AppImage
squashfs-root/
buildpi/
rpi-ffmpeg/

View file

@ -1,15 +1,38 @@
#include "drm.h"
#include <drm_fourcc.h>
#include <fcntl.h>
#include <libavutil/hwcontext_drm.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#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;
}

View file

@ -2,6 +2,7 @@
#define VANILLA_PI_DRM_H
#include <libavutil/frame.h>
#include <linux/kd.h>
#include <stdint.h>
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);

View file

@ -8,6 +8,7 @@
#include <libavfilter/buffersrc.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <semaphore.h>
#include <signal.h>
#include <stdio.h>
#include <SDL2/SDL.h>
@ -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);