Statistics
| Branch: | Revision:

ffmpeg / libswscale / yuv2rgb_bfin.c @ e281d684

History | View | Annotate | Download (6.52 KB)

1 d3f3eea9 Marc Hoffman
/*
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 "rgb2rgb.h"
36
#include "swscale.h"
37
#include "swscale_internal.h"
38
39 d2a4ecaf Mike Frysinger
#ifdef __FDPIC__
40 d3f3eea9 Marc Hoffman
#define L1CODE __attribute__ ((l1_text))
41 d2a4ecaf Mike Frysinger
#else
42
#define L1CODE
43
#endif
44 d3f3eea9 Marc Hoffman
45
extern void ff_bfin_yuv2rgb555_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
46
                                     int w, uint32_t *coeffs) L1CODE;
47
48
extern void ff_bfin_yuv2rgb565_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
49
                                     int w, uint32_t *coeffs) L1CODE;
50
51
extern void ff_bfin_yuv2rgb24_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
52
                                    int w, uint32_t *coeffs) L1CODE;
53
54
typedef void (* ltransform_t)(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
55
                              int w, uint32_t *coeffs);
56
57
58
static void bfin_prepare_coefficients (SwsContext *c, int rgb, int masks)
59
{
60
    int oy;
61
    oy      = c->yOffset&0xffff;
62
    oy      = oy >> 3; // keep everything U8.0 for offset calculation
63
64
    c->oc   = 128*0x01010101U;
65
    c->oy   =  oy*0x01010101U;
66
67
    /* copy 64bit vector coeffs down to 32bit vector coeffs */
68
    c->cy  = c->yCoeff;
69
    c->zero = 0;
70
71
    if (rgb) {
72
        c->crv = c->vrCoeff;
73
        c->cbu = c->ubCoeff;
74
        c->cgu = c->ugCoeff;
75
        c->cgv = c->vgCoeff;
76
    } else {
77
        c->crv = c->ubCoeff;
78
        c->cbu = c->vrCoeff;
79
        c->cgu = c->vgCoeff;
80
        c->cgv = c->ugCoeff;
81
    }
82
83
84
    if (masks == 555) {
85
        c->rmask = 0x001f * 0x00010001U;
86
        c->gmask = 0x03e0 * 0x00010001U;
87
        c->bmask = 0x7c00 * 0x00010001U;
88
    } else if (masks == 565) {
89
        c->rmask = 0x001f * 0x00010001U;
90
        c->gmask = 0x07e0 * 0x00010001U;
91
        c->bmask = 0xf800 * 0x00010001U;
92
    }
93
}
94
95
static int core_yuv420_rgb (SwsContext *c,
96
                            uint8_t **in, int *instrides,
97
                            int srcSliceY, int srcSliceH,
98
                            uint8_t **oplanes, int *outstrides,
99
                            ltransform_t lcscf, int rgb, int masks)
100
{
101
    uint8_t *py,*pu,*pv,*op;
102
    int w  = instrides[0];
103
    int h2 = srcSliceH>>1;
104
    int i;
105
106
    bfin_prepare_coefficients (c, rgb, masks);
107
108
    py = in[0];
109
    pu = in[1+(1^rgb)];
110
    pv = in[1+(0^rgb)];
111
112
    op = oplanes[0] + srcSliceY*outstrides[0];
113
114
    for (i=0;i<h2;i++) {
115
116 30c48a0a Benoit Fouet
        lcscf (py, pu, pv, op, w, &c->oy);
117 d3f3eea9 Marc Hoffman
118
        py += instrides[0];
119
        op += outstrides[0];
120
121 30c48a0a Benoit Fouet
        lcscf (py, pu, pv, op, w, &c->oy);
122 d3f3eea9 Marc Hoffman
123
        py += instrides[0];
124
        pu += instrides[1];
125
        pv += instrides[2];
126
        op += outstrides[0];
127
    }
128
129
    return srcSliceH;
130
}
131
132
133
static int bfin_yuv420_rgb555 (SwsContext *c,
134
                               uint8_t **in, int *instrides,
135
                               int srcSliceY, int srcSliceH,
136
                               uint8_t **oplanes, int *outstrides)
137
{
138 30c48a0a Benoit Fouet
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
139 d3f3eea9 Marc Hoffman
                            ff_bfin_yuv2rgb555_line, 1, 555);
140
}
141
142
static int bfin_yuv420_bgr555 (SwsContext *c,
143
                               uint8_t **in, int *instrides,
144
                               int srcSliceY, int srcSliceH,
145
                               uint8_t **oplanes, int *outstrides)
146
{
147 30c48a0a Benoit Fouet
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
148 d3f3eea9 Marc Hoffman
                            ff_bfin_yuv2rgb555_line, 0, 555);
149
}
150
151
static int bfin_yuv420_rgb24 (SwsContext *c,
152
                              uint8_t **in, int *instrides,
153
                              int srcSliceY, int srcSliceH,
154
                              uint8_t **oplanes, int *outstrides)
155
{
156 30c48a0a Benoit Fouet
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
157 d3f3eea9 Marc Hoffman
                            ff_bfin_yuv2rgb24_line, 1, 888);
158
}
159
160
static int bfin_yuv420_bgr24 (SwsContext *c,
161
                              uint8_t **in, int *instrides,
162
                              int srcSliceY, int srcSliceH,
163
                              uint8_t **oplanes, int *outstrides)
164
{
165 30c48a0a Benoit Fouet
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
166 d3f3eea9 Marc Hoffman
                            ff_bfin_yuv2rgb24_line, 0, 888);
167
}
168
169
static int bfin_yuv420_rgb565 (SwsContext *c,
170
                               uint8_t **in, int *instrides,
171
                               int srcSliceY, int srcSliceH,
172
                               uint8_t **oplanes, int *outstrides)
173
{
174 30c48a0a Benoit Fouet
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
175 d3f3eea9 Marc Hoffman
                            ff_bfin_yuv2rgb565_line, 1, 565);
176
}
177
178
static int bfin_yuv420_bgr565 (SwsContext *c,
179
                               uint8_t **in, int *instrides,
180
                               int srcSliceY, int srcSliceH,
181
                               uint8_t **oplanes, int *outstrides)
182
{
183 30c48a0a Benoit Fouet
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
184 d3f3eea9 Marc Hoffman
                            ff_bfin_yuv2rgb565_line, 0, 565);
185
}
186
187
188
SwsFunc ff_bfin_yuv2rgb_get_func_ptr (SwsContext *c)
189
{
190
    SwsFunc f;
191
192
    switch(c->dstFormat) {
193
    case PIX_FMT_RGB555: f = bfin_yuv420_rgb555; break;
194
    case PIX_FMT_BGR555: f = bfin_yuv420_bgr555; break;
195
    case PIX_FMT_RGB565: f = bfin_yuv420_rgb565; break;
196
    case PIX_FMT_BGR565: f = bfin_yuv420_bgr565; break;
197
    case PIX_FMT_RGB24:  f = bfin_yuv420_rgb24;  break;
198
    case PIX_FMT_BGR24:  f = bfin_yuv420_bgr24;  break;
199
    default:
200
        return 0;
201
    }
202
203
    av_log(c, AV_LOG_INFO, "BlackFin Accelerated Color Space Converter %s\n",
204
           sws_format_name (c->dstFormat));
205
206
    return f;
207
}