yuv2rgb_bfin.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
  3. *
  4. * Blackfin video color space converter operations
  5. * convert I420 YV12 to RGB in various formats
  6. *
  7. * This file is part of FFmpeg.
  8. *
  9. * FFmpeg is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * FFmpeg is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with FFmpeg; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include "libavutil/pixdesc.h"
  24. #include <stdint.h>
  25. #include "config.h"
  26. #include "libswscale/swscale_internal.h"
  27. #if defined(__FDPIC__) && CONFIG_SRAM
  28. #define L1CODE __attribute__((l1_text))
  29. #else
  30. #define L1CODE
  31. #endif
  32. void ff_bfin_yuv2rgb555_line(const uint8_t *Y, const uint8_t *U,
  33. const uint8_t *V, uint8_t *out,
  34. int w, uint32_t *coeffs) L1CODE;
  35. void ff_bfin_yuv2rgb565_line(const uint8_t *Y, const uint8_t *U,
  36. const uint8_t *V, uint8_t *out,
  37. int w, uint32_t *coeffs) L1CODE;
  38. void ff_bfin_yuv2rgb24_line(const uint8_t *Y, const uint8_t *U,
  39. const uint8_t *V, uint8_t *out,
  40. int w, uint32_t *coeffs) L1CODE;
  41. typedef void (*ltransform)(const uint8_t *Y, const uint8_t *U, const uint8_t *V,
  42. uint8_t *out, int w, uint32_t *coeffs);
  43. static void bfin_prepare_coefficients(SwsContext *c, int rgb, int masks)
  44. {
  45. int oy;
  46. oy = c->yOffset & 0xffff;
  47. oy = oy >> 3; // keep everything U8.0 for offset calculation
  48. c->oc = 128 * 0x01010101U;
  49. c->oy = oy * 0x01010101U;
  50. /* copy 64bit vector coeffs down to 32bit vector coeffs */
  51. c->cy = c->yCoeff;
  52. c->zero = 0;
  53. if (rgb) {
  54. c->crv = c->vrCoeff;
  55. c->cbu = c->ubCoeff;
  56. c->cgu = c->ugCoeff;
  57. c->cgv = c->vgCoeff;
  58. } else {
  59. c->crv = c->ubCoeff;
  60. c->cbu = c->vrCoeff;
  61. c->cgu = c->vgCoeff;
  62. c->cgv = c->ugCoeff;
  63. }
  64. if (masks == 555) {
  65. c->rmask = 0x001f * 0x00010001U;
  66. c->gmask = 0x03e0 * 0x00010001U;
  67. c->bmask = 0x7c00 * 0x00010001U;
  68. } else if (masks == 565) {
  69. c->rmask = 0x001f * 0x00010001U;
  70. c->gmask = 0x07e0 * 0x00010001U;
  71. c->bmask = 0xf800 * 0x00010001U;
  72. }
  73. }
  74. static int core_yuv420_rgb(SwsContext *c, const uint8_t **in, int *instrides,
  75. int srcSliceY, int srcSliceH, uint8_t **oplanes,
  76. int *outstrides, ltransform lcscf,
  77. int rgb, int masks)
  78. {
  79. const uint8_t *py, *pu, *pv;
  80. uint8_t *op;
  81. int w = instrides[0];
  82. int h2 = srcSliceH >> 1;
  83. int i;
  84. bfin_prepare_coefficients(c, rgb, masks);
  85. py = in[0];
  86. pu = in[1 + (1 ^ rgb)];
  87. pv = in[1 + (0 ^ rgb)];
  88. op = oplanes[0] + srcSliceY * outstrides[0];
  89. for (i = 0; i < h2; i++) {
  90. lcscf(py, pu, pv, op, w, &c->oy);
  91. py += instrides[0];
  92. op += outstrides[0];
  93. lcscf(py, pu, pv, op, w, &c->oy);
  94. py += instrides[0];
  95. pu += instrides[1];
  96. pv += instrides[2];
  97. op += outstrides[0];
  98. }
  99. return srcSliceH;
  100. }
  101. static int bfin_yuv420_rgb555(SwsContext *c, const uint8_t **in, int *instrides,
  102. int srcSliceY, int srcSliceH,
  103. uint8_t **oplanes, int *outstrides)
  104. {
  105. return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  106. outstrides, ff_bfin_yuv2rgb555_line, 1, 555);
  107. }
  108. static int bfin_yuv420_bgr555(SwsContext *c, const uint8_t **in, int *instrides,
  109. int srcSliceY, int srcSliceH,
  110. uint8_t **oplanes, int *outstrides)
  111. {
  112. return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  113. outstrides, ff_bfin_yuv2rgb555_line, 0, 555);
  114. }
  115. static int bfin_yuv420_rgb24(SwsContext *c, const uint8_t **in, int *instrides,
  116. int srcSliceY, int srcSliceH,
  117. uint8_t **oplanes, int *outstrides)
  118. {
  119. return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  120. outstrides, ff_bfin_yuv2rgb24_line, 1, 888);
  121. }
  122. static int bfin_yuv420_bgr24(SwsContext *c, const uint8_t **in, int *instrides,
  123. int srcSliceY, int srcSliceH,
  124. uint8_t **oplanes, int *outstrides)
  125. {
  126. return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  127. outstrides, ff_bfin_yuv2rgb24_line, 0, 888);
  128. }
  129. static int bfin_yuv420_rgb565(SwsContext *c, const uint8_t **in, int *instrides,
  130. int srcSliceY, int srcSliceH,
  131. uint8_t **oplanes, int *outstrides)
  132. {
  133. return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  134. outstrides, ff_bfin_yuv2rgb565_line, 1, 565);
  135. }
  136. static int bfin_yuv420_bgr565(SwsContext *c, const uint8_t **in, int *instrides,
  137. int srcSliceY, int srcSliceH,
  138. uint8_t **oplanes, int *outstrides)
  139. {
  140. return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  141. outstrides, ff_bfin_yuv2rgb565_line, 0, 565);
  142. }
  143. SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c)
  144. {
  145. SwsFunc f;
  146. switch (c->dstFormat) {
  147. case PIX_FMT_RGB555:
  148. f = bfin_yuv420_rgb555;
  149. break;
  150. case PIX_FMT_BGR555:
  151. f = bfin_yuv420_bgr555;
  152. break;
  153. case PIX_FMT_RGB565:
  154. f = bfin_yuv420_rgb565;
  155. break;
  156. case PIX_FMT_BGR565:
  157. f = bfin_yuv420_bgr565;
  158. break;
  159. case PIX_FMT_RGB24:
  160. f = bfin_yuv420_rgb24;
  161. break;
  162. case PIX_FMT_BGR24:
  163. f = bfin_yuv420_bgr24;
  164. break;
  165. default:
  166. return 0;
  167. }
  168. av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n",
  169. av_get_pix_fmt_name(c->dstFormat));
  170. return f;
  171. }