Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * Copyright (C) 2007 Marc Hoffman 
3
 *
4
 * Blackfin video color space converter operations
5
 * convert I420 YV12 to RGB in various formats
6
 *
7
 * This file is part of FFmpeg.
8
 *
9
 * FFmpeg is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * FFmpeg is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with FFmpeg; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
 
24
#include "libavutil/pixdesc.h"
25
#include 
26
 
27
#include "config.h"
28
#include "libavutil/attributes.h"
29
#include "libswscale/swscale_internal.h"
30
 
31
#if defined(__FDPIC__) && CONFIG_SRAM
32
#define L1CODE __attribute__((l1_text))
33
#else
34
#define L1CODE
35
#endif
36
 
37
void ff_bfin_yuv2rgb555_line(const uint8_t *Y, const uint8_t *U,
38
                             const uint8_t *V, uint8_t *out,
39
                             int w, uint32_t *coeffs) L1CODE;
40
 
41
void ff_bfin_yuv2rgb565_line(const uint8_t *Y, const uint8_t *U,
42
                             const uint8_t *V, uint8_t *out,
43
                             int w, uint32_t *coeffs) L1CODE;
44
 
45
void ff_bfin_yuv2rgb24_line(const uint8_t *Y, const uint8_t *U,
46
                            const uint8_t *V, uint8_t *out,
47
                            int w, uint32_t *coeffs) L1CODE;
48
 
49
typedef void (*ltransform)(const uint8_t *Y, const uint8_t *U, const uint8_t *V,
50
                           uint8_t *out, int w, uint32_t *coeffs);
51
 
52
static void bfin_prepare_coefficients(SwsContext *c, int rgb, int masks)
53
{
54
    int oy;
55
    oy = c->yOffset & 0xffff;
56
    oy = oy >> 3;      // keep everything U8.0 for offset calculation
57
 
58
    c->oc = 128 * 0x01010101U;
59
    c->oy = oy * 0x01010101U;
60
 
61
    /* copy 64bit vector coeffs down to 32bit vector coeffs */
62
    c->cy   = c->yCoeff;
63
    c->zero = 0;
64
 
65
    if (rgb) {
66
        c->crv = c->vrCoeff;
67
        c->cbu = c->ubCoeff;
68
        c->cgu = c->ugCoeff;
69
        c->cgv = c->vgCoeff;
70
    } else {
71
        c->crv = c->ubCoeff;
72
        c->cbu = c->vrCoeff;
73
        c->cgu = c->vgCoeff;
74
        c->cgv = c->ugCoeff;
75
    }
76
 
77
    if (masks == 555) {
78
        c->rmask = 0x001f * 0x00010001U;
79
        c->gmask = 0x03e0 * 0x00010001U;
80
        c->bmask = 0x7c00 * 0x00010001U;
81
    } else if (masks == 565) {
82
        c->rmask = 0x001f * 0x00010001U;
83
        c->gmask = 0x07e0 * 0x00010001U;
84
        c->bmask = 0xf800 * 0x00010001U;
85
    }
86
}
87
 
88
static int core_yuv420_rgb(SwsContext *c, const uint8_t **in, int *instrides,
89
                           int srcSliceY, int srcSliceH, uint8_t **oplanes,
90
                           int *outstrides, ltransform lcscf,
91
                           int rgb, int masks)
92
{
93
    const uint8_t *py, *pu, *pv;
94
    uint8_t *op;
95
    int w  = instrides[0];
96
    int h2 = srcSliceH >> 1;
97
    int i;
98
 
99
    bfin_prepare_coefficients(c, rgb, masks);
100
 
101
    py = in[0];
102
    pu = in[1 + (1 ^ rgb)];
103
    pv = in[1 + (0 ^ rgb)];
104
 
105
    op = oplanes[0] + srcSliceY * outstrides[0];
106
 
107
    for (i = 0; i < h2; i++) {
108
        lcscf(py, pu, pv, op, w, &c->oy);
109
 
110
        py += instrides[0];
111
        op += outstrides[0];
112
 
113
        lcscf(py, pu, pv, op, w, &c->oy);
114
 
115
        py += instrides[0];
116
        pu += instrides[1];
117
        pv += instrides[2];
118
        op += outstrides[0];
119
    }
120
 
121
    return srcSliceH;
122
}
123
 
124
static int bfin_yuv420_rgb555(SwsContext *c, const uint8_t **in, int *instrides,
125
                              int srcSliceY, int srcSliceH,
126
                              uint8_t **oplanes, int *outstrides)
127
{
128
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
129
                           outstrides, ff_bfin_yuv2rgb555_line, 1, 555);
130
}
131
 
132
static int bfin_yuv420_bgr555(SwsContext *c, const 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,
137
                           outstrides, ff_bfin_yuv2rgb555_line, 0, 555);
138
}
139
 
140
static int bfin_yuv420_rgb24(SwsContext *c, const uint8_t **in, int *instrides,
141
                             int srcSliceY, int srcSliceH,
142
                             uint8_t **oplanes, int *outstrides)
143
{
144
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
145
                           outstrides, ff_bfin_yuv2rgb24_line, 1, 888);
146
}
147
 
148
static int bfin_yuv420_bgr24(SwsContext *c, const uint8_t **in, int *instrides,
149
                             int srcSliceY, int srcSliceH,
150
                             uint8_t **oplanes, int *outstrides)
151
{
152
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
153
                           outstrides, ff_bfin_yuv2rgb24_line, 0, 888);
154
}
155
 
156
static int bfin_yuv420_rgb565(SwsContext *c, const uint8_t **in, int *instrides,
157
                              int srcSliceY, int srcSliceH,
158
                              uint8_t **oplanes, int *outstrides)
159
{
160
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
161
                           outstrides, ff_bfin_yuv2rgb565_line, 1, 565);
162
}
163
 
164
static int bfin_yuv420_bgr565(SwsContext *c, const uint8_t **in, int *instrides,
165
                              int srcSliceY, int srcSliceH,
166
                              uint8_t **oplanes, int *outstrides)
167
{
168
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
169
                           outstrides, ff_bfin_yuv2rgb565_line, 0, 565);
170
}
171
 
172
av_cold SwsFunc ff_yuv2rgb_init_bfin(SwsContext *c)
173
{
174
    SwsFunc f;
175
 
176
    switch (c->dstFormat) {
177
    case AV_PIX_FMT_RGB555:
178
        f = bfin_yuv420_rgb555;
179
        break;
180
    case AV_PIX_FMT_BGR555:
181
        f = bfin_yuv420_bgr555;
182
        break;
183
    case AV_PIX_FMT_RGB565:
184
        f = bfin_yuv420_rgb565;
185
        break;
186
    case AV_PIX_FMT_BGR565:
187
        f = bfin_yuv420_bgr565;
188
        break;
189
    case AV_PIX_FMT_RGB24:
190
        f = bfin_yuv420_rgb24;
191
        break;
192
    case AV_PIX_FMT_BGR24:
193
        f = bfin_yuv420_bgr24;
194
        break;
195
    default:
196
        return 0;
197
    }
198
 
199
    av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n",
200
           av_get_pix_fmt_name(c->dstFormat));
201
 
202
    return f;
203
}