00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "libavutil/pixdesc.h"
00025 #include <stdint.h>
00026
00027 #include "config.h"
00028 #include "libswscale/swscale_internal.h"
00029
00030 #if defined(__FDPIC__) && CONFIG_SRAM
00031 #define L1CODE __attribute__((l1_text))
00032 #else
00033 #define L1CODE
00034 #endif
00035
00036 void ff_bfin_yuv2rgb555_line(const uint8_t *Y, const uint8_t *U,
00037 const uint8_t *V, uint8_t *out,
00038 int w, uint32_t *coeffs) L1CODE;
00039
00040 void ff_bfin_yuv2rgb565_line(const uint8_t *Y, const uint8_t *U,
00041 const uint8_t *V, uint8_t *out,
00042 int w, uint32_t *coeffs) L1CODE;
00043
00044 void ff_bfin_yuv2rgb24_line(const uint8_t *Y, const uint8_t *U,
00045 const uint8_t *V, uint8_t *out,
00046 int w, uint32_t *coeffs) L1CODE;
00047
00048 typedef void (*ltransform)(const uint8_t *Y, const uint8_t *U, const uint8_t *V,
00049 uint8_t *out, int w, uint32_t *coeffs);
00050
00051 static void bfin_prepare_coefficients(SwsContext *c, int rgb, int masks)
00052 {
00053 int oy;
00054 oy = c->yOffset & 0xffff;
00055 oy = oy >> 3;
00056
00057 c->oc = 128 * 0x01010101U;
00058 c->oy = oy * 0x01010101U;
00059
00060
00061 c->cy = c->yCoeff;
00062 c->zero = 0;
00063
00064 if (rgb) {
00065 c->crv = c->vrCoeff;
00066 c->cbu = c->ubCoeff;
00067 c->cgu = c->ugCoeff;
00068 c->cgv = c->vgCoeff;
00069 } else {
00070 c->crv = c->ubCoeff;
00071 c->cbu = c->vrCoeff;
00072 c->cgu = c->vgCoeff;
00073 c->cgv = c->ugCoeff;
00074 }
00075
00076 if (masks == 555) {
00077 c->rmask = 0x001f * 0x00010001U;
00078 c->gmask = 0x03e0 * 0x00010001U;
00079 c->bmask = 0x7c00 * 0x00010001U;
00080 } else if (masks == 565) {
00081 c->rmask = 0x001f * 0x00010001U;
00082 c->gmask = 0x07e0 * 0x00010001U;
00083 c->bmask = 0xf800 * 0x00010001U;
00084 }
00085 }
00086
00087 static int core_yuv420_rgb(SwsContext *c, const uint8_t **in, int *instrides,
00088 int srcSliceY, int srcSliceH, uint8_t **oplanes,
00089 int *outstrides, ltransform lcscf,
00090 int rgb, int masks)
00091 {
00092 const uint8_t *py, *pu, *pv;
00093 uint8_t *op;
00094 int w = instrides[0];
00095 int h2 = srcSliceH >> 1;
00096 int i;
00097
00098 bfin_prepare_coefficients(c, rgb, masks);
00099
00100 py = in[0];
00101 pu = in[1 + (1 ^ rgb)];
00102 pv = in[1 + (0 ^ rgb)];
00103
00104 op = oplanes[0] + srcSliceY * outstrides[0];
00105
00106 for (i = 0; i < h2; i++) {
00107 lcscf(py, pu, pv, op, w, &c->oy);
00108
00109 py += instrides[0];
00110 op += outstrides[0];
00111
00112 lcscf(py, pu, pv, op, w, &c->oy);
00113
00114 py += instrides[0];
00115 pu += instrides[1];
00116 pv += instrides[2];
00117 op += outstrides[0];
00118 }
00119
00120 return srcSliceH;
00121 }
00122
00123 static int bfin_yuv420_rgb555(SwsContext *c, const uint8_t **in, int *instrides,
00124 int srcSliceY, int srcSliceH,
00125 uint8_t **oplanes, int *outstrides)
00126 {
00127 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
00128 outstrides, ff_bfin_yuv2rgb555_line, 1, 555);
00129 }
00130
00131 static int bfin_yuv420_bgr555(SwsContext *c, const uint8_t **in, int *instrides,
00132 int srcSliceY, int srcSliceH,
00133 uint8_t **oplanes, int *outstrides)
00134 {
00135 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
00136 outstrides, ff_bfin_yuv2rgb555_line, 0, 555);
00137 }
00138
00139 static int bfin_yuv420_rgb24(SwsContext *c, const uint8_t **in, int *instrides,
00140 int srcSliceY, int srcSliceH,
00141 uint8_t **oplanes, int *outstrides)
00142 {
00143 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
00144 outstrides, ff_bfin_yuv2rgb24_line, 1, 888);
00145 }
00146
00147 static int bfin_yuv420_bgr24(SwsContext *c, const uint8_t **in, int *instrides,
00148 int srcSliceY, int srcSliceH,
00149 uint8_t **oplanes, int *outstrides)
00150 {
00151 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
00152 outstrides, ff_bfin_yuv2rgb24_line, 0, 888);
00153 }
00154
00155 static int bfin_yuv420_rgb565(SwsContext *c, const uint8_t **in, int *instrides,
00156 int srcSliceY, int srcSliceH,
00157 uint8_t **oplanes, int *outstrides)
00158 {
00159 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
00160 outstrides, ff_bfin_yuv2rgb565_line, 1, 565);
00161 }
00162
00163 static int bfin_yuv420_bgr565(SwsContext *c, const uint8_t **in, int *instrides,
00164 int srcSliceY, int srcSliceH,
00165 uint8_t **oplanes, int *outstrides)
00166 {
00167 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
00168 outstrides, ff_bfin_yuv2rgb565_line, 0, 565);
00169 }
00170
00171 SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c)
00172 {
00173 SwsFunc f;
00174
00175 switch (c->dstFormat) {
00176 case PIX_FMT_RGB555:
00177 f = bfin_yuv420_rgb555;
00178 break;
00179 case PIX_FMT_BGR555:
00180 f = bfin_yuv420_bgr555;
00181 break;
00182 case PIX_FMT_RGB565:
00183 f = bfin_yuv420_rgb565;
00184 break;
00185 case PIX_FMT_BGR565:
00186 f = bfin_yuv420_bgr565;
00187 break;
00188 case PIX_FMT_RGB24:
00189 f = bfin_yuv420_rgb24;
00190 break;
00191 case PIX_FMT_BGR24:
00192 f = bfin_yuv420_bgr24;
00193 break;
00194 default:
00195 return 0;
00196 }
00197
00198 av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n",
00199 av_get_pix_fmt_name(c->dstFormat));
00200
00201 return f;
00202 }