From 463109fcb69cae21e4b4f44f1b0516a6568c4490 Mon Sep 17 00:00:00 2001 From: jojo61 Date: Mon, 23 Dec 2019 11:14:38 +0100 Subject: [PATCH] Prepare for v4l2m2m for Raspi 4 --- codec.c | 46 +++++++++-- drm.c | 13 ++- shaders.h | 103 ++++++++++++++++++++++- video.c | 242 +++++++++++++++++++++++++++++++++++------------------- 4 files changed, 311 insertions(+), 93 deletions(-) diff --git a/codec.c b/codec.c index 0072325..f5d2986 100644 --- a/codec.c +++ b/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 } diff --git a/drm.c b/drm.c index 29fba6f..5547522 100644 --- a/drm.c +++ b/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; } diff --git a/shaders.h b/shaders.h index 25207bf..6b38477 100644 --- a/shaders.h +++ b/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\ diff --git a/video.c b/video.c index ec00b87..06a6155 100644 --- a/video.c +++ b/video.c @@ -160,6 +160,10 @@ typedef enum #include #include +#ifdef RASPI +#include +#include +#endif #include #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);