1
0
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:
jojo61 2019-12-23 11:14:38 +01:00
parent d1bc51edb8
commit 463109fcb6
4 changed files with 311 additions and 93 deletions

46
codec.c
View File

@ -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");
@ -257,6 +256,20 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
break; break;
} }
} }
#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 #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");
@ -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
View File

@ -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
View File

@ -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\

236
video.c
View File

@ -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
} }
@ -1666,18 +1680,24 @@ 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,11 +3546,19 @@ 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
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
render_pass_quad(0, xcropf, ycropf); render_pass_quad(0, xcropf, ycropf);