Statistics
| Branch: | Revision:

ffmpeg / libswscale / yuv2rgb_bfin.c @ 8a322796

History | View | Annotate | Download (6.49 KB)

1
/*
2
 * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
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 <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <inttypes.h>
28
#include <assert.h>
29
#include "config.h"
30
#ifdef HAVE_MALLOC_H
31
#include <malloc.h>
32
#endif
33
#include <unistd.h>
34
#include "rgb2rgb.h"
35
#include "swscale.h"
36
#include "swscale_internal.h"
37

    
38
#ifdef __FDPIC__
39
#define L1CODE __attribute__ ((l1_text))
40
#else
41
#define L1CODE
42
#endif
43

    
44
extern void ff_bfin_yuv2rgb555_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
45
                                     int w, uint32_t *coeffs) L1CODE;
46

    
47
extern void ff_bfin_yuv2rgb565_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
48
                                     int w, uint32_t *coeffs) L1CODE;
49

    
50
extern void ff_bfin_yuv2rgb24_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
51
                                    int w, uint32_t *coeffs) L1CODE;
52

    
53
typedef void (* ltransform_t)(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
54
                              int w, uint32_t *coeffs);
55

    
56

    
57
static void bfin_prepare_coefficients (SwsContext *c, int rgb, int masks)
58
{
59
    int oy;
60
    oy      = c->yOffset&0xffff;
61
    oy      = oy >> 3; // keep everything U8.0 for offset calculation
62

    
63
    c->oc   = 128*0x01010101U;
64
    c->oy   =  oy*0x01010101U;
65

    
66
    /* copy 64bit vector coeffs down to 32bit vector coeffs */
67
    c->cy  = c->yCoeff;
68
    c->zero = 0;
69

    
70
    if (rgb) {
71
        c->crv = c->vrCoeff;
72
        c->cbu = c->ubCoeff;
73
        c->cgu = c->ugCoeff;
74
        c->cgv = c->vgCoeff;
75
    } else {
76
        c->crv = c->ubCoeff;
77
        c->cbu = c->vrCoeff;
78
        c->cgu = c->vgCoeff;
79
        c->cgv = c->ugCoeff;
80
    }
81

    
82

    
83
    if (masks == 555) {
84
        c->rmask = 0x001f * 0x00010001U;
85
        c->gmask = 0x03e0 * 0x00010001U;
86
        c->bmask = 0x7c00 * 0x00010001U;
87
    } else if (masks == 565) {
88
        c->rmask = 0x001f * 0x00010001U;
89
        c->gmask = 0x07e0 * 0x00010001U;
90
        c->bmask = 0xf800 * 0x00010001U;
91
    }
92
}
93

    
94
static int core_yuv420_rgb (SwsContext *c,
95
                            uint8_t **in, int *instrides,
96
                            int srcSliceY, int srcSliceH,
97
                            uint8_t **oplanes, int *outstrides,
98
                            ltransform_t lcscf, int rgb, int masks)
99
{
100
    uint8_t *py,*pu,*pv,*op;
101
    int w  = instrides[0];
102
    int h2 = srcSliceH>>1;
103
    int i;
104

    
105
    bfin_prepare_coefficients (c, rgb, masks);
106

    
107
    py = in[0];
108
    pu = in[1+(1^rgb)];
109
    pv = in[1+(0^rgb)];
110

    
111
    op = oplanes[0] + srcSliceY*outstrides[0];
112

    
113
    for (i=0;i<h2;i++) {
114

    
115
        lcscf (py, pu, pv, op, w, &c->oy);
116

    
117
        py += instrides[0];
118
        op += outstrides[0];
119

    
120
        lcscf (py, pu, pv, op, w, &c->oy);
121

    
122
        py += instrides[0];
123
        pu += instrides[1];
124
        pv += instrides[2];
125
        op += outstrides[0];
126
    }
127

    
128
    return srcSliceH;
129
}
130

    
131

    
132
static int bfin_yuv420_rgb555 (SwsContext *c,
133
                               uint8_t **in, int *instrides,
134
                               int srcSliceY, int srcSliceH,
135
                               uint8_t **oplanes, int *outstrides)
136
{
137
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
138
                            ff_bfin_yuv2rgb555_line, 1, 555);
139
}
140

    
141
static int bfin_yuv420_bgr555 (SwsContext *c,
142
                               uint8_t **in, int *instrides,
143
                               int srcSliceY, int srcSliceH,
144
                               uint8_t **oplanes, int *outstrides)
145
{
146
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
147
                            ff_bfin_yuv2rgb555_line, 0, 555);
148
}
149

    
150
static int bfin_yuv420_rgb24 (SwsContext *c,
151
                              uint8_t **in, int *instrides,
152
                              int srcSliceY, int srcSliceH,
153
                              uint8_t **oplanes, int *outstrides)
154
{
155
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
156
                            ff_bfin_yuv2rgb24_line, 1, 888);
157
}
158

    
159
static int bfin_yuv420_bgr24 (SwsContext *c,
160
                              uint8_t **in, int *instrides,
161
                              int srcSliceY, int srcSliceH,
162
                              uint8_t **oplanes, int *outstrides)
163
{
164
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
165
                            ff_bfin_yuv2rgb24_line, 0, 888);
166
}
167

    
168
static int bfin_yuv420_rgb565 (SwsContext *c,
169
                               uint8_t **in, int *instrides,
170
                               int srcSliceY, int srcSliceH,
171
                               uint8_t **oplanes, int *outstrides)
172
{
173
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
174
                            ff_bfin_yuv2rgb565_line, 1, 565);
175
}
176

    
177
static int bfin_yuv420_bgr565 (SwsContext *c,
178
                               uint8_t **in, int *instrides,
179
                               int srcSliceY, int srcSliceH,
180
                               uint8_t **oplanes, int *outstrides)
181
{
182
    return core_yuv420_rgb (c, in, instrides, srcSliceY, srcSliceH, oplanes, outstrides,
183
                            ff_bfin_yuv2rgb565_line, 0, 565);
184
}
185

    
186

    
187
SwsFunc ff_bfin_yuv2rgb_get_func_ptr (SwsContext *c)
188
{
189
    SwsFunc f;
190

    
191
    switch(c->dstFormat) {
192
    case PIX_FMT_RGB555: f = bfin_yuv420_rgb555; break;
193
    case PIX_FMT_BGR555: f = bfin_yuv420_bgr555; break;
194
    case PIX_FMT_RGB565: f = bfin_yuv420_rgb565; break;
195
    case PIX_FMT_BGR565: f = bfin_yuv420_bgr565; break;
196
    case PIX_FMT_RGB24:  f = bfin_yuv420_rgb24;  break;
197
    case PIX_FMT_BGR24:  f = bfin_yuv420_bgr24;  break;
198
    default:
199
        return 0;
200
    }
201

    
202
    av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n",
203
           sws_format_name (c->dstFormat));
204

    
205
    return f;
206
}