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;
|
||||
|
||||
decoder = video_ctx->opaque;
|
||||
|
||||
// bug in ffmpeg 1.1.1, called with zero width or height
|
||||
if (!video_ctx->width || !video_ctx->height) {
|
||||
Error("codec/video: ffmpeg/libav buggy: width or height zero\n");
|
||||
@ -258,6 +257,20 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
||||
}
|
||||
}
|
||||
#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))) {
|
||||
Debug(3, "codec: decoder found\n");
|
||||
} 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))) {
|
||||
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);
|
||||
#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
|
||||
decoder->VideoCtx->thread_count = 1;
|
||||
@ -290,7 +309,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
||||
#ifdef YADIF
|
||||
deint = 2;
|
||||
#endif
|
||||
#ifdef VAAPI
|
||||
#if defined VAAPI && !defined RASPI
|
||||
decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
|
||||
if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) {
|
||||
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)
|
||||
Fatal(_("VAAPI Refcounts invalid\n"));
|
||||
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
|
||||
|
||||
#ifdef CUVID
|
||||
@ -367,7 +401,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
||||
//decoder->VideoCtx->debug = FF_DEBUG_STARTCODE;
|
||||
//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);
|
||||
|
||||
decoder->VideoCtx->get_format = Codec_get_format;
|
||||
@ -387,7 +421,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
||||
|
||||
// reset buggy ffmpeg/libav flag
|
||||
decoder->GetFormatDone = 0;
|
||||
#ifdef YADIF
|
||||
#if defined (YADIF) || defined (RASPI)
|
||||
decoder->filter = 0;
|
||||
#endif
|
||||
}
|
||||
|
13
drm.c
13
drm.c
@ -198,8 +198,11 @@ static int FindDevice(VideoRender * render)
|
||||
int i,ii=0;
|
||||
char connectorstr[10];
|
||||
int found = 0;
|
||||
|
||||
render->fd_drm = open("/dev/dri/card0", O_RDWR);
|
||||
#ifdef RASPI
|
||||
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) {
|
||||
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n");
|
||||
return -errno;
|
||||
@ -339,7 +342,11 @@ static int FindDevice(VideoRender * render)
|
||||
for (k = 0; k < plane->count_formats; k++) {
|
||||
if (encoder->possible_crtcs & plane->possible_crtcs) {
|
||||
switch (plane->formats[k]) {
|
||||
case DRM_FORMAT_XRGB2101010:
|
||||
#ifdef RASPI
|
||||
case DRM_FORMAT_ARGB8888:
|
||||
#else
|
||||
case DRM_FORMAT_XRGB2101010:
|
||||
#endif
|
||||
if (!render->video_plane) {
|
||||
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\
|
||||
out_color = color;\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[] = { "\
|
||||
\n\
|
||||
in vec2 vertex_position;\n\
|
||||
|
242
video.c
242
video.c
@ -160,6 +160,10 @@ typedef enum
|
||||
|
||||
#include <va/va_drmcommon.h>
|
||||
#include <libavcodec/vaapi.h>
|
||||
#ifdef RASPI
|
||||
#include <libavutil/hwcontext_drm.h>
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
#endif
|
||||
#include <libavutil/hwcontext_vaapi.h>
|
||||
#define TO_AVHW_DEVICE_CTX(x) ((AVHWDeviceContext*)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 OUTPUT_SURFACES_MAX 4 ///< output surfaces for flip page
|
||||
#ifdef VAAPI
|
||||
#if defined VAAPI && !defined RASPI
|
||||
#define PIXEL_FORMAT AV_PIX_FMT_VAAPI
|
||||
#define SWAP_BUFFER_SIZE 3
|
||||
#endif
|
||||
@ -342,12 +346,22 @@ typedef struct
|
||||
#define PIXEL_FORMAT AV_PIX_FMT_CUDA
|
||||
#define SWAP_BUFFER_SIZE 1
|
||||
#endif
|
||||
#if defined RASPI
|
||||
#define PIXEL_FORMAT AV_PIX_FMT_MMAL
|
||||
#define SWAP_BUFFER_SIZE 3
|
||||
#endif
|
||||
//----------------------------------------------------------------------------
|
||||
// Variables
|
||||
//----------------------------------------------------------------------------
|
||||
AVBufferRef *HwDeviceContext; ///< ffmpeg HW device context
|
||||
char VideoIgnoreRepeatPict; ///< disable repeat pict warning
|
||||
|
||||
#ifdef RASPI
|
||||
int Planes = 3;
|
||||
#else
|
||||
int Planes = 2;
|
||||
#endif
|
||||
|
||||
unsigned char *posd;
|
||||
|
||||
static const char *VideoDriverName = "cuvid"; ///< video output device
|
||||
@ -1551,7 +1565,7 @@ static void CuvidDestroySurfaces(CuvidDecoder * decoder)
|
||||
if (decoder->frames[i]) {
|
||||
av_frame_free(&decoder->frames[i]);
|
||||
}
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (j = 0; j < Planes; j++) {
|
||||
#ifdef PLACEBO
|
||||
if (decoder->pl_images[i].planes[j].texture) {
|
||||
|
||||
@ -1567,13 +1581,13 @@ static void CuvidDestroySurfaces(CuvidDecoder * decoder)
|
||||
checkCudaErrors(cuGraphicsUnregisterResource(decoder->cu_res[i][j]));
|
||||
#endif
|
||||
#ifdef VAAPI
|
||||
if (decoder->images[i * 2 + j]) {
|
||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[i * 2 + j]);
|
||||
if (decoder->fds[i * 2 + j])
|
||||
close(decoder->fds[i * 2 + j]);
|
||||
}
|
||||
decoder->fds[i * 2 + j] = 0;
|
||||
decoder->images[i * 2 + j] = 0;
|
||||
if (decoder->images[i*Planes+j]) {
|
||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[i*Planes+j]);
|
||||
if (decoder->fds[i*Planes+j])
|
||||
close(decoder->fds[i*Planes+j]);
|
||||
}
|
||||
decoder->fds[i*Planes+j] = 0;
|
||||
decoder->images[i*Planes+j] = 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@ -1665,19 +1679,25 @@ static void CuvidReleaseSurface(CuvidDecoder * decoder, int surface)
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef VAAPI
|
||||
if (decoder->images[surface * 2]) {
|
||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface * 2]);
|
||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface * 2 + 1]);
|
||||
if (decoder->fds[surface * 2]) {
|
||||
close(decoder->fds[surface * 2]);
|
||||
close(decoder->fds[surface * 2 + 1]);
|
||||
}
|
||||
}
|
||||
decoder->fds[surface * 2] = 0;
|
||||
decoder->fds[surface * 2 + 1] = 0;
|
||||
decoder->images[surface * 2] = 0;
|
||||
decoder->images[surface * 2 + 1] = 0;
|
||||
#ifdef VAAPI
|
||||
if (decoder->images[surface*Planes]) {
|
||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes]);
|
||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes+1]);
|
||||
#ifdef RASPI
|
||||
DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes+2]);
|
||||
#endif
|
||||
if (decoder->fds[surface*Planes]) {
|
||||
close(decoder->fds[surface*Planes]);
|
||||
close(decoder->fds[surface*Planes+1]);
|
||||
#ifdef RASPI
|
||||
close(decoder->fds[surface*Planes+2]);
|
||||
#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
|
||||
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_NONE
|
||||
};
|
||||
EGLint num_configs;
|
||||
|
||||
EGLint num_configs=0;
|
||||
#ifndef RASPI
|
||||
attribs = attributes10;
|
||||
*bpp = 10;
|
||||
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
|
||||
num_configs = 0;
|
||||
}
|
||||
} else if (num_configs == 0) {
|
||||
} else
|
||||
#endif
|
||||
if (num_configs == 0) {
|
||||
EglCheck();
|
||||
Debug(3, " 10 Bit egl Failed\n");
|
||||
attribs = attributes8;
|
||||
@ -1903,7 +1925,7 @@ make_egl()
|
||||
int vID, n;
|
||||
|
||||
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
|
||||
InitBo(bpp);
|
||||
#else
|
||||
@ -1946,19 +1968,21 @@ static CuvidDecoder *CuvidNewHwDecoder(VideoStream * stream)
|
||||
Fatal("codec: can't allocate HW video codec context err %04x", i);
|
||||
}
|
||||
#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, "/dev/dri/renderD128", NULL, 0)) != 0) {
|
||||
Fatal("codec: can't allocate HW video codec context err %04x", i);
|
||||
}
|
||||
#endif
|
||||
#ifndef RASPI
|
||||
HwDeviceContext = av_buffer_ref(hw_device_ctx);
|
||||
#endif
|
||||
|
||||
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
||||
Error(_("video/cuvid: out of memory\n"));
|
||||
return NULL;
|
||||
}
|
||||
#ifdef VAAPI
|
||||
#if defined (VAAPI) && !defined (RASPI)
|
||||
VaDisplay = TO_VAAPI_DEVICE_CTX(HwDeviceContext)->display;
|
||||
decoder->VaDisplay = VaDisplay;
|
||||
#endif
|
||||
@ -2384,29 +2408,34 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi
|
||||
glGenBuffers(1, &vao_buffer);
|
||||
GlxCheck();
|
||||
// create texture planes
|
||||
glGenTextures(CODEC_SURFACES_MAX * 2, decoder->gl_textures);
|
||||
glGenTextures(CODEC_SURFACES_MAX * Planes, decoder->gl_textures);
|
||||
GlxCheck();
|
||||
|
||||
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();
|
||||
// set basic parameters
|
||||
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_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
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);
|
||||
#ifdef RASPI
|
||||
if (PixFmt == AV_PIX_FMT_NV12)
|
||||
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
|
||||
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);
|
||||
#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();
|
||||
// register this texture with CUDA
|
||||
#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));
|
||||
checkCudaErrors(cuGraphicsMapResources(1, &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;
|
||||
|
||||
uint64_t first_time;
|
||||
#if defined (VAAPI) && !defined (RASPI)
|
||||
VADRMPRIMESurfaceDescriptor desc;
|
||||
|
||||
status =
|
||||
@ -2458,28 +2488,58 @@ void generateVAAPIImage(CuvidDecoder * decoder, int index, const AVFrame * frame
|
||||
return;
|
||||
}
|
||||
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);
|
||||
EglCheck();
|
||||
//#endif
|
||||
for (int n = 0; n < 2; n++) {
|
||||
|
||||
for (int n = 0; n < Planes; n++) {
|
||||
int attribs[20] = { EGL_NONE };
|
||||
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);
|
||||
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] =
|
||||
decoder->images[index * Planes + n] =
|
||||
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;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[index * 2 + n]);
|
||||
EGLImageTargetTexture2DOES(GL_TEXTURE_2D, decoder->images[index * 2 + n]);
|
||||
decoder->fds[index * 2 + n] = desc.objects[desc.layers[n].object_index[0]].fd;
|
||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[index * Planes + n]);
|
||||
EGLImageTargetTexture2DOES(GL_TEXTURE_2D, decoder->images[index * Planes + n]);
|
||||
#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);
|
||||
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:
|
||||
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);
|
||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
EglCheck();
|
||||
@ -2859,12 +2919,18 @@ int get_RGB(CuvidDecoder * decoder)
|
||||
glUniform1i(texLoc, 0);
|
||||
texLoc = glGetUniformLocation(gl_prog, "texture1");
|
||||
glUniform1i(texLoc, 1);
|
||||
|
||||
#ifdef RASPI
|
||||
texLoc = glGetUniformLocation(gl_prog, "texture2");
|
||||
glUniform1i(texLoc, 2);
|
||||
#endif
|
||||
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);
|
||||
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);
|
||||
|
||||
render_pass_quad(1, 0.0, 0.0);
|
||||
@ -3207,32 +3273,32 @@ static void CuvidRenderFrame(CuvidDecoder * decoder, const AVCodecContext * vide
|
||||
color = frame->colorspace;
|
||||
if (color == AVCOL_SPC_UNSPECIFIED) // if unknown
|
||||
color = AVCOL_SPC_BT709;
|
||||
#if 0
|
||||
//
|
||||
// Check image, format, size
|
||||
//
|
||||
if ( // decoder->PixFmt != video_ctx->pix_fmt
|
||||
video_ctx->width != decoder->InputWidth
|
||||
// || decoder->ColorSpace != color
|
||||
|| 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);
|
||||
#ifdef RASPI
|
||||
//
|
||||
// Check image, format, size
|
||||
//
|
||||
if ( // decoder->PixFmt != video_ctx->pix_fmt
|
||||
video_ctx->width != decoder->InputWidth
|
||||
// || decoder->ColorSpace != color
|
||||
|| 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
|
||||
//
|
||||
// Copy data from frame to image
|
||||
//
|
||||
|
||||
#ifdef RASPI
|
||||
if (video_ctx->pix_fmt == 0) {
|
||||
#else
|
||||
if (video_ctx->pix_fmt == PIXEL_FORMAT) {
|
||||
|
||||
#endif
|
||||
int w = decoder->InputWidth;
|
||||
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);
|
||||
texLoc = glGetUniformLocation(gl_prog, "texture1");
|
||||
glUniform1i(texLoc, 1);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * 2 + 0]);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * 2 + 1]);
|
||||
|
||||
#ifdef RASPI
|
||||
texLoc = glGetUniformLocation(gl_prog, "texture2");
|
||||
glUniform1i(texLoc, 2);
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
glUseProgram(0);
|
||||
|
Loading…
Reference in New Issue
Block a user