Commit 549f0522 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'lukaszmluki/master'

* lukaszmluki/master:
  lavd/opengl_enc: remove inlines
  lavd/opengl_enc: fix window caption
  lavd/opengl_enc: simplify opengl_load_procedures usage
  lavd/opengl_enc: factorize deinit_context function
  lavd/opengl_enc: factorize create/release window functions
  lavd/opengl_enc: rename GL_RED_COMPONENT define
  lavd/opengl_enc: create format description table
  lavd/opengl_enc_shaders: make shaders code static and const
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 96c4ba23 5059d8df
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
#define APIENTRY #define APIENTRY
#endif #endif
/* GL_RED_COMPONENT is used for plannar pixel types. /* FF_GL_RED_COMPONENT is used for plannar pixel types.
* Only red component is sampled in shaders. * Only red component is sampled in shaders.
* On some platforms GL_RED is not availabe and GL_LUMINANCE have to be used, * On some platforms GL_RED is not availabe and GL_LUMINANCE have to be used,
* but since OpenGL 3.0 GL_LUMINANCE is deprecated. * but since OpenGL 3.0 GL_LUMINANCE is deprecated.
...@@ -71,11 +71,11 @@ ...@@ -71,11 +71,11 @@
* GL_LUMINANCE produces RGBA = value, value, value, 1. * GL_LUMINANCE produces RGBA = value, value, value, 1.
* Note: GL_INTENSITY may also be used which produce RGBA = value, value, value, value. */ * Note: GL_INTENSITY may also be used which produce RGBA = value, value, value, value. */
#if defined(GL_RED) #if defined(GL_RED)
#define GL_RED_COMPONENT GL_RED #define FF_GL_RED_COMPONENT GL_RED
#elif defined(GL_LUMINANCE) #elif defined(GL_LUMINANCE)
#define GL_RED_COMPONENT GL_LUMINANCE #define FF_GL_RED_COMPONENT GL_LUMINANCE
#else #else
#define GL_RED_COMPONENT 0x1903; //GL_RED #define FF_GL_RED_COMPONENT 0x1903; //GL_RED
#endif #endif
/* Constants not defined for iOS */ /* Constants not defined for iOS */
...@@ -188,6 +188,8 @@ typedef struct OpenGLContext { ...@@ -188,6 +188,8 @@ typedef struct OpenGLContext {
/* Current OpenGL configuration */ /* Current OpenGL configuration */
GLuint program; ///< Shader program GLuint program; ///< Shader program
GLuint vertex_shader; ///< Vertex shader
GLuint fragment_shader; ///< Fragment shader for current pix_pmt
GLuint texture_name[4]; ///< Textures' IDs GLuint texture_name[4]; ///< Textures' IDs
GLuint index_buffer; ///< Index buffer GLuint index_buffer; ///< Index buffer
GLuint vertex_buffer; ///< Vertex buffer GLuint vertex_buffer; ///< Vertex buffer
...@@ -219,10 +221,83 @@ typedef struct OpenGLContext { ...@@ -219,10 +221,83 @@ typedef struct OpenGLContext {
int window_height; int window_height;
} OpenGLContext; } OpenGLContext;
static const struct OpenGLFormatDesc {
enum AVPixelFormat fixel_format;
const char * const * fragment_shader;
GLenum format;
GLenum type;
} opengl_format_desc[] = {
{ AV_PIX_FMT_YUV420P, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUV444P, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUV422P, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUV410P, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUV411P, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUV440P, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUV420P16, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_YUV422P16, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_YUV444P16, &FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_YUVA420P, &FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUVA444P, &FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUVA422P, &FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_YUVA420P16, &FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_YUVA422P16, &FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_YUVA444P16, &FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_RGB24, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGB, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_BGR24, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGB, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_0RGB, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGBA, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_RGB0, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGBA, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_0BGR, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGBA, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_BGR0, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGBA, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_RGB565, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 },
{ AV_PIX_FMT_BGR565, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 },
{ AV_PIX_FMT_RGB555, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGBA, FF_GL_UNSIGNED_SHORT_1_5_5_5_REV },
{ AV_PIX_FMT_BGR555, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGBA, FF_GL_UNSIGNED_SHORT_1_5_5_5_REV },
{ AV_PIX_FMT_RGB8, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGB, FF_GL_UNSIGNED_BYTE_3_3_2 },
{ AV_PIX_FMT_BGR8, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGB, FF_GL_UNSIGNED_BYTE_2_3_3_REV },
{ AV_PIX_FMT_RGB48, &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET, GL_RGB, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_ARGB, &FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET, GL_RGBA, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_RGBA, &FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET, GL_RGBA, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_ABGR, &FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET, GL_RGBA, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_BGRA, &FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET, GL_RGBA, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_RGBA64, &FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET, GL_RGBA, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_BGRA64, &FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET, GL_RGBA, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_GBRP, &FF_OPENGL_FRAGMENT_SHADER_RGB_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_GBRP16, &FF_OPENGL_FRAGMENT_SHADER_RGB_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_GBRAP, &FF_OPENGL_FRAGMENT_SHADER_RGBA_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_BYTE },
{ AV_PIX_FMT_GBRAP16, &FF_OPENGL_FRAGMENT_SHADER_RGBA_PLANAR, FF_GL_RED_COMPONENT, GL_UNSIGNED_SHORT },
{ AV_PIX_FMT_NONE, NULL }
};
static av_cold int opengl_prepare_vertex(AVFormatContext *s); static av_cold int opengl_prepare_vertex(AVFormatContext *s);
static int opengl_draw(AVFormatContext *h, AVPacket *pkt, int repaint); static int opengl_draw(AVFormatContext *h, AVPacket *pkt, int repaint);
static av_cold int opengl_init_context(OpenGLContext *opengl); static av_cold int opengl_init_context(OpenGLContext *opengl);
static av_cold void opengl_deinit_context(OpenGLContext *opengl)
{
glDeleteTextures(4, opengl->texture_name);
opengl->texture_name[0] = opengl->texture_name[1] =
opengl->texture_name[2] = opengl->texture_name[3] = 0;
if (opengl->glprocs.glUseProgram)
opengl->glprocs.glUseProgram(0);
if (opengl->glprocs.glDeleteProgram) {
opengl->glprocs.glDeleteProgram(opengl->program);
opengl->program = 0;
}
if (opengl->glprocs.glDeleteShader) {
opengl->glprocs.glDeleteShader(opengl->vertex_shader);
opengl->glprocs.glDeleteShader(opengl->fragment_shader);
opengl->vertex_shader = opengl->fragment_shader = 0;
}
if (opengl->glprocs.glBindBuffer) {
opengl->glprocs.glBindBuffer(FF_GL_ARRAY_BUFFER, 0);
opengl->glprocs.glBindBuffer(FF_GL_ELEMENT_ARRAY_BUFFER, 0);
}
if (opengl->glprocs.glDeleteBuffers) {
opengl->glprocs.glDeleteBuffers(2, &opengl->index_buffer);
opengl->vertex_buffer = opengl->index_buffer = 0;
}
}
static int opengl_resize(AVFormatContext *h, int width, int height) static int opengl_resize(AVFormatContext *h, int width, int height)
{ {
int ret = 0; int ret = 0;
...@@ -302,8 +377,7 @@ static int opengl_sdl_process_events(AVFormatContext *h) ...@@ -302,8 +377,7 @@ static int opengl_sdl_process_events(AVFormatContext *h)
SDL_VideoDriverName(buffer, sizeof(buffer)); SDL_VideoDriverName(buffer, sizeof(buffer));
reinit = !av_strncasecmp(buffer, "quartz", sizeof(buffer)); reinit = !av_strncasecmp(buffer, "quartz", sizeof(buffer));
if (reinit) { if (reinit) {
glDeleteTextures(4, opengl->texture_name); opengl_deinit_context(opengl);
opengl->glprocs.glDeleteBuffers(2, &opengl->index_buffer);
} }
if ((ret = opengl_sdl_recreate_window(opengl, event.resize.w, event.resize.h)) < 0) if ((ret = opengl_sdl_recreate_window(opengl, event.resize.w, event.resize.h)) < 0)
return ret; return ret;
...@@ -333,6 +407,7 @@ static int av_cold opengl_sdl_create_window(AVFormatContext *h) ...@@ -333,6 +407,7 @@ static int av_cold opengl_sdl_create_window(AVFormatContext *h)
av_log(opengl, AV_LOG_INFO, "SDL driver: '%s'.\n", SDL_VideoDriverName(buffer, sizeof(buffer))); av_log(opengl, AV_LOG_INFO, "SDL driver: '%s'.\n", SDL_VideoDriverName(buffer, sizeof(buffer)));
message.width = opengl->surface->w; message.width = opengl->surface->w;
message.height = opengl->surface->h; message.height = opengl->surface->h;
SDL_WM_SetCaption(opengl->window_title, NULL);
opengl_control_message(h, AV_APP_TO_DEV_WINDOW_SIZE, &message, sizeof(AVDeviceRect)); opengl_control_message(h, AV_APP_TO_DEV_WINDOW_SIZE, &message, sizeof(AVDeviceRect));
return 0; return 0;
} }
...@@ -385,6 +460,11 @@ static int av_cold opengl_load_procedures(OpenGLContext *opengl) ...@@ -385,6 +460,11 @@ static int av_cold opengl_load_procedures(OpenGLContext *opengl)
{ {
FFOpenGLFunctions *procs = &opengl->glprocs; FFOpenGLFunctions *procs = &opengl->glprocs;
#if HAVE_SDL
if (!opengl->no_window)
return opengl_sdl_load_procedures(opengl);
#endif
procs->glActiveTexture = glActiveTexture; procs->glActiveTexture = glActiveTexture;
procs->glGenBuffers = glGenBuffers; procs->glGenBuffers = glGenBuffers;
procs->glDeleteBuffers = glDeleteBuffers; procs->glDeleteBuffers = glDeleteBuffers;
...@@ -430,6 +510,11 @@ static int av_cold opengl_load_procedures(OpenGLContext *opengl) ...@@ -430,6 +510,11 @@ static int av_cold opengl_load_procedures(OpenGLContext *opengl)
return AVERROR(ENOSYS); \ return AVERROR(ENOSYS); \
} }
#if HAVE_SDL
if (!opengl->no_window)
return opengl_sdl_load_procedures(opengl);
#endif
LOAD_OPENGL_FUN(glActiveTexture, FF_PFNGLACTIVETEXTUREPROC) LOAD_OPENGL_FUN(glActiveTexture, FF_PFNGLACTIVETEXTUREPROC)
LOAD_OPENGL_FUN(glGenBuffers, FF_PFNGLGENBUFFERSPROC) LOAD_OPENGL_FUN(glGenBuffers, FF_PFNGLGENBUFFERSPROC)
LOAD_OPENGL_FUN(glDeleteBuffers, FF_PFNGLDELETEBUFFERSPROC) LOAD_OPENGL_FUN(glDeleteBuffers, FF_PFNGLDELETEBUFFERSPROC)
...@@ -463,16 +548,14 @@ static int av_cold opengl_load_procedures(OpenGLContext *opengl) ...@@ -463,16 +548,14 @@ static int av_cold opengl_load_procedures(OpenGLContext *opengl)
} }
#endif #endif
static av_always_inline void opengl_make_identity(float matrix[16]) static void opengl_make_identity(float matrix[16])
{ {
memset(matrix, 0, 16 * sizeof(float)); memset(matrix, 0, 16 * sizeof(float));
matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.0f; matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.0f;
} }
static av_always_inline void opengl_make_ortho(float matrix[16], static void opengl_make_ortho(float matrix[16], float left, float right,
float left, float right, float bottom, float top, float nearZ, float farZ)
float bottom, float top,
float nearZ, float farZ)
{ {
float ral = right + left; float ral = right + left;
float rsl = right - left; float rsl = right - left;
...@@ -539,43 +622,17 @@ static av_cold int opengl_read_limits(OpenGLContext *opengl) ...@@ -539,43 +622,17 @@ static av_cold int opengl_read_limits(OpenGLContext *opengl)
return AVERROR_EXTERNAL; return AVERROR_EXTERNAL;
} }
static av_always_inline const char * opengl_get_fragment_shader_code(enum AVPixelFormat format) static const char* opengl_get_fragment_shader_code(enum AVPixelFormat format)
{ {
switch (format) { int i;
case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUV444P: for (i = 0; i < FF_ARRAY_ELEMS(opengl_format_desc); i++) {
case AV_PIX_FMT_YUV422P: case AV_PIX_FMT_YUV410P: if (opengl_format_desc[i].fixel_format == format)
case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_YUV440P: return *opengl_format_desc[i].fragment_shader;
case AV_PIX_FMT_YUV420P16: case AV_PIX_FMT_YUV422P16:
case AV_PIX_FMT_YUV444P16:
return FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR;
case AV_PIX_FMT_YUVA420P: case AV_PIX_FMT_YUVA444P:
case AV_PIX_FMT_YUVA422P:
case AV_PIX_FMT_YUVA420P16: case AV_PIX_FMT_YUVA422P16:
case AV_PIX_FMT_YUVA444P16:
return FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR;
case AV_PIX_FMT_RGB24: case AV_PIX_FMT_BGR24:
case AV_PIX_FMT_0RGB: case AV_PIX_FMT_RGB0:
case AV_PIX_FMT_0BGR: case AV_PIX_FMT_BGR0:
case AV_PIX_FMT_RGB565: case AV_PIX_FMT_BGR565:
case AV_PIX_FMT_RGB555: case AV_PIX_FMT_BGR555:
case AV_PIX_FMT_RGB8: case AV_PIX_FMT_BGR8:
case AV_PIX_FMT_RGB48:
return FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET;
case AV_PIX_FMT_ARGB: case AV_PIX_FMT_RGBA:
case AV_PIX_FMT_ABGR: case AV_PIX_FMT_BGRA:
case AV_PIX_FMT_RGBA64: case AV_PIX_FMT_BGRA64:
return FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET;
case AV_PIX_FMT_GBRP: case AV_PIX_FMT_GBRP16:
return FF_OPENGL_FRAGMENT_SHADER_RGB_PLANAR;
case AV_PIX_FMT_GBRAP: case AV_PIX_FMT_GBRAP16:
return FF_OPENGL_FRAGMENT_SHADER_RGBA_PLANAR;
default:
break;
} }
return NULL; return NULL;
} }
static av_always_inline int opengl_type_size(GLenum type) static int opengl_type_size(GLenum type)
{ {
switch(type) { switch(type) {
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT:
...@@ -593,59 +650,13 @@ static av_always_inline int opengl_type_size(GLenum type) ...@@ -593,59 +650,13 @@ static av_always_inline int opengl_type_size(GLenum type)
static av_cold void opengl_get_texture_params(OpenGLContext *opengl) static av_cold void opengl_get_texture_params(OpenGLContext *opengl)
{ {
switch(opengl->pix_fmt) { int i;
case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUV444P: for (i = 0; i < FF_ARRAY_ELEMS(opengl_format_desc); i++) {
case AV_PIX_FMT_YUV422P: case AV_PIX_FMT_YUV410P: if (opengl_format_desc[i].fixel_format == opengl->pix_fmt) {
case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_YUV440P: opengl->format = opengl_format_desc[i].format;
case AV_PIX_FMT_YUVA420P: case AV_PIX_FMT_YUVA444P: opengl->type = opengl_format_desc[i].type;
case AV_PIX_FMT_YUVA422P: break;
case AV_PIX_FMT_GBRP: case AV_PIX_FMT_GBRAP: }
opengl->format = GL_RED_COMPONENT;
opengl->type = GL_UNSIGNED_BYTE;
break;
case AV_PIX_FMT_YUV420P16: case AV_PIX_FMT_YUV422P16:
case AV_PIX_FMT_YUV444P16:
case AV_PIX_FMT_YUVA420P16: case AV_PIX_FMT_YUVA422P16:
case AV_PIX_FMT_YUVA444P16:
case AV_PIX_FMT_GBRP16: case AV_PIX_FMT_GBRAP16:
opengl->format = GL_RED_COMPONENT;
opengl->type = GL_UNSIGNED_SHORT;
break;
case AV_PIX_FMT_RGB24: case AV_PIX_FMT_BGR24:
opengl->format = GL_RGB;
opengl->type = GL_UNSIGNED_BYTE;
break;
case AV_PIX_FMT_ARGB: case AV_PIX_FMT_RGBA:
case AV_PIX_FMT_ABGR: case AV_PIX_FMT_BGRA:
case AV_PIX_FMT_0RGB: case AV_PIX_FMT_RGB0:
case AV_PIX_FMT_0BGR: case AV_PIX_FMT_BGR0:
opengl->format = GL_RGBA;
opengl->type = GL_UNSIGNED_BYTE;
break;
case AV_PIX_FMT_RGB8:
opengl->format = GL_RGB;
opengl->type = FF_GL_UNSIGNED_BYTE_3_3_2;
break;
case AV_PIX_FMT_BGR8:
opengl->format = GL_RGB;
opengl->type = FF_GL_UNSIGNED_BYTE_2_3_3_REV;
break;
case AV_PIX_FMT_RGB555: case AV_PIX_FMT_BGR555:
opengl->format = GL_RGBA;
opengl->type = FF_GL_UNSIGNED_SHORT_1_5_5_5_REV;
break;
case AV_PIX_FMT_RGB565: case AV_PIX_FMT_BGR565:
opengl->format = GL_RGB;
opengl->type = GL_UNSIGNED_SHORT_5_6_5;
break;
case AV_PIX_FMT_RGB48:
opengl->format = GL_RGB;
opengl->type = GL_UNSIGNED_SHORT;
break;
case AV_PIX_FMT_RGBA64: case AV_PIX_FMT_BGRA64:
opengl->format = GL_RGBA;
opengl->type = GL_UNSIGNED_SHORT;
break;
} }
} }
...@@ -756,7 +767,6 @@ static av_cold GLuint opengl_load_shader(OpenGLContext *opengl, GLenum type, con ...@@ -756,7 +767,6 @@ static av_cold GLuint opengl_load_shader(OpenGLContext *opengl, GLenum type, con
static av_cold int opengl_compile_shaders(OpenGLContext *opengl, enum AVPixelFormat pix_fmt) static av_cold int opengl_compile_shaders(OpenGLContext *opengl, enum AVPixelFormat pix_fmt)
{ {
GLuint vertex_shader = 0, fragment_shader = 0;
GLint result; GLint result;
const char *fragment_shader_code = opengl_get_fragment_shader_code(pix_fmt); const char *fragment_shader_code = opengl_get_fragment_shader_code(pix_fmt);
...@@ -766,15 +776,15 @@ static av_cold int opengl_compile_shaders(OpenGLContext *opengl, enum AVPixelFor ...@@ -766,15 +776,15 @@ static av_cold int opengl_compile_shaders(OpenGLContext *opengl, enum AVPixelFor
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
vertex_shader = opengl_load_shader(opengl, FF_GL_VERTEX_SHADER, opengl->vertex_shader = opengl_load_shader(opengl, FF_GL_VERTEX_SHADER,
FF_OPENGL_VERTEX_SHADER); FF_OPENGL_VERTEX_SHADER);
if (!vertex_shader) { if (!opengl->vertex_shader) {
av_log(opengl, AV_LOG_ERROR, "Vertex shader loading failed.\n"); av_log(opengl, AV_LOG_ERROR, "Vertex shader loading failed.\n");
goto fail; goto fail;
} }
fragment_shader = opengl_load_shader(opengl, FF_GL_FRAGMENT_SHADER, opengl->fragment_shader = opengl_load_shader(opengl, FF_GL_FRAGMENT_SHADER,
fragment_shader_code); fragment_shader_code);
if (!fragment_shader) { if (!opengl->fragment_shader) {
av_log(opengl, AV_LOG_ERROR, "Fragment shader loading failed.\n"); av_log(opengl, AV_LOG_ERROR, "Fragment shader loading failed.\n");
goto fail; goto fail;
} }
...@@ -783,8 +793,8 @@ static av_cold int opengl_compile_shaders(OpenGLContext *opengl, enum AVPixelFor ...@@ -783,8 +793,8 @@ static av_cold int opengl_compile_shaders(OpenGLContext *opengl, enum AVPixelFor
if (!opengl->program) if (!opengl->program)
goto fail; goto fail;
opengl->glprocs.glAttachShader(opengl->program, vertex_shader); opengl->glprocs.glAttachShader(opengl->program, opengl->vertex_shader);
opengl->glprocs.glAttachShader(opengl->program, fragment_shader); opengl->glprocs.glAttachShader(opengl->program, opengl->fragment_shader);
opengl->glprocs.glLinkProgram(opengl->program); opengl->glprocs.glLinkProgram(opengl->program);
opengl->glprocs.glGetProgramiv(opengl->program, FF_GL_LINK_STATUS, &result); opengl->glprocs.glGetProgramiv(opengl->program, FF_GL_LINK_STATUS, &result);
...@@ -817,10 +827,10 @@ static av_cold int opengl_compile_shaders(OpenGLContext *opengl, enum AVPixelFor ...@@ -817,10 +827,10 @@ static av_cold int opengl_compile_shaders(OpenGLContext *opengl, enum AVPixelFor
OPENGL_ERROR_CHECK(opengl); OPENGL_ERROR_CHECK(opengl);
return 0; return 0;
fail: fail:
opengl->glprocs.glDeleteShader(vertex_shader); opengl->glprocs.glDeleteShader(opengl->vertex_shader);
opengl->glprocs.glDeleteShader(fragment_shader); opengl->glprocs.glDeleteShader(opengl->fragment_shader);
opengl->glprocs.glDeleteProgram(opengl->program); opengl->glprocs.glDeleteProgram(opengl->program);
opengl->program = 0; opengl->fragment_shader = opengl->vertex_shader = opengl->program = 0;
return AVERROR_EXTERNAL; return AVERROR_EXTERNAL;
} }
...@@ -914,25 +924,59 @@ static int opengl_prepare(OpenGLContext *opengl) ...@@ -914,25 +924,59 @@ static int opengl_prepare(OpenGLContext *opengl)
return AVERROR_EXTERNAL; return AVERROR_EXTERNAL;
} }
static av_cold int opengl_write_trailer(AVFormatContext *h) static int opengl_create_window(AVFormatContext *h)
{ {
OpenGLContext *opengl = h->priv_data; OpenGLContext *opengl = h->priv_data;
int ret;
if (opengl->no_window && if (!opengl->no_window) {
avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER, NULL , 0) < 0) #if HAVE_SDL
av_log(opengl, AV_LOG_ERROR, "Application failed to prepare window buffer.\n"); if ((ret = opengl_sdl_create_window(h)) < 0) {
av_log(opengl, AV_LOG_ERROR, "Cannot create default SDL window.\n");
glDeleteTextures(4, opengl->texture_name); return ret;
if (opengl && opengl->glprocs.glDeleteBuffers) }
opengl->glprocs.glDeleteBuffers(2, &opengl->index_buffer); #else
av_log(opengl, AV_LOG_ERROR, "FFmpeg is compiled without SDL. Cannot create default window.\n");
return AVERROR(ENOSYS);
#endif
} else {
if ((ret = avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_CREATE_WINDOW_BUFFER, NULL , 0)) < 0) {
av_log(opengl, AV_LOG_ERROR, "Application failed to create window buffer.\n");
return ret;
}
if ((ret = avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER, NULL , 0)) < 0) {
av_log(opengl, AV_LOG_ERROR, "Application failed to prepare window buffer.\n");
return ret;
}
}
return 0;
}
static int opengl_release_window(AVFormatContext *h)
{
int ret;
OpenGLContext *opengl = h->priv_data;
if (!opengl->no_window) {
#if HAVE_SDL #if HAVE_SDL
if (!opengl->no_window)
SDL_Quit(); SDL_Quit();
#endif #endif
if (opengl->no_window && } else if ((ret = avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_DESTROY_WINDOW_BUFFER, NULL , 0) < 0)) {
avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_DESTROY_WINDOW_BUFFER, NULL , 0) < 0)
av_log(opengl, AV_LOG_ERROR, "Application failed to release window buffer.\n"); av_log(opengl, AV_LOG_ERROR, "Application failed to release window buffer.\n");
return ret;
}
return 0;
}
static av_cold int opengl_write_trailer(AVFormatContext *h)
{
OpenGLContext *opengl = h->priv_data;
if (opengl->no_window &&
avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER, NULL , 0) < 0)
av_log(opengl, AV_LOG_ERROR, "Application failed to prepare window buffer.\n");
opengl_deinit_context(opengl);
opengl_release_window(h);
return 0; return 0;
} }
...@@ -1016,25 +1060,8 @@ static av_cold int opengl_write_header(AVFormatContext *h) ...@@ -1016,25 +1060,8 @@ static av_cold int opengl_write_header(AVFormatContext *h)
if (!opengl->window_title && !opengl->no_window) if (!opengl->window_title && !opengl->no_window)
opengl->window_title = av_strdup(h->filename); opengl->window_title = av_strdup(h->filename);
if (!opengl->no_window) { if ((ret = opengl_create_window(h)))
#if HAVE_SDL
if ((ret = opengl_sdl_create_window(h)) < 0)
goto fail;
#else
av_log(opengl, AV_LOG_ERROR, "FFmpeg is compiled without SDL. Cannot create default window.\n");
ret = AVERROR(ENOSYS);
goto fail; goto fail;
#endif
} else {
if ((ret = avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_CREATE_WINDOW_BUFFER, NULL , 0)) < 0) {
av_log(opengl, AV_LOG_ERROR, "Application failed to create window buffer.\n");
goto fail;
}
if ((ret = avdevice_dev_to_app_control_message(h, AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER, NULL , 0)) < 0) {
av_log(opengl, AV_LOG_ERROR, "Application failed to prepare window buffer.\n");
goto fail;
}
}
if ((ret = opengl_read_limits(opengl)) < 0) if ((ret = opengl_read_limits(opengl)) < 0)
goto fail; goto fail;
...@@ -1046,12 +1073,7 @@ static av_cold int opengl_write_header(AVFormatContext *h) ...@@ -1046,12 +1073,7 @@ static av_cold int opengl_write_header(AVFormatContext *h)
goto fail; goto fail;
} }
if (!opengl->no_window) { if ((ret = opengl_load_procedures(opengl)) < 0)
#if HAVE_SDL
if ((ret = opengl_sdl_load_procedures(opengl)) < 0)
goto fail;
#endif
} else if ((ret = opengl_load_procedures(opengl)) < 0)
goto fail; goto fail;
opengl_fill_color_map(opengl); opengl_fill_color_map(opengl);
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "libavutil/pixfmt.h" #include "libavutil/pixfmt.h"
const char *FF_OPENGL_VERTEX_SHADER = static const char * const FF_OPENGL_VERTEX_SHADER =
"uniform mat4 u_projectionMatrix;" "uniform mat4 u_projectionMatrix;"
"uniform mat4 u_modelViewMatrix;" "uniform mat4 u_modelViewMatrix;"
...@@ -41,7 +41,7 @@ const char *FF_OPENGL_VERTEX_SHADER = ...@@ -41,7 +41,7 @@ const char *FF_OPENGL_VERTEX_SHADER =
/** /**
* Fragment shader for packet RGBA formats. * Fragment shader for packet RGBA formats.
*/ */
const char *FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET = static const char * const FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET =
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
"precision mediump float;" "precision mediump float;"
#endif #endif
...@@ -58,7 +58,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET = ...@@ -58,7 +58,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_RGBA_PACKET =
/** /**
* Fragment shader for packet RGB formats. * Fragment shader for packet RGB formats.
*/ */
const char *FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET = static const char * const FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET =
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
"precision mediump float;" "precision mediump float;"
#endif #endif
...@@ -75,7 +75,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET = ...@@ -75,7 +75,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET =
/** /**
* Fragment shader for planar RGBA formats. * Fragment shader for planar RGBA formats.
*/ */
const char *FF_OPENGL_FRAGMENT_SHADER_RGBA_PLANAR = static const char * const FF_OPENGL_FRAGMENT_SHADER_RGBA_PLANAR =
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
"precision mediump float;" "precision mediump float;"
#endif #endif
...@@ -97,7 +97,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_RGBA_PLANAR = ...@@ -97,7 +97,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_RGBA_PLANAR =
/** /**
* Fragment shader for planar RGB formats. * Fragment shader for planar RGB formats.
*/ */
const char *FF_OPENGL_FRAGMENT_SHADER_RGB_PLANAR = static const char * const FF_OPENGL_FRAGMENT_SHADER_RGB_PLANAR =
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
"precision mediump float;" "precision mediump float;"
#endif #endif
...@@ -118,7 +118,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_RGB_PLANAR = ...@@ -118,7 +118,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_RGB_PLANAR =
/** /**
* Fragment shader for planar YUV formats. * Fragment shader for planar YUV formats.
*/ */
const char *FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR = static const char * const FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR =
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
"precision mediump float;" "precision mediump float;"
#endif #endif
...@@ -147,7 +147,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR = ...@@ -147,7 +147,7 @@ const char *FF_OPENGL_FRAGMENT_SHADER_YUV_PLANAR =
/** /**
* Fragment shader for planar YUVA formats. * Fragment shader for planar YUVA formats.
*/ */
const char *FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR = static const char * const FF_OPENGL_FRAGMENT_SHADER_YUVA_PLANAR =
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
"precision mediump float;" "precision mediump float;"
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment