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