Mercurial > mplayer.hg
comparison libswscale/yuv2rgb_bfin.c @ 23289:786823779b67
Blackfin optimized YUV420 to RGB CSC Color Space Converters.
YUV2 -> RGB BGR for 565, 555 and 888 a.k.a. 24bit color.
Speed-up compared to C version compiled with -O3 187.28%
Patch by Marc Hoffman %mmh A pleasantst P com%
Original thread:
Date: May 9, 2007 2:46 AM
Subject: [FFmpeg-devel] PATCH BlackFin yuv2rgb color space conversion
author | gpoirier |
---|---|
date | Sun, 13 May 2007 19:22:32 +0000 |
parents | |
children | e88ed9dc0737 |
comparison
equal
deleted
inserted
replaced
23288:3e0d632ec805 | 23289:786823779b67 |
---|---|
1 /* | |
2 * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> | |
3 * April 20, 2007 | |
4 * | |
5 * Blackfin Video Color Space Converters Operations | |
6 * convert I420 YV12 to RGB in various formats, | |
7 * | |
8 * This file is part of FFmpeg. | |
9 * | |
10 * FFmpeg is free software; you can redistribute it and/or | |
11 * modify it under the terms of the GNU Lesser General Public | |
12 * License as published by the Free Software Foundation; either | |
13 * version 2.1 of the License, or (at your option) any later version. | |
14 * | |
15 * FFmpeg is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 * Lesser General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU Lesser General Public | |
21 * License along with FFmpeg; if not, write to the Free Software | |
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
23 */ | |
24 | |
25 #include <stdio.h> | |
26 #include <stdlib.h> | |
27 #include <string.h> | |
28 #include <inttypes.h> | |
29 #include <assert.h> | |
30 #include "config.h" | |
31 #ifdef HAVE_MALLOC_H | |
32 #include <malloc.h> | |
33 #endif | |
34 #include <unistd.h> | |
35 #include <bits/bfin_sram.h> | |
36 #include "rgb2rgb.h" | |
37 #include "swscale.h" | |
38 #include "swscale_internal.h" | |
39 | |
40 | |
41 #define L1CODE __attribute__ ((l1_text)) | |
42 | |
43 extern void ff_bfin_yuv2rgb555_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out, | |
44 int w, uint32_t *coeffs) L1CODE; | |
45 | |
46 extern void ff_bfin_yuv2rgb565_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out, | |
47 int w, uint32_t *coeffs) L1CODE; | |
48 | |
49 extern void ff_bfin_yuv2rgb24_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out, | |
50 int w, uint32_t *coeffs) L1CODE; | |
51 | |
52 typedef void (* ltransform_t)(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out, | |
53 int w, uint32_t *coeffs); | |
54 | |
55 | |
56 static void bfin_prepare_coefficients (SwsContext *c, int rgb, int masks) | |
57 { | |
58 int oy; | |
59 oy = c->yOffset&0xffff; | |
60 oy = oy >> 3; // keep everything U8.0 for offset calculation | |
61 | |
62 c->oc = 128*0x01010101U; | |
63 c->oy = oy*0x01010101U; | |
64 | |
65 /* copy 64bit vector coeffs down to 32bit vector coeffs */ | |
66 c->cy = c->yCoeff; | |
67 c->zero = 0; | |
68 | |
69 if (rgb) { | |
70 c->crv = c->vrCoeff; | |
71 c->cbu = c->ubCoeff; | |
72 c->cgu = c->ugCoeff; | |
73 c->cgv = c->vgCoeff; | |
74 } else { | |
75 c->crv = c->ubCoeff; | |
76 c->cbu = c->vrCoeff; | |
77 c->cgu = c->vgCoeff; | |
78 c->cgv = c->ugCoeff; | |
79 } | |
80 | |
81 | |
82 if (masks == 555) { | |
83 c->rmask = 0x001f * 0x00010001U; | |
84 c->gmask = 0x03e0 * 0x00010001U; | |
85 c->bmask = 0x7c00 * 0x00010001U; | |
86 } else if (masks == 565) { | |
87 c->rmask = 0x001f * 0x00010001U; | |
88 c->gmask = 0x07e0 * 0x00010001U; | |
89 c->bmask = 0xf800 * 0x00010001U; | |
90 } | |
91 } | |
92 | |
93 static int core_yuv420_rgb (SwsContext *c, | |
94 uint8_t **in, int *instrides, | |
95 int srcSliceY, int srcSliceH, | |
96 uint8_t **oplanes, int *outstrides, | |
97 ltransform_t lcscf, int rgb, int masks) | |
98 { | |
99 uint8_t *py,*pu,*pv,*op; | |
100 int w = instrides[0]; | |
101 int h2 = srcSliceH>>1; | |
102 int i; | |
103 | |
104 bfin_prepare_coefficients (c, rgb, masks); | |
105 | |
106 py = in[0]; | |
107 pu = in[1+(1^rgb)]; | |
108 pv = in[1+(0^rgb)]; | |
109 | |
110 op = oplanes[0] + srcSliceY*outstrides[0]; | |
111 | |
112 for (i=0;i<h2;i++) { | |
113 | |
114 lcscf (py,pu,pv,op,w,&c->oy); | |
115 | |
116 py += instrides[0]; | |
117 op += outstrides[0]; | |
118 | |
119 lcscf (py,pu,pv,op,w,&c->oy); | |
120 | |
121 py += instrides[0]; | |
122 pu += instrides[1]; | |
123 pv += instrides[2]; | |
124 op += outstrides[0]; | |
125 } | |
126 | |
127 return srcSliceH; | |
128 } | |
129 | |
130 | |
131 static int bfin_yuv420_rgb555 (SwsContext *c, | |
132 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,outstrides, | |
137 ff_bfin_yuv2rgb555_line, 1, 555); | |
138 } | |
139 | |
140 static int bfin_yuv420_bgr555 (SwsContext *c, | |
141 uint8_t **in, int *instrides, | |
142 int srcSliceY, int srcSliceH, | |
143 uint8_t **oplanes, int *outstrides) | |
144 { | |
145 return core_yuv420_rgb (c,in,instrides,srcSliceY,srcSliceH,oplanes,outstrides, | |
146 ff_bfin_yuv2rgb555_line, 0, 555); | |
147 } | |
148 | |
149 static int bfin_yuv420_rgb24 (SwsContext *c, | |
150 uint8_t **in, int *instrides, | |
151 int srcSliceY, int srcSliceH, | |
152 uint8_t **oplanes, int *outstrides) | |
153 { | |
154 return core_yuv420_rgb (c,in,instrides,srcSliceY,srcSliceH,oplanes,outstrides, | |
155 ff_bfin_yuv2rgb24_line, 1, 888); | |
156 } | |
157 | |
158 static int bfin_yuv420_bgr24 (SwsContext *c, | |
159 uint8_t **in, int *instrides, | |
160 int srcSliceY, int srcSliceH, | |
161 uint8_t **oplanes, int *outstrides) | |
162 { | |
163 return core_yuv420_rgb (c,in,instrides,srcSliceY,srcSliceH,oplanes,outstrides, | |
164 ff_bfin_yuv2rgb24_line, 0, 888); | |
165 } | |
166 | |
167 static int bfin_yuv420_rgb565 (SwsContext *c, | |
168 uint8_t **in, int *instrides, | |
169 int srcSliceY, int srcSliceH, | |
170 uint8_t **oplanes, int *outstrides) | |
171 { | |
172 return core_yuv420_rgb (c,in,instrides,srcSliceY,srcSliceH,oplanes,outstrides, | |
173 ff_bfin_yuv2rgb565_line, 1, 565); | |
174 } | |
175 | |
176 static int bfin_yuv420_bgr565 (SwsContext *c, | |
177 uint8_t **in, int *instrides, | |
178 int srcSliceY, int srcSliceH, | |
179 uint8_t **oplanes, int *outstrides) | |
180 { | |
181 return core_yuv420_rgb (c,in,instrides,srcSliceY,srcSliceH,oplanes,outstrides, | |
182 ff_bfin_yuv2rgb565_line, 0, 565); | |
183 } | |
184 | |
185 | |
186 SwsFunc ff_bfin_yuv2rgb_get_func_ptr (SwsContext *c) | |
187 { | |
188 SwsFunc f; | |
189 | |
190 switch(c->dstFormat) { | |
191 case PIX_FMT_RGB555: f = bfin_yuv420_rgb555; break; | |
192 case PIX_FMT_BGR555: f = bfin_yuv420_bgr555; break; | |
193 case PIX_FMT_RGB565: f = bfin_yuv420_rgb565; break; | |
194 case PIX_FMT_BGR565: f = bfin_yuv420_bgr565; break; | |
195 case PIX_FMT_RGB24: f = bfin_yuv420_rgb24; break; | |
196 case PIX_FMT_BGR24: f = bfin_yuv420_bgr24; break; | |
197 default: | |
198 return 0; | |
199 } | |
200 | |
201 av_log(c, AV_LOG_INFO, "BlackFin Accelerated Color Space Converter %s\n", | |
202 sws_format_name (c->dstFormat)); | |
203 | |
204 return f; | |
205 } |