Statistics
| Branch: | Revision:

ffmpeg / libswscale / yuv2rgb_bfin.c @ b41c9046

History | View | Annotate | Download (6.44 KB)

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 "rgb2rgb.h"
36
#include "swscale.h"
37
#include "swscale_internal.h"
38

    
39

    
40
#define L1CODE __attribute__ ((l1_text))
41

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

    
45
extern void ff_bfin_yuv2rgb565_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_yuv2rgb24_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
49
                                    int w, uint32_t *coeffs) L1CODE;
50

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

    
54

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

    
61
    c->oc   = 128*0x01010101U;
62
    c->oy   =  oy*0x01010101U;
63

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

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

    
80

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

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

    
103
    bfin_prepare_coefficients (c, rgb, masks);
104

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

    
109
    op = oplanes[0] + srcSliceY*outstrides[0];
110

    
111
    for (i=0;i<h2;i++) {
112

    
113
        lcscf (py,pu,pv,op,w,&c->oy);
114

    
115
        py += instrides[0];
116
        op += outstrides[0];
117

    
118
        lcscf (py,pu,pv,op,w,&c->oy);
119

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

    
126
    return srcSliceH;
127
}
128

    
129

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

    
139
static int bfin_yuv420_bgr555 (SwsContext *c,
140
                               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,outstrides,
145
                            ff_bfin_yuv2rgb555_line, 0, 555);
146
}
147

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

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

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

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

    
184

    
185
SwsFunc ff_bfin_yuv2rgb_get_func_ptr (SwsContext *c)
186
{
187
    SwsFunc f;
188

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

    
200
    av_log(c, AV_LOG_INFO, "BlackFin Accelerated Color Space Converter %s\n",
201
           sws_format_name (c->dstFormat));
202

    
203
    return f;
204
}