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