mirror of
https://github.com/vanilla-wiiu/vanilla.git
synced 2026-10-28 09:43:51 +00:00
gui: add support for v4l2request hardware decoding (orange pi)
This commit is contained in:
1 parent
dc28618301
commit
063e3cba67
3 files changed
+83
-2
No files matched your search
@@ -403,6 +403,14 @@ target_link_libraries(vanillagui PRIVATE
|
||||
${_vanilla_gui_libs}
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
option(VANILLA_BUILD_USE_V4L2REQUEST "Enable V4L2 Request API (Orange Pi/Cedrus)" OFF)
|
||||
if (VANILLA_BUILD_USE_V4L2REQUEST)
|
||||
target_compile_definitions(vanillagui PRIVATE VANILLA_V4L2REQUEST_AVAILABLE)
|
||||
target_link_libraries(vanillagui PRIVATE udev drm)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
target_link_libraries(vanillagui PRIVATE "-framework VideoToolbox" "-framework CoreMedia" iconv)
|
||||
endif()
|
||||
|
||||
@@ -18,6 +18,13 @@
|
||||
#include "ui/ui_anim.h"
|
||||
#include "ui/ui_util.h"
|
||||
|
||||
#ifdef VANILLA_V4L2REQUEST_AVAILABLE
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/videodev2.h>
|
||||
#endif
|
||||
|
||||
static char vpi_toast_string[VPI_TOAST_MAX_LEN];
|
||||
static struct timeval vpi_toast_expiry;
|
||||
static int vpi_toast_number = 0;
|
||||
@@ -223,11 +230,50 @@ typedef struct {
|
||||
enum HwDecoderType {
|
||||
HWDEC_TYPE_NVDEC,
|
||||
HWDEC_TYPE_VAAPI,
|
||||
HWDEC_TYPE_V4L2REQUEST,
|
||||
HWDEC_TYPE_DRM,
|
||||
HWDEC_TYPE_SOFTWARE,
|
||||
HWDEC_TYPE_COUNT
|
||||
};
|
||||
|
||||
#ifdef VANILLA_V4L2REQUEST_AVAILABLE
|
||||
static int is_v4l2request_available(void)
|
||||
{
|
||||
char path[32];
|
||||
for (int i = 0; i < 64; i++) {
|
||||
snprintf(path, sizeof(path), "/dev/video%d", i);
|
||||
int fd = open(path, O_RDWR | O_NONBLOCK);
|
||||
if (fd < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int found = 0;
|
||||
for (int t = 0; t < 2; t++) {
|
||||
struct v4l2_fmtdesc desc;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.type = (t == 0) ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
|
||||
: V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||
for (desc.index = 0; ioctl(fd, VIDIOC_ENUM_FMT, &desc) == 0; desc.index++) {
|
||||
if (desc.pixelformat == V4L2_PIX_FMT_H264_SLICE) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
if (found) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // VANILLA_V4L2REQUEST_AVAILABLE
|
||||
|
||||
void vpi_decode_exit(vpi_decode_state_t *s)
|
||||
{
|
||||
if (s->frame)
|
||||
@@ -303,6 +349,8 @@ int vpi_decode_init(vpi_decode_state_t *s)
|
||||
{
|
||||
int ffmpeg_err;
|
||||
|
||||
// av_log_set_level(AV_LOG_VERBOSE);
|
||||
|
||||
// Initialize decoding context, preferring hardware decoding when available
|
||||
hwdec_t decoders[HWDEC_TYPE_COUNT];
|
||||
|
||||
@@ -314,6 +362,10 @@ int vpi_decode_init(vpi_decode_state_t *s)
|
||||
decoders[HWDEC_TYPE_VAAPI].codec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
||||
decoders[HWDEC_TYPE_VAAPI].get_format = vaapi_get_format;
|
||||
|
||||
decoders[HWDEC_TYPE_V4L2REQUEST].name = "V4L2 Request";
|
||||
decoders[HWDEC_TYPE_V4L2REQUEST].codec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
||||
decoders[HWDEC_TYPE_V4L2REQUEST].get_format = drm_get_format;
|
||||
|
||||
decoders[HWDEC_TYPE_DRM].name = "DRM";
|
||||
decoders[HWDEC_TYPE_DRM].codec = avcodec_find_decoder_by_name("h264_v4l2m2m");
|
||||
decoders[HWDEC_TYPE_DRM].get_format = drm_get_format;
|
||||
@@ -345,6 +397,15 @@ int vpi_decode_init(vpi_decode_state_t *s)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VANILLA_V4L2REQUEST_AVAILABLE
|
||||
if (r != VANILLA_SUCCESS && is_v4l2request_available()) {
|
||||
vpi_decode_exit(s);
|
||||
if ((ffmpeg_err = av_hwdevice_ctx_create(&s->hw_device_ctx, AV_HWDEVICE_TYPE_V4L2REQUEST, NULL, NULL, 0)) >= 0) {
|
||||
r = open_decoder(s, &decoders[HWDEC_TYPE_V4L2REQUEST]);
|
||||
}
|
||||
}
|
||||
#endif // VANILLA_V4L2REQUEST_AVAILABLE
|
||||
|
||||
// See if we can create a DRM context (Raspberry Pi, et al.)
|
||||
if (r != VANILLA_SUCCESS) {
|
||||
vpi_decode_exit(s);
|
||||
|
||||
+14
-2
@@ -82,6 +82,7 @@ typedef struct {
|
||||
SDL_Texture *toast_tex;
|
||||
struct timeval toast_expiry;
|
||||
AVFrame *frame;
|
||||
AVFrame *held_frame; // keeps the displayed dmabuf alive until the next frame replaces it
|
||||
SDL_Texture *pw_tex;
|
||||
|
||||
uint8_t audio_buffer[AUDIO_BUFFER_COUNT][AUDIO_BUFFER_SIZE];
|
||||
@@ -888,6 +889,7 @@ int vui_init_sdl(vui_context_t *ctx, int fullscreen)
|
||||
#endif
|
||||
|
||||
sdl_ctx->frame = av_frame_alloc();
|
||||
sdl_ctx->held_frame = av_frame_alloc();
|
||||
|
||||
// Initialize gamepad lookup tables
|
||||
init_gamepad(ctx);
|
||||
@@ -903,6 +905,7 @@ void vui_close_sdl(vui_context_t *ctx)
|
||||
}
|
||||
|
||||
av_frame_free(&sdl_ctx->frame);
|
||||
av_frame_free(&sdl_ctx->held_frame);
|
||||
|
||||
#ifdef VANILLA_NX_IMU
|
||||
vpi_nx_imu_quit();
|
||||
@@ -1798,7 +1801,14 @@ int get_texture_from_drm_prime_frame(vui_sdl_context_t *sdl_ctx, AVFrame *f)
|
||||
}
|
||||
}
|
||||
|
||||
EGLAttrib use_fmt = layer->format == DRM_FORMAT_YUV420 ? DRM_FORMAT_R8 : layer->format;
|
||||
EGLAttrib use_fmt;
|
||||
if (layer->format == DRM_FORMAT_YUV420) {
|
||||
use_fmt = DRM_FORMAT_R8;
|
||||
} else if (layer->format == DRM_FORMAT_NV12) {
|
||||
use_fmt = (image_index == 0) ? DRM_FORMAT_R8 : DRM_FORMAT_GR88;
|
||||
} else {
|
||||
use_fmt = layer->format;
|
||||
}
|
||||
|
||||
int w = f->width;
|
||||
int h = f->height;
|
||||
@@ -1966,7 +1976,9 @@ int vui_update_sdl(vui_context_t *vui)
|
||||
get_texture_from_cpu_frame(sdl_ctx, sdl_ctx->frame);
|
||||
break;
|
||||
}
|
||||
av_frame_unref(sdl_ctx->frame);
|
||||
|
||||
av_frame_unref(sdl_ctx->held_frame);
|
||||
av_frame_move_ref(sdl_ctx->held_frame, sdl_ctx->frame);
|
||||
|
||||
if (sdl_ctx->game_tex) {
|
||||
if (handle_final_blit) {
|
||||
|
||||
Reference in new issue
Block a user