Libav
|
00001 /* 00002 * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> 00003 * 00004 * Blackfin video color space converter operations 00005 * convert I420 YV12 to RGB in various formats 00006 * 00007 * This file is part of FFmpeg. 00008 * 00009 * FFmpeg is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * FFmpeg is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with FFmpeg; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 "libswscale/rgb2rgb.h" 00032 #include "libswscale/swscale.h" 00033 #include "libswscale/swscale_internal.h" 00034 00035 #if defined(__FDPIC__) && CONFIG_SRAM 00036 #define L1CODE __attribute__ ((l1_text)) 00037 #else 00038 #define L1CODE 00039 #endif 00040 00041 void ff_bfin_yuv2rgb555_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out, 00042 int w, uint32_t *coeffs) L1CODE; 00043 00044 void ff_bfin_yuv2rgb565_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out, 00045 int w, uint32_t *coeffs) L1CODE; 00046 00047 void ff_bfin_yuv2rgb24_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out, 00048 int w, uint32_t *coeffs) L1CODE; 00049 00050 typedef void (* ltransform)(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out, 00051 int w, uint32_t *coeffs); 00052 00053 00054 static void bfin_prepare_coefficients(SwsContext *c, int rgb, int masks) 00055 { 00056 int oy; 00057 oy = c->yOffset&0xffff; 00058 oy = oy >> 3; // keep everything U8.0 for offset calculation 00059 00060 c->oc = 128*0x01010101U; 00061 c->oy = oy*0x01010101U; 00062 00063 /* copy 64bit vector coeffs down to 32bit vector coeffs */ 00064 c->cy = c->yCoeff; 00065 c->zero = 0; 00066 00067 if (rgb) { 00068 c->crv = c->vrCoeff; 00069 c->cbu = c->ubCoeff; 00070 c->cgu = c->ugCoeff; 00071 c->cgv = c->vgCoeff; 00072 } else { 00073 c->crv = c->ubCoeff; 00074 c->cbu = c->vrCoeff; 00075 c->cgu = c->vgCoeff; 00076 c->cgv = c->ugCoeff; 00077 } 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, 00092 uint8_t **in, int *instrides, 00093 int srcSliceY, int srcSliceH, 00094 uint8_t **oplanes, int *outstrides, 00095 ltransform lcscf, int rgb, int masks) 00096 { 00097 uint8_t *py,*pu,*pv,*op; 00098 int w = instrides[0]; 00099 int h2 = srcSliceH>>1; 00100 int i; 00101 00102 bfin_prepare_coefficients(c, rgb, masks); 00103 00104 py = in[0]; 00105 pu = in[1+(1^rgb)]; 00106 pv = in[1+(0^rgb)]; 00107 00108 op = oplanes[0] + srcSliceY*outstrides[0]; 00109 00110 for (i=0;i<h2;i++) { 00111 00112 lcscf(py, pu, pv, op, w, &c->oy); 00113 00114 py += instrides[0]; 00115 op += outstrides[0]; 00116 00117 lcscf(py, pu, pv, op, w, &c->oy); 00118 00119 py += instrides[0]; 00120 pu += instrides[1]; 00121 pv += instrides[2]; 00122 op += outstrides[0]; 00123 } 00124 00125 return srcSliceH; 00126 } 00127 00128 00129 static int bfin_yuv420_rgb555(SwsContext *c, 00130 uint8_t **in, int *instrides, 00131 int srcSliceY, int srcSliceH, 00132 uint8_t **oplanes, int *outstrides) 00133 { 00134 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes, 00135 outstrides, ff_bfin_yuv2rgb555_line, 1, 555); 00136 } 00137 00138 static int bfin_yuv420_bgr555(SwsContext *c, 00139 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_yuv2rgb555_line, 0, 555); 00145 } 00146 00147 static int bfin_yuv420_rgb24(SwsContext *c, 00148 uint8_t **in, int *instrides, 00149 int srcSliceY, int srcSliceH, 00150 uint8_t **oplanes, int *outstrides) 00151 { 00152 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes, 00153 outstrides, ff_bfin_yuv2rgb24_line, 1, 888); 00154 } 00155 00156 static int bfin_yuv420_bgr24(SwsContext *c, 00157 uint8_t **in, int *instrides, 00158 int srcSliceY, int srcSliceH, 00159 uint8_t **oplanes, int *outstrides) 00160 { 00161 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes, 00162 outstrides, ff_bfin_yuv2rgb24_line, 0, 888); 00163 } 00164 00165 static int bfin_yuv420_rgb565(SwsContext *c, 00166 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, 1, 565); 00172 } 00173 00174 static int bfin_yuv420_bgr565(SwsContext *c, 00175 uint8_t **in, int *instrides, 00176 int srcSliceY, int srcSliceH, 00177 uint8_t **oplanes, int *outstrides) 00178 { 00179 return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes, 00180 outstrides, ff_bfin_yuv2rgb565_line, 0, 565); 00181 } 00182 00183 00184 SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c) 00185 { 00186 SwsFunc f; 00187 00188 switch(c->dstFormat) { 00189 case PIX_FMT_RGB555: f = bfin_yuv420_rgb555; break; 00190 case PIX_FMT_BGR555: f = bfin_yuv420_bgr555; break; 00191 case PIX_FMT_RGB565: f = bfin_yuv420_rgb565; break; 00192 case PIX_FMT_BGR565: f = bfin_yuv420_bgr565; break; 00193 case PIX_FMT_RGB24: f = bfin_yuv420_rgb24; break; 00194 case PIX_FMT_BGR24: f = bfin_yuv420_bgr24; break; 00195 default: 00196 return 0; 00197 } 00198 00199 av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n", 00200 sws_format_name (c->dstFormat)); 00201 00202 return f; 00203 }