renderer_yuv420p.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Copyright (c) 2016 Bilibili
  3. * copyright (c) 2016 Zhang Rui <bbcallen@gmail.com>
  4. *
  5. * This file is part of ijkPlayer.
  6. *
  7. * ijkPlayer is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * ijkPlayer is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with ijkPlayer; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "internal.h"
  22. static GLboolean yuv420p_use(IJK_GLES2_Renderer *renderer)
  23. {
  24. ALOGI("use render yuv420p\n");
  25. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  26. glUseProgram(renderer->program); IJK_GLES2_checkError_TRACE("glUseProgram");
  27. if (0 == renderer->plane_textures[0])
  28. glGenTextures(3, renderer->plane_textures);
  29. for (int i = 0; i < 3; ++i) {
  30. glActiveTexture(GL_TEXTURE0 + i);
  31. glBindTexture(GL_TEXTURE_2D, renderer->plane_textures[i]);
  32. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  33. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  34. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  35. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  36. glUniform1i(renderer->us2_sampler[i], i);
  37. }
  38. glUniformMatrix3fv(renderer->um3_color_conversion, 1, GL_FALSE, IJK_GLES2_getColorMatrix_bt709());
  39. return GL_TRUE;
  40. }
  41. static GLsizei yuv420p_getBufferWidth(IJK_GLES2_Renderer *renderer, SDL_VoutOverlay *overlay)
  42. {
  43. if (!overlay)
  44. return 0;
  45. return overlay->pitches[0] / 1;
  46. }
  47. static GLboolean yuv420p_uploadTexture(IJK_GLES2_Renderer *renderer, SDL_VoutOverlay *overlay)
  48. {
  49. if (!renderer || !overlay)
  50. return GL_FALSE;
  51. int planes[3] = { 0, 1, 2 };
  52. const GLsizei widths[3] = { overlay->pitches[0], overlay->pitches[1], overlay->pitches[2] };
  53. const GLsizei heights[3] = { overlay->h, overlay->h / 2, overlay->h / 2 };
  54. const GLubyte *pixels[3] = { overlay->pixels[0], overlay->pixels[1], overlay->pixels[2] };
  55. switch (overlay->format) {
  56. case SDL_FCC_I420:
  57. break;
  58. case SDL_FCC_YV12:
  59. planes[1] = 2;
  60. planes[2] = 1;
  61. break;
  62. default:
  63. ALOGE("[yuv420p] unexpected format %x\n", overlay->format);
  64. return GL_FALSE;
  65. }
  66. for (int i = 0; i < 3; ++i) {
  67. int plane = planes[i];
  68. glBindTexture(GL_TEXTURE_2D, renderer->plane_textures[i]);
  69. glTexImage2D(GL_TEXTURE_2D,
  70. 0,
  71. GL_LUMINANCE,
  72. widths[plane],
  73. heights[plane],
  74. 0,
  75. GL_LUMINANCE,
  76. GL_UNSIGNED_BYTE,
  77. pixels[plane]);
  78. }
  79. return GL_TRUE;
  80. }
  81. IJK_GLES2_Renderer *IJK_GLES2_Renderer_create_yuv420p()
  82. {
  83. ALOGI("create render yuv420p\n");
  84. IJK_GLES2_Renderer *renderer = IJK_GLES2_Renderer_create_base(IJK_GLES2_getFragmentShader_yuv420p());
  85. if (!renderer)
  86. goto fail;
  87. renderer->us2_sampler[0] = glGetUniformLocation(renderer->program, "us2_SamplerX"); IJK_GLES2_checkError_TRACE("glGetUniformLocation(us2_SamplerX)");
  88. renderer->us2_sampler[1] = glGetUniformLocation(renderer->program, "us2_SamplerY"); IJK_GLES2_checkError_TRACE("glGetUniformLocation(us2_SamplerY)");
  89. renderer->us2_sampler[2] = glGetUniformLocation(renderer->program, "us2_SamplerZ"); IJK_GLES2_checkError_TRACE("glGetUniformLocation(us2_SamplerZ)");
  90. renderer->um3_color_conversion = glGetUniformLocation(renderer->program, "um3_ColorConversion"); IJK_GLES2_checkError_TRACE("glGetUniformLocation(um3_ColorConversionMatrix)");
  91. renderer->func_use = yuv420p_use;
  92. renderer->func_getBufferWidth = yuv420p_getBufferWidth;
  93. renderer->func_uploadTexture = yuv420p_uploadTexture;
  94. return renderer;
  95. fail:
  96. IJK_GLES2_Renderer_free(renderer);
  97. return NULL;
  98. }