mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2023-10-10 13:37:41 +02:00
Prepare for v4l2m2m for Raspi 4
This commit is contained in:
parent
d1bc51edb8
commit
463109fcb6
46
codec.c
46
codec.c
@ -143,7 +143,6 @@ static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx, const enu
|
|||||||
enum AVPixelFormat fmt1;
|
enum AVPixelFormat fmt1;
|
||||||
|
|
||||||
decoder = video_ctx->opaque;
|
decoder = video_ctx->opaque;
|
||||||
|
|
||||||
// bug in ffmpeg 1.1.1, called with zero width or height
|
// bug in ffmpeg 1.1.1, called with zero width or height
|
||||||
if (!video_ctx->width || !video_ctx->height) {
|
if (!video_ctx->width || !video_ctx->height) {
|
||||||
Error("codec/video: ffmpeg/libav buggy: width or height zero\n");
|
Error("codec/video: ffmpeg/libav buggy: width or height zero\n");
|
||||||
@ -258,6 +257,20 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RASPI
|
||||||
|
switch (codec_id) {
|
||||||
|
case AV_CODEC_ID_MPEG2VIDEO:
|
||||||
|
name = "mpeg2_v4l2m2m";
|
||||||
|
break;
|
||||||
|
case AV_CODEC_ID_H264:
|
||||||
|
name = "h264_v4l2m2m";
|
||||||
|
// name = "h264_mmal";
|
||||||
|
break;
|
||||||
|
case AV_CODEC_ID_HEVC:
|
||||||
|
name = "hevc_v4l2m2m";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
|
if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
|
||||||
Debug(3, "codec: decoder found\n");
|
Debug(3, "codec: decoder found\n");
|
||||||
} else if ((video_codec = avcodec_find_decoder(codec_id)) == NULL) {
|
} else if ((video_codec = avcodec_find_decoder(codec_id)) == NULL) {
|
||||||
@ -272,10 +285,16 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
if (!(decoder->VideoCtx = avcodec_alloc_context3(video_codec))) {
|
if (!(decoder->VideoCtx = avcodec_alloc_context3(video_codec))) {
|
||||||
Fatal(_("codec: can't allocate video codec context\n"));
|
Fatal(_("codec: can't allocate video codec context\n"));
|
||||||
}
|
}
|
||||||
if (!HwDeviceContext) {
|
|
||||||
Fatal("codec: no hw device context to be used");
|
#ifndef RASPI
|
||||||
|
if (!HwDeviceContext) {
|
||||||
|
Fatal("codec: no hw device context to be used");
|
||||||
}
|
}
|
||||||
decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext);
|
decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext);
|
||||||
|
#else
|
||||||
|
decoder->VideoCtx->pix_fmt = AV_PIX_FMT_DRM_PRIME; /* request a DRM frame
|
||||||
|
// decoder->VideoCtx->pix_fmt = AV_PIX_FMT_MMAL; /* request a DRM frame */
|
||||||
|
#endif
|
||||||
|
|
||||||
// FIXME: for software decoder use all cpus, otherwise 1
|
// FIXME: for software decoder use all cpus, otherwise 1
|
||||||
decoder->VideoCtx->thread_count = 1;
|
decoder->VideoCtx->thread_count = 1;
|
||||||
@ -290,7 +309,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
#ifdef YADIF
|
#ifdef YADIF
|
||||||
deint = 2;
|
deint = 2;
|
||||||
#endif
|
#endif
|
||||||
#ifdef VAAPI
|
#if defined VAAPI && !defined RASPI
|
||||||
decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
|
decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
|
||||||
if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) {
|
if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) {
|
||||||
Debug(3, "codec: auto threads enabled");
|
Debug(3, "codec: auto threads enabled");
|
||||||
@ -318,6 +337,21 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0)
|
if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0)
|
||||||
Fatal(_("VAAPI Refcounts invalid\n"));
|
Fatal(_("VAAPI Refcounts invalid\n"));
|
||||||
decoder->VideoCtx->thread_safe_callbacks = 0;
|
decoder->VideoCtx->thread_safe_callbacks = 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RASPI
|
||||||
|
decoder->VideoCtx->codec_id = codec_id;
|
||||||
|
decoder->VideoCtx->flags |= AV_CODEC_FLAG_BITEXACT;
|
||||||
|
if (video_codec->capabilities & AV_CODEC_CAP_FRAME_THREADS || AV_CODEC_CAP_SLICE_THREADS) {
|
||||||
|
Debug(3, "codec: supports frame threads");
|
||||||
|
decoder->VideoCtx->thread_count = 4;
|
||||||
|
// decoder->VideoCtx->thread_type |= FF_THREAD_FRAME;
|
||||||
|
}
|
||||||
|
if (video_codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
|
||||||
|
Debug(3, "codec: supports slice threads");
|
||||||
|
decoder->VideoCtx->thread_type |= FF_THREAD_SLICE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CUVID
|
#ifdef CUVID
|
||||||
@ -367,7 +401,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
//decoder->VideoCtx->debug = FF_DEBUG_STARTCODE;
|
//decoder->VideoCtx->debug = FF_DEBUG_STARTCODE;
|
||||||
//decoder->VideoCtx->err_recognition |= AV_EF_EXPLODE;
|
//decoder->VideoCtx->err_recognition |= AV_EF_EXPLODE;
|
||||||
|
|
||||||
// av_log_set_level(AV_LOG_DEBUG);
|
//av_log_set_level(AV_LOG_DEBUG);
|
||||||
av_log_set_level(0);
|
av_log_set_level(0);
|
||||||
|
|
||||||
decoder->VideoCtx->get_format = Codec_get_format;
|
decoder->VideoCtx->get_format = Codec_get_format;
|
||||||
@ -387,7 +421,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
|
|
||||||
// reset buggy ffmpeg/libav flag
|
// reset buggy ffmpeg/libav flag
|
||||||
decoder->GetFormatDone = 0;
|
decoder->GetFormatDone = 0;
|
||||||
#ifdef YADIF
|
#if defined (YADIF) || defined (RASPI)
|
||||||
decoder->filter = 0;
|
decoder->filter = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
13
drm.c
13
drm.c
@ -198,8 +198,11 @@ static int FindDevice(VideoRender * render)
|
|||||||
int i,ii=0;
|
int i,ii=0;
|
||||||
char connectorstr[10];
|
char connectorstr[10];
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
#ifdef RASPI
|
||||||
render->fd_drm = open("/dev/dri/card0", O_RDWR);
|
render->fd_drm = open("/dev/dri/card1", O_RDWR);
|
||||||
|
#else
|
||||||
|
render->fd_drm = open("/dev/dri/card0", O_RDWR);
|
||||||
|
#endif
|
||||||
if (render->fd_drm < 0) {
|
if (render->fd_drm < 0) {
|
||||||
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n");
|
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n");
|
||||||
return -errno;
|
return -errno;
|
||||||
@ -339,7 +342,11 @@ static int FindDevice(VideoRender * render)
|
|||||||
for (k = 0; k < plane->count_formats; k++) {
|
for (k = 0; k < plane->count_formats; k++) {
|
||||||
if (encoder->possible_crtcs & plane->possible_crtcs) {
|
if (encoder->possible_crtcs & plane->possible_crtcs) {
|
||||||
switch (plane->formats[k]) {
|
switch (plane->formats[k]) {
|
||||||
case DRM_FORMAT_XRGB2101010:
|
#ifdef RASPI
|
||||||
|
case DRM_FORMAT_ARGB8888:
|
||||||
|
#else
|
||||||
|
case DRM_FORMAT_XRGB2101010:
|
||||||
|
#endif
|
||||||
if (!render->video_plane) {
|
if (!render->video_plane) {
|
||||||
render->video_plane = plane->plane_id;
|
render->video_plane = plane->plane_id;
|
||||||
}
|
}
|
||||||
|
103
shaders.h
103
shaders.h
@ -88,8 +88,109 @@ color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
|
|||||||
color.rgb = pow(color.rgb, vec3(1.0/2.4));\n\
|
color.rgb = pow(color.rgb, vec3(1.0/2.4));\n\
|
||||||
out_color = color;\n\
|
out_color = color;\n\
|
||||||
}\n" };
|
}\n" };
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#ifdef RASPI
|
||||||
|
char vertex_osd[] = {"\
|
||||||
|
#version 300 es\n\
|
||||||
|
in vec2 vertex_position;\n\
|
||||||
|
in vec2 vertex_texcoord0;\n\
|
||||||
|
out vec2 texcoord0;\n\
|
||||||
|
void main() {\n\
|
||||||
|
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
|
||||||
|
texcoord0 = vertex_texcoord0;\n\
|
||||||
|
}\n"};
|
||||||
|
|
||||||
|
char fragment_osd[] = {"\
|
||||||
|
#version 300 es\n\
|
||||||
|
#define texture1D texture\n\
|
||||||
|
precision mediump float; \
|
||||||
|
layout(location = 0) out vec4 out_color;\n\
|
||||||
|
in vec2 texcoord0;\n\
|
||||||
|
uniform sampler2D texture0;\n\
|
||||||
|
void main() {\n\
|
||||||
|
vec4 color; \n\
|
||||||
|
color = vec4(texture(texture0, texcoord0));\n\
|
||||||
|
out_color = color;\n\
|
||||||
|
}\n"};
|
||||||
|
|
||||||
|
char vertex[] = {"\
|
||||||
|
#version 300 es\n\
|
||||||
|
in vec2 vertex_position;\n\
|
||||||
|
in vec2 vertex_texcoord0;\n\
|
||||||
|
out vec2 texcoord0;\n\
|
||||||
|
in vec2 vertex_texcoord1;\n\
|
||||||
|
out vec2 texcoord1;\n\
|
||||||
|
in vec2 vertex_texcoord2;\n\
|
||||||
|
out vec2 texcoord2;\n\
|
||||||
|
void main() {\n\
|
||||||
|
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
|
||||||
|
texcoord0 = vertex_texcoord0;\n\
|
||||||
|
texcoord1 = vertex_texcoord1;\n\
|
||||||
|
texcoord2 = vertex_texcoord1;\n\
|
||||||
|
}\n"};
|
||||||
|
|
||||||
|
char fragment[] = {"\
|
||||||
|
#version 300 es\n\
|
||||||
|
#define texture1D texture\n\
|
||||||
|
#define texture3D texture\n\
|
||||||
|
precision mediump float; \
|
||||||
|
layout(location = 0) out vec4 out_color;\n\
|
||||||
|
in vec2 texcoord0;\n\
|
||||||
|
in vec2 texcoord1;\n\
|
||||||
|
in vec2 texcoord2;\n\
|
||||||
|
uniform mat3 colormatrix;\n\
|
||||||
|
uniform vec3 colormatrix_c;\n\
|
||||||
|
uniform sampler2D texture0;\n\
|
||||||
|
uniform sampler2D texture1;\n\
|
||||||
|
uniform sampler2D texture2;\n\
|
||||||
|
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
|
||||||
|
void main() {\n\
|
||||||
|
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
|
||||||
|
color.r = 1.000000 * vec4(texture(texture0, texcoord0)).r;\n\
|
||||||
|
color.g = 1.000000 * vec4(texture(texture1, texcoord1)).r;\n\
|
||||||
|
color.b = 1.000000 * vec4(texture(texture2, texcoord2)).r;\n\
|
||||||
|
// color conversion\n\
|
||||||
|
color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;\n\
|
||||||
|
color.a = 1.0;\n\
|
||||||
|
// color mapping\n\
|
||||||
|
out_color = color;\n\
|
||||||
|
}\n"};
|
||||||
|
|
||||||
|
char fragment_bt2100[] = {"\
|
||||||
|
#version 300 es\n \
|
||||||
|
#define texture1D texture\n\
|
||||||
|
#define texture3D texture\n\
|
||||||
|
precision mediump float; \
|
||||||
|
layout(location = 0) out vec4 out_color;\n\
|
||||||
|
in vec2 texcoord0;\n\
|
||||||
|
in vec2 texcoord1;\n\
|
||||||
|
in vec2 texcoord2;\n\
|
||||||
|
uniform mat3 colormatrix;\n\
|
||||||
|
uniform vec3 colormatrix_c;\n\
|
||||||
|
uniform mat3 cms_matrix;\n\
|
||||||
|
uniform sampler2D texture0;\n\
|
||||||
|
uniform sampler2D texture1;\n\
|
||||||
|
uniform sampler2D texture2;\n\
|
||||||
|
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
|
||||||
|
void main() {\n\
|
||||||
|
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
|
||||||
|
color.r = 1.003906 * vec4(texture(texture0, texcoord0)).r;\n\
|
||||||
|
color.g = 1.003906 * vec4(texture(texture1, texcoord1)).r;\n\
|
||||||
|
color.b = 1.003906 * vec4(texture(texture2, texcoord2)).r;\n\
|
||||||
|
// color conversion\n\
|
||||||
|
color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;\n\
|
||||||
|
color.a = 1.0;\n\
|
||||||
|
// color mapping\n\
|
||||||
|
color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
|
||||||
|
color.rgb = pow(color.rgb, vec3(2.4));\n\
|
||||||
|
color.rgb = cms_matrix * color.rgb;\n\
|
||||||
|
color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
|
||||||
|
color.rgb = pow(color.rgb, vec3(1.0/2.4));\n\
|
||||||
|
out_color = color;\n\
|
||||||
|
}\n"};
|
||||||
|
#endif
|
||||||
|
#if defined VAAPI && !defined RASPI
|
||||||
char vertex_osd[] = { "\
|
char vertex_osd[] = { "\
|
||||||
\n\
|
\n\
|
||||||
in vec2 vertex_position;\n\
|
in vec2 vertex_position;\n\
|
||||||
|
242
video.c
242
video.c
@ -160,6 +160,10 @@ typedef enum
|
|||||||
|
|
||||||
#include <va/va_drmcommon.h>
|
#include <va/va_drmcommon.h>
|
||||||
#include <libavcodec/vaapi.h>
|
#include <libavcodec/vaapi.h>
|
||||||
|
#ifdef RASPI
|
||||||
|
#include <libavutil/hwcontext_drm.h>
|
||||||
|
#include <libdrm/drm_fourcc.h>
|
||||||
|
#endif
|
||||||
#include <libavutil/hwcontext_vaapi.h>
|
#include <libavutil/hwcontext_vaapi.h>
|
||||||
#define TO_AVHW_DEVICE_CTX(x) ((AVHWDeviceContext*)x->data)
|
#define TO_AVHW_DEVICE_CTX(x) ((AVHWDeviceContext*)x->data)
|
||||||
#define TO_AVHW_FRAMES_CTX(x) ((AVHWFramesContext*)x->data)
|
#define TO_AVHW_FRAMES_CTX(x) ((AVHWFramesContext*)x->data)
|
||||||
@ -334,7 +338,7 @@ typedef struct
|
|||||||
|
|
||||||
#define VIDEO_SURFACES_MAX 6 ///< video output surfaces for queue
|
#define VIDEO_SURFACES_MAX 6 ///< video output surfaces for queue
|
||||||
// #define OUTPUT_SURFACES_MAX 4 ///< output surfaces for flip page
|
// #define OUTPUT_SURFACES_MAX 4 ///< output surfaces for flip page
|
||||||
#ifdef VAAPI
|
#if defined VAAPI && !defined RASPI
|
||||||
#define PIXEL_FORMAT AV_PIX_FMT_VAAPI
|
#define PIXEL_FORMAT AV_PIX_FMT_VAAPI
|
||||||
#define SWAP_BUFFER_SIZE 3
|
#define SWAP_BUFFER_SIZE 3
|
||||||
#endif
|
#endif
|
||||||
@ -342,12 +346,22 @@ typedef struct
|
|||||||
#define PIXEL_FORMAT AV_PIX_FMT_CUDA
|
#define PIXEL_FORMAT AV_PIX_FMT_CUDA
|
||||||
#define SWAP_BUFFER_SIZE 1
|
#define SWAP_BUFFER_SIZE 1
|
||||||
#endif
|
#endif
|
||||||
|
#if defined RASPI
|
||||||
|
#define PIXEL_FORMAT AV_PIX_FMT_MMAL
|
||||||
|
#define SWAP_BUFFER_SIZE 3
|
||||||
|
#endif
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Variables
|
// Variables
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
AVBufferRef *HwDeviceContext; ///< ffmpeg HW device context
|
AVBufferRef *HwDeviceContext; ///< ffmpeg HW device context
|
||||||
char VideoIgnoreRepeatPict; ///< disable repeat pict warning
|
char VideoIgnoreRepeatPict; ///< disable repeat pict warning
|
||||||
|
|
||||||
|
#ifdef RASPI
|
||||||
|
int Planes = 3;
|
||||||
|
#else
|
||||||
|
int Planes = 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned char *posd;
|
unsigned char *posd;
|
||||||
|
|
||||||
static const char *VideoDriverName = "cuvid"; ///< video output device
|
static const char *VideoDriverName = "cuvid"; ///< video output device
|
||||||
@ -1551,7 +1565,7 @@ static void CuvidDestroySurfaces(CuvidDecoder * decoder)
|
|||||||
if (decoder->frames[i]) {
|
if (decoder->frames[i]) {
|
||||||
av_frame_free(&decoder->frames[i]);
|
av_frame_free(&decoder->frames[i]);
|
||||||
}
|
}
|
||||||
for (j = 0; j < 2; j++) {
|
for (j = 0; j < Planes; j++) {
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
if (decoder->pl_images[i].planes[j].texture) {
|
if (decoder->pl_images[i].planes[j].texture) {
|
||||||
|
|
||||||
@ -1567,13 +1581,13 @@ static void CuvidDestroySurfaces(CuvidDecoder * decoder)
|
|||||||
checkCudaErrors(cuGraphicsUnregisterResource(decoder->cu_res[i][j]));
|
checkCudaErrors(cuGraphicsUnregisterResource(decoder->cu_res[i][j]));
|
||||||
#endif
|
#endif
|
||||||
#ifdef VAAPI
|
#ifdef VAAPI
|
||||||
if (decoder->images[i * 2 + j]) {
|
if (decoder->images[i*Planes+j]) {
|
||||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[i * 2 + j]);
|
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[i*Planes+j]);
|
||||||
if (decoder->fds[i * 2 + j])
|
if (decoder->fds[i*Planes+j])
|
||||||
close(decoder->fds[i * 2 + j]);
|
close(decoder->fds[i*Planes+j]);
|
||||||
}
|
}
|
||||||
decoder->fds[i * 2 + j] = 0;
|
decoder->fds[i*Planes+j] = 0;
|
||||||
decoder->images[i * 2 + j] = 0;
|
decoder->images[i*Planes+j] = 0;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1665,19 +1679,25 @@ static void CuvidReleaseSurface(CuvidDecoder * decoder, int surface)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef VAAPI
|
#ifdef VAAPI
|
||||||
if (decoder->images[surface * 2]) {
|
if (decoder->images[surface*Planes]) {
|
||||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface * 2]);
|
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes]);
|
||||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface * 2 + 1]);
|
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes+1]);
|
||||||
if (decoder->fds[surface * 2]) {
|
#ifdef RASPI
|
||||||
close(decoder->fds[surface * 2]);
|
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes+2]);
|
||||||
close(decoder->fds[surface * 2 + 1]);
|
#endif
|
||||||
}
|
if (decoder->fds[surface*Planes]) {
|
||||||
}
|
close(decoder->fds[surface*Planes]);
|
||||||
decoder->fds[surface * 2] = 0;
|
close(decoder->fds[surface*Planes+1]);
|
||||||
decoder->fds[surface * 2 + 1] = 0;
|
#ifdef RASPI
|
||||||
decoder->images[surface * 2] = 0;
|
close(decoder->fds[surface*Planes+2]);
|
||||||
decoder->images[surface * 2 + 1] = 0;
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decoder->fds[surface*Planes] = 0;
|
||||||
|
decoder->fds[surface*Planes+1] = 0;
|
||||||
|
decoder->images[surface*Planes] = 0;
|
||||||
|
decoder->images[surface*Planes+1] = 0;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < decoder->SurfaceUsedN; ++i) {
|
for (i = 0; i < decoder->SurfaceUsedN; ++i) {
|
||||||
@ -1803,8 +1823,8 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * o
|
|||||||
EGL_RENDERABLE_TYPE, rend,
|
EGL_RENDERABLE_TYPE, rend,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
EGLint num_configs;
|
EGLint num_configs=0;
|
||||||
|
#ifndef RASPI
|
||||||
attribs = attributes10;
|
attribs = attributes10;
|
||||||
*bpp = 10;
|
*bpp = 10;
|
||||||
if (!eglChooseConfig(display, attributes10, NULL, 0, &num_configs)) { // try 10 Bit
|
if (!eglChooseConfig(display, attributes10, NULL, 0, &num_configs)) { // try 10 Bit
|
||||||
@ -1814,7 +1834,9 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * o
|
|||||||
if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit
|
if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit
|
||||||
num_configs = 0;
|
num_configs = 0;
|
||||||
}
|
}
|
||||||
} else if (num_configs == 0) {
|
} else
|
||||||
|
#endif
|
||||||
|
if (num_configs == 0) {
|
||||||
EglCheck();
|
EglCheck();
|
||||||
Debug(3, " 10 Bit egl Failed\n");
|
Debug(3, " 10 Bit egl Failed\n");
|
||||||
attribs = attributes8;
|
attribs = attributes8;
|
||||||
@ -1903,7 +1925,7 @@ make_egl()
|
|||||||
int vID, n;
|
int vID, n;
|
||||||
|
|
||||||
eglGetConfigAttrib(eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &vID);
|
eglGetConfigAttrib(eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &vID);
|
||||||
Debug(3, "chose visual 0x%x\n", vID);
|
Debug(3, "chose visual 0x%x bpp %d\n", vID,bpp);
|
||||||
#ifdef USE_DRM
|
#ifdef USE_DRM
|
||||||
InitBo(bpp);
|
InitBo(bpp);
|
||||||
#else
|
#else
|
||||||
@ -1946,19 +1968,21 @@ static CuvidDecoder *CuvidNewHwDecoder(VideoStream * stream)
|
|||||||
Fatal("codec: can't allocate HW video codec context err %04x", i);
|
Fatal("codec: can't allocate HW video codec context err %04x", i);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef VAAPI
|
#if defined (VAAPI) && !defined (RASPI)
|
||||||
// if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, ":0.0" , NULL, 0)) != 0 ) {
|
// if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, ":0.0" , NULL, 0)) != 0 ) {
|
||||||
if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, "/dev/dri/renderD128", NULL, 0)) != 0) {
|
if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, "/dev/dri/renderD128", NULL, 0)) != 0) {
|
||||||
Fatal("codec: can't allocate HW video codec context err %04x", i);
|
Fatal("codec: can't allocate HW video codec context err %04x", i);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef RASPI
|
||||||
HwDeviceContext = av_buffer_ref(hw_device_ctx);
|
HwDeviceContext = av_buffer_ref(hw_device_ctx);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
||||||
Error(_("video/cuvid: out of memory\n"));
|
Error(_("video/cuvid: out of memory\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#ifdef VAAPI
|
#if defined (VAAPI) && !defined (RASPI)
|
||||||
VaDisplay = TO_VAAPI_DEVICE_CTX(HwDeviceContext)->display;
|
VaDisplay = TO_VAAPI_DEVICE_CTX(HwDeviceContext)->display;
|
||||||
decoder->VaDisplay = VaDisplay;
|
decoder->VaDisplay = VaDisplay;
|
||||||
#endif
|
#endif
|
||||||
@ -2384,29 +2408,34 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi
|
|||||||
glGenBuffers(1, &vao_buffer);
|
glGenBuffers(1, &vao_buffer);
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
// create texture planes
|
// create texture planes
|
||||||
glGenTextures(CODEC_SURFACES_MAX * 2, decoder->gl_textures);
|
glGenTextures(CODEC_SURFACES_MAX * Planes, decoder->gl_textures);
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
|
|
||||||
for (i = 0; i < anz; i++) {
|
for (i = 0; i < anz; i++) {
|
||||||
for (n = 0; n < 2; n++) { // number of planes
|
for (n = 0; n < Planes; n++) { // number of planes
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[i * 2 + n]);
|
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[i * Planes + n]);
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
// set basic parameters
|
// set basic parameters
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
if (PixFmt == AV_PIX_FMT_NV12)
|
#ifdef RASPI
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, n == 0 ? GL_R8 : GL_RG8, n == 0 ? size_x : size_x / 2,
|
if (PixFmt == AV_PIX_FMT_NV12)
|
||||||
n == 0 ? size_y : size_y / 2, 0, n == 0 ? GL_RED : GL_RG, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0,GL_R8 ,n==0?size_x:size_x/2, n==0?size_y:size_y/2, 0, GL_RED , GL_UNSIGNED_BYTE , NULL);
|
||||||
else
|
else
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, n == 0 ? GL_R16 : GL_RG16, n == 0 ? size_x : size_x / 2,
|
glTexImage2D(GL_TEXTURE_2D, 0,GL_R16,n==0?size_x:size_x/2, n==0?size_y:size_y/2, 0, GL_RED , GL_UNSIGNED_SHORT, NULL);
|
||||||
n == 0 ? size_y : size_y / 2, 0, n == 0 ? GL_RED : GL_RG, GL_UNSIGNED_SHORT, NULL);
|
#else
|
||||||
|
if (PixFmt == AV_PIX_FMT_NV12)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0,n==0?GL_R8 :GL_RG8 ,n==0?size_x:size_x/2, n==0?size_y:size_y/2, 0, n==0?GL_RED:GL_RG , GL_UNSIGNED_BYTE , NULL);
|
||||||
|
else
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0,n==0?GL_R16:GL_RG16 ,n==0?size_x:size_x/2, n==0?size_y:size_y/2, 0, n==0?GL_RED:GL_RG , GL_UNSIGNED_SHORT, NULL);
|
||||||
|
#endif
|
||||||
SDK_CHECK_ERROR_GL();
|
SDK_CHECK_ERROR_GL();
|
||||||
// register this texture with CUDA
|
// register this texture with CUDA
|
||||||
#ifdef CUVID
|
#ifdef CUVID
|
||||||
checkCudaErrors(cuGraphicsGLRegisterImage(&decoder->cu_res[i][n], decoder->gl_textures[i * 2 + n],
|
checkCudaErrors(cuGraphicsGLRegisterImage(&decoder->cu_res[i][n], decoder->gl_textures[i * Planes + n],
|
||||||
GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD));
|
GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD));
|
||||||
checkCudaErrors(cuGraphicsMapResources(1, &decoder->cu_res[i][n], 0));
|
checkCudaErrors(cuGraphicsMapResources(1, &decoder->cu_res[i][n], 0));
|
||||||
checkCudaErrors(cuGraphicsSubResourceGetMappedArray(&decoder->cu_array[i][n], decoder->cu_res[i][n], 0,
|
checkCudaErrors(cuGraphicsSubResourceGetMappedArray(&decoder->cu_array[i][n], decoder->cu_res[i][n], 0,
|
||||||
@ -2447,6 +2476,7 @@ void generateVAAPIImage(CuvidDecoder * decoder, int index, const AVFrame * frame
|
|||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
|
||||||
uint64_t first_time;
|
uint64_t first_time;
|
||||||
|
#if defined (VAAPI) && !defined (RASPI)
|
||||||
VADRMPRIMESurfaceDescriptor desc;
|
VADRMPRIMESurfaceDescriptor desc;
|
||||||
|
|
||||||
status =
|
status =
|
||||||
@ -2458,28 +2488,58 @@ void generateVAAPIImage(CuvidDecoder * decoder, int index, const AVFrame * frame
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vaSyncSurface(decoder->VaDisplay, (unsigned int)frame->data[3]);
|
vaSyncSurface(decoder->VaDisplay, (unsigned int)frame->data[3]);
|
||||||
//#ifndef USE_DRM
|
#endif
|
||||||
|
#ifdef RASPI
|
||||||
|
AVDRMFrameDescriptor desc;
|
||||||
|
memcpy(&desc,frame->data[0],sizeof(desc));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
|
||||||
EglCheck();
|
EglCheck();
|
||||||
//#endif
|
|
||||||
for (int n = 0; n < 2; n++) {
|
for (int n = 0; n < Planes; n++) {
|
||||||
int attribs[20] = { EGL_NONE };
|
int attribs[20] = { EGL_NONE };
|
||||||
int num_attribs = 0;
|
int num_attribs = 0;
|
||||||
|
int fd;
|
||||||
|
#if defined (VAAPI) && !defined (RASPI)
|
||||||
|
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, desc.layers[n].drm_format);
|
||||||
|
ADD_ATTRIB(EGL_WIDTH, n==0?image_width:image_width/2);
|
||||||
|
ADD_ATTRIB(EGL_HEIGHT, n==0?image_height:image_height/2);
|
||||||
|
ADD_PLANE_ATTRIBS(0);
|
||||||
|
#endif
|
||||||
|
#ifdef RASPI
|
||||||
|
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_R8);
|
||||||
|
ADD_ATTRIB(EGL_WIDTH, n==0?image_width:image_width/2);
|
||||||
|
ADD_ATTRIB(EGL_HEIGHT, n==0?image_height:image_height/2);
|
||||||
|
if (n==0) {
|
||||||
|
fd = dup(desc.objects[0].fd);
|
||||||
|
ADD_ATTRIB( EGL_DMA_BUF_PLANE0_FD_EXT,fd);
|
||||||
|
ADD_ATTRIB( EGL_DMA_BUF_PLANE0_OFFSET_EXT,desc.layers[0].planes[n].offset);
|
||||||
|
ADD_ATTRIB( EGL_DMA_BUF_PLANE0_PITCH_EXT,desc.layers[0].planes[n].pitch);
|
||||||
|
} else {
|
||||||
|
fd = dup(desc.objects[0].fd);
|
||||||
|
ADD_ATTRIB( EGL_DMA_BUF_PLANE0_FD_EXT,fd);
|
||||||
|
ADD_ATTRIB( EGL_DMA_BUF_PLANE0_OFFSET_EXT,desc.layers[0].planes[n].offset);
|
||||||
|
ADD_ATTRIB( EGL_DMA_BUF_PLANE0_PITCH_EXT,desc.layers[0].planes[n].pitch);
|
||||||
|
}
|
||||||
|
// Debug(3,"n %d fd %d nb_planes %d nb_layers %d plane %d offeset %d offset2 %d pitch %d \n",n, fd,
|
||||||
|
// desc.layers[0].nb_planes,desc.nb_layers,n,desc.layers[0].planes[n].offset,desc.layers[0].planes[n+1].offset,desc.layers[0].planes[n].pitch);
|
||||||
|
#endif
|
||||||
|
|
||||||
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, desc.layers[n].drm_format);
|
decoder->images[index * Planes + n] =
|
||||||
ADD_ATTRIB(EGL_WIDTH, n == 0 ? image_width : image_width / 2);
|
|
||||||
ADD_ATTRIB(EGL_HEIGHT, n == 0 ? image_height : image_height / 2);
|
|
||||||
ADD_PLANE_ATTRIBS(0);
|
|
||||||
|
|
||||||
decoder->images[index * 2 + n] =
|
|
||||||
CreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
CreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
||||||
|
|
||||||
if (!decoder->images[index * 2 + n])
|
if (!decoder->images[index * Planes + n])
|
||||||
goto esh_failed;
|
goto esh_failed;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[index * 2 + n]);
|
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[index * Planes + n]);
|
||||||
EGLImageTargetTexture2DOES(GL_TEXTURE_2D, decoder->images[index * 2 + n]);
|
EGLImageTargetTexture2DOES(GL_TEXTURE_2D, decoder->images[index * Planes + n]);
|
||||||
decoder->fds[index * 2 + n] = desc.objects[desc.layers[n].object_index[0]].fd;
|
#ifdef RASPI
|
||||||
|
decoder->fds[index*Planes+n] = fd;
|
||||||
|
#else
|
||||||
|
decoder->fds[index*Planes+n] = desc.objects[desc.layers[n].object_index[0]].fd;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
@ -2488,7 +2548,7 @@ void generateVAAPIImage(CuvidDecoder * decoder, int index, const AVFrame * frame
|
|||||||
|
|
||||||
esh_failed:
|
esh_failed:
|
||||||
Debug(3, "Failure in generateVAAPIImage\n");
|
Debug(3, "Failure in generateVAAPIImage\n");
|
||||||
for (int n = 0; n < desc.num_objects; n++)
|
for (int n = 0; n < Planes; n++)
|
||||||
close(desc.objects[n].fd);
|
close(desc.objects[n].fd);
|
||||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
EglCheck();
|
EglCheck();
|
||||||
@ -2859,12 +2919,18 @@ int get_RGB(CuvidDecoder * decoder)
|
|||||||
glUniform1i(texLoc, 0);
|
glUniform1i(texLoc, 0);
|
||||||
texLoc = glGetUniformLocation(gl_prog, "texture1");
|
texLoc = glGetUniformLocation(gl_prog, "texture1");
|
||||||
glUniform1i(texLoc, 1);
|
glUniform1i(texLoc, 1);
|
||||||
|
#ifdef RASPI
|
||||||
|
texLoc = glGetUniformLocation(gl_prog, "texture2");
|
||||||
|
glUniform1i(texLoc, 2);
|
||||||
|
#endif
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * 2 + 0]);
|
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * 2 + 1]);
|
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 1]);
|
||||||
|
#ifdef RASPI
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 2]);
|
||||||
|
#endif
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||||
|
|
||||||
render_pass_quad(1, 0.0, 0.0);
|
render_pass_quad(1, 0.0, 0.0);
|
||||||
@ -3207,32 +3273,32 @@ static void CuvidRenderFrame(CuvidDecoder * decoder, const AVCodecContext * vide
|
|||||||
color = frame->colorspace;
|
color = frame->colorspace;
|
||||||
if (color == AVCOL_SPC_UNSPECIFIED) // if unknown
|
if (color == AVCOL_SPC_UNSPECIFIED) // if unknown
|
||||||
color = AVCOL_SPC_BT709;
|
color = AVCOL_SPC_BT709;
|
||||||
#if 0
|
#ifdef RASPI
|
||||||
//
|
//
|
||||||
// Check image, format, size
|
// Check image, format, size
|
||||||
//
|
//
|
||||||
if ( // decoder->PixFmt != video_ctx->pix_fmt
|
if ( // decoder->PixFmt != video_ctx->pix_fmt
|
||||||
video_ctx->width != decoder->InputWidth
|
video_ctx->width != decoder->InputWidth
|
||||||
// || decoder->ColorSpace != color
|
// || decoder->ColorSpace != color
|
||||||
|| video_ctx->height != decoder->InputHeight) {
|
|| video_ctx->height != decoder->InputHeight) {
|
||||||
// Debug(3,"fmt %02d:%02d width %d:%d hight %d:%d\n",decoder->ColorSpace,frame->colorspace ,video_ctx->width, decoder->InputWidth,video_ctx->height, decoder->InputHeight);
|
Debug(3,"fmt %02d:%02d width %d:%d hight %d:%d\n",decoder->ColorSpace,frame->colorspace ,video_ctx->width, decoder->InputWidth,video_ctx->height, decoder->InputHeight);
|
||||||
|
decoder->PixFmt = AV_PIX_FMT_NV12;
|
||||||
|
decoder->InputWidth = video_ctx->width;
|
||||||
|
decoder->InputHeight = video_ctx->height;
|
||||||
|
CuvidCleanup(decoder);
|
||||||
|
decoder->SurfacesNeeded = VIDEO_SURFACES_MAX + 1;
|
||||||
|
CuvidSetupOutput(decoder);
|
||||||
|
|
||||||
decoder->InputWidth = video_ctx->width;
|
}
|
||||||
decoder->InputHeight = video_ctx->height;
|
|
||||||
CuvidCleanup(decoder);
|
|
||||||
decoder->SurfacesNeeded = VIDEO_SURFACES_MAX + 1;
|
|
||||||
CuvidSetupOutput(decoder);
|
|
||||||
#ifdef PLACEBO // dont show first frame
|
|
||||||
decoder->newchannel = 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
//
|
//
|
||||||
// Copy data from frame to image
|
// Copy data from frame to image
|
||||||
//
|
//
|
||||||
|
#ifdef RASPI
|
||||||
|
if (video_ctx->pix_fmt == 0) {
|
||||||
|
#else
|
||||||
if (video_ctx->pix_fmt == PIXEL_FORMAT) {
|
if (video_ctx->pix_fmt == PIXEL_FORMAT) {
|
||||||
|
#endif
|
||||||
int w = decoder->InputWidth;
|
int w = decoder->InputWidth;
|
||||||
int h = decoder->InputHeight;
|
int h = decoder->InputHeight;
|
||||||
|
|
||||||
@ -3302,7 +3368,9 @@ static void CuvidRenderFrame(CuvidDecoder * decoder, const AVCodecContext * vide
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatal(_("video/vdpau: pixel format %d not supported\n"), video_ctx->pix_fmt);
|
// Debug(3,"video/vdpau: pixel format %d not supported\n", video_ctx->pix_fmt);
|
||||||
|
av_frame_free(&frame);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -3478,12 +3546,20 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
glUniform1i(texLoc, 0);
|
glUniform1i(texLoc, 0);
|
||||||
texLoc = glGetUniformLocation(gl_prog, "texture1");
|
texLoc = glGetUniformLocation(gl_prog, "texture1");
|
||||||
glUniform1i(texLoc, 1);
|
glUniform1i(texLoc, 1);
|
||||||
|
#ifdef RASPI
|
||||||
glActiveTexture(GL_TEXTURE0);
|
texLoc = glGetUniformLocation(gl_prog, "texture2");
|
||||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * 2 + 0]);
|
glUniform1i(texLoc, 2);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
#endif
|
||||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * 2 + 1]);
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]);
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 1]);
|
||||||
|
#ifdef RASPI
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 2]);
|
||||||
|
#endif
|
||||||
|
|
||||||
render_pass_quad(0, xcropf, ycropf);
|
render_pass_quad(0, xcropf, ycropf);
|
||||||
|
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
Loading…
Reference in New Issue
Block a user