Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.  
  24. #include "libavutil/pixdesc.h"
  25. #include <stdint.h>
  26.  
  27. #include "config.h"
  28. #include "libavutil/attributes.h"
  29. #include "libswscale/swscale_internal.h"
  30.  
  31. #if defined(__FDPIC__) && CONFIG_SRAM
  32. #define L1CODE __attribute__((l1_text))
  33. #else
  34. #define L1CODE
  35. #endif
  36.  
  37. void ff_bfin_yuv2rgb555_line(const uint8_t *Y, const uint8_t *U,
  38.                              const uint8_t *V, uint8_t *out,
  39.                              int w, uint32_t *coeffs) L1CODE;
  40.  
  41. void ff_bfin_yuv2rgb565_line(const uint8_t *Y, const uint8_t *U,
  42.                              const uint8_t *V, uint8_t *out,
  43.                              int w, uint32_t *coeffs) L1CODE;
  44.  
  45. void ff_bfin_yuv2rgb24_line(const uint8_t *Y, const uint8_t *U,
  46.                             const uint8_t *V, uint8_t *out,
  47.                             int w, uint32_t *coeffs) L1CODE;
  48.  
  49. typedef void (*ltransform)(const uint8_t *Y, const uint8_t *U, const uint8_t *V,
  50.                            uint8_t *out, int w, uint32_t *coeffs);
  51.  
  52. static void bfin_prepare_coefficients(SwsContext *c, int rgb, int masks)
  53. {
  54.     int oy;
  55.     oy = c->yOffset & 0xffff;
  56.     oy = oy >> 3;      // keep everything U8.0 for offset calculation
  57.  
  58.     c->oc = 128 * 0x01010101U;
  59.     c->oy = oy * 0x01010101U;
  60.  
  61.     /* copy 64bit vector coeffs down to 32bit vector coeffs */
  62.     c->cy   = c->yCoeff;
  63.     c->zero = 0;
  64.  
  65.     if (rgb) {
  66.         c->crv = c->vrCoeff;
  67.         c->cbu = c->ubCoeff;
  68.         c->cgu = c->ugCoeff;
  69.         c->cgv = c->vgCoeff;
  70.     } else {
  71.         c->crv = c->ubCoeff;
  72.         c->cbu = c->vrCoeff;
  73.         c->cgu = c->vgCoeff;
  74.         c->cgv = c->ugCoeff;
  75.     }
  76.  
  77.     if (masks == 555) {
  78.         c->rmask = 0x001f * 0x00010001U;
  79.         c->gmask = 0x03e0 * 0x00010001U;
  80.         c->bmask = 0x7c00 * 0x00010001U;
  81.     } else if (masks == 565) {
  82.         c->rmask = 0x001f * 0x00010001U;
  83.         c->gmask = 0x07e0 * 0x00010001U;
  84.         c->bmask = 0xf800 * 0x00010001U;
  85.     }
  86. }
  87.  
  88. static int core_yuv420_rgb(SwsContext *c, const uint8_t **in, int *instrides,
  89.                            int srcSliceY, int srcSliceH, uint8_t **oplanes,
  90.                            int *outstrides, ltransform lcscf,
  91.                            int rgb, int masks)
  92. {
  93.     const uint8_t *py, *pu, *pv;
  94.     uint8_t *op;
  95.     int w  = instrides[0];
  96.     int h2 = srcSliceH >> 1;
  97.     int i;
  98.  
  99.     bfin_prepare_coefficients(c, rgb, masks);
  100.  
  101.     py = in[0];
  102.     pu = in[1 + (1 ^ rgb)];
  103.     pv = in[1 + (0 ^ rgb)];
  104.  
  105.     op = oplanes[0] + srcSliceY * outstrides[0];
  106.  
  107.     for (i = 0; i < h2; i++) {
  108.         lcscf(py, pu, pv, op, w, &c->oy);
  109.  
  110.         py += instrides[0];
  111.         op += outstrides[0];
  112.  
  113.         lcscf(py, pu, pv, op, w, &c->oy);
  114.  
  115.         py += instrides[0];
  116.         pu += instrides[1];
  117.         pv += instrides[2];
  118.         op += outstrides[0];
  119.     }
  120.  
  121.     return srcSliceH;
  122. }
  123.  
  124. static int bfin_yuv420_rgb555(SwsContext *c, const uint8_t **in, int *instrides,
  125.                               int srcSliceY, int srcSliceH,
  126.                               uint8_t **oplanes, int *outstrides)
  127. {
  128.     return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  129.                            outstrides, ff_bfin_yuv2rgb555_line, 1, 555);
  130. }
  131.  
  132. static int bfin_yuv420_bgr555(SwsContext *c, const uint8_t **in, int *instrides,
  133.                               int srcSliceY, int srcSliceH,
  134.                               uint8_t **oplanes, int *outstrides)
  135. {
  136.     return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  137.                            outstrides, ff_bfin_yuv2rgb555_line, 0, 555);
  138. }
  139.  
  140. static int bfin_yuv420_rgb24(SwsContext *c, const uint8_t **in, int *instrides,
  141.                              int srcSliceY, int srcSliceH,
  142.                              uint8_t **oplanes, int *outstrides)
  143. {
  144.     return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  145.                            outstrides, ff_bfin_yuv2rgb24_line, 1, 888);
  146. }
  147.  
  148. static int bfin_yuv420_bgr24(SwsContext *c, const uint8_t **in, int *instrides,
  149.                              int srcSliceY, int srcSliceH,
  150.                              uint8_t **oplanes, int *outstrides)
  151. {
  152.     return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  153.                            outstrides, ff_bfin_yuv2rgb24_line, 0, 888);
  154. }
  155.  
  156. static int bfin_yuv420_rgb565(SwsContext *c, const uint8_t **in, int *instrides,
  157.                               int srcSliceY, int srcSliceH,
  158.                               uint8_t **oplanes, int *outstrides)
  159. {
  160.     return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  161.                            outstrides, ff_bfin_yuv2rgb565_line, 1, 565);
  162. }
  163.  
  164. static int bfin_yuv420_bgr565(SwsContext *c, const uint8_t **in, int *instrides,
  165.                               int srcSliceY, int srcSliceH,
  166.                               uint8_t **oplanes, int *outstrides)
  167. {
  168.     return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
  169.                            outstrides, ff_bfin_yuv2rgb565_line, 0, 565);
  170. }
  171.  
  172. av_cold SwsFunc ff_yuv2rgb_init_bfin(SwsContext *c)
  173. {
  174.     SwsFunc f;
  175.  
  176.     switch (c->dstFormat) {
  177.     case AV_PIX_FMT_RGB555:
  178.         f = bfin_yuv420_rgb555;
  179.         break;
  180.     case AV_PIX_FMT_BGR555:
  181.         f = bfin_yuv420_bgr555;
  182.         break;
  183.     case AV_PIX_FMT_RGB565:
  184.         f = bfin_yuv420_rgb565;
  185.         break;
  186.     case AV_PIX_FMT_BGR565:
  187.         f = bfin_yuv420_bgr565;
  188.         break;
  189.     case AV_PIX_FMT_RGB24:
  190.         f = bfin_yuv420_rgb24;
  191.         break;
  192.     case AV_PIX_FMT_BGR24:
  193.         f = bfin_yuv420_bgr24;
  194.         break;
  195.     default:
  196.         return 0;
  197.     }
  198.  
  199.     av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n",
  200.            av_get_pix_fmt_name(c->dstFormat));
  201.  
  202.     return f;
  203. }
  204.