~ubuntu-branches/ubuntu/trusty/v4l-utils/trusty

« back to all changes in this revision

Viewing changes to utils/qv4l2/raw2sliced.cpp

  • Committer: Package Import Robot
  • Author(s): Gregor Jasny
  • Date: 2012-10-09 18:38:05 UTC
  • mfrom: (11.1.15 sid)
  • Revision ID: package-import@ubuntu.com-20121009183805-v1m5kb2a1i97rw9y
* Imported Upstream version 0.8.9
  - libv4lconvert: Various Pixart JPEG fixes
  - libv4lconvert: Add more notebooks to the upside down device table
  - keytable: Add support for Sanyo IR and RC-5-SZ protocol
  - keytable: Add missing buttons in shipped keytables (LP: #1054122)
  - v4l2-compliance, v4l-ctl, qv4l2: Sync with development branch
* Drop 32bit cross compiled libraries

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
#include <stdio.h>
 
3
#include <stdbool.h>
 
4
#include <stdint.h>
 
5
#include <string.h>
 
6
#include <assert.h>
 
7
#include <unistd.h>
 
8
#include <sys/fcntl.h>
 
9
 
 
10
#include "raw2sliced.h"
 
11
 
 
12
/*
 
13
 * The slicing code was copied from libzvbi. The original copyright notice is:
 
14
 *
 
15
 * Copyright (C) 2000-2004 Michael H. Schimek
 
16
 *
 
17
 * The vbi_prepare/vbi_parse functions are:
 
18
 *
 
19
 * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com>
 
20
 *
 
21
 * This library is free software; you can redistribute it and/or
 
22
 * modify it under the terms of the GNU Library General Public
 
23
 * License as published by the Free Software Foundation; either
 
24
 * version 2 of the License, or (at your option) any later version.
 
25
 *
 
26
 * This library is distributed in the hope that it will be useful,
 
27
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
28
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
29
 * Library General Public License for more details.
 
30
 *
 
31
 * You should have received a copy of the GNU Library General Public
 
32
 * License along with this library; if not, write to the 
 
33
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
 
34
 * Boston, MA  02110-1301  USA.
 
35
 */
 
36
 
 
37
// Modulation used for VBI data transmission.
 
38
enum vbi_modulation {
 
39
        /*
 
40
         * The data is 'non-return to zero' coded, logical '1' bits
 
41
         * are described by high sample values, logical '0' bits by
 
42
         * low values. The data is last significant bit first transmitted.
 
43
         */
 
44
        VBI_MODULATION_NRZ_LSB,
 
45
        /*
 
46
         * The data is 'bi-phase' coded. Each data bit is described
 
47
         * by two complementary signalling elements, a logical '1'
 
48
         * by a sequence of '10' elements, a logical '0' by a '01'
 
49
         * sequence. The data is last significant bit first transmitted.
 
50
         */
 
51
        VBI_MODULATION_BIPHASE_LSB,
 
52
        /*
 
53
         * 'Bi-phase' coded, most significant bit first transmitted.
 
54
         */
 
55
        VBI_MODULATION_BIPHASE_MSB
 
56
};
 
57
 
 
58
// Service definition struct
 
59
struct service {
 
60
        __u16 service;
 
61
        v4l2_std_id std;
 
62
        /*
 
63
         * Most scan lines used by the data service, first and last
 
64
         * line of first and second field. ITU-R numbering scheme.
 
65
         * Zero if no data from this field, requires field sync.
 
66
         */
 
67
        int             first[2];
 
68
        int             last[2];
 
69
 
 
70
        /*
 
71
         * Leading edge hsync to leading edge first CRI one bit,
 
72
         * half amplitude points, in nanoseconds.
 
73
         */
 
74
        unsigned int            offset;
 
75
 
 
76
        unsigned int            cri_rate;       /* Hz */
 
77
        unsigned int            bit_rate;       /* Hz */
 
78
 
 
79
        /* Clock Run In and FRaming Code, LSB last txed bit of FRC. */
 
80
        unsigned int            cri_frc;
 
81
 
 
82
        /* CRI and FRC bits significant for identification. */
 
83
        unsigned int            cri_frc_mask;
 
84
 
 
85
        /*
 
86
         * Number of significat cri_bits (at cri_rate),
 
87
         * frc_bits (at bit_rate).
 
88
         */
 
89
        unsigned int            cri_bits;
 
90
        unsigned int            frc_bits;
 
91
 
 
92
        unsigned int            payload;        /* bits */
 
93
        enum vbi_modulation     modulation;
 
94
};
 
95
 
 
96
// Supported services
 
97
static const struct service services[] = {
 
98
        {
 
99
                V4L2_SLICED_TELETEXT_B,
 
100
                V4L2_STD_625_50,
 
101
                { 6, 318 },
 
102
                { 22, 335 },
 
103
                10300, 6937500, 6937500, /* 444 x FH */
 
104
                0x00AAAAE4, 0xFFFF, 18, 6, 42 * 8,
 
105
                VBI_MODULATION_NRZ_LSB,
 
106
        }, {
 
107
                V4L2_SLICED_VPS,
 
108
                V4L2_STD_PAL_BG,
 
109
                { 16, 0 },
 
110
                { 16, 0 },
 
111
                12500, 5000000, 2500000, /* 160 x FH */
 
112
                0xAAAA8A99, 0xFFFFFF, 32, 0, 13 * 8,
 
113
                VBI_MODULATION_BIPHASE_MSB,
 
114
        }, {
 
115
                V4L2_SLICED_WSS_625,
 
116
                V4L2_STD_625_50,
 
117
                { 23, 0 },
 
118
                { 23, 0 },
 
119
                11000, 5000000, 833333, /* 160/3 x FH */
 
120
                /* ...1000 111 / 0 0011 1100 0111 1000 0011 111x */
 
121
                /* ...0010 010 / 0 1001 1001 0011 0011 1001 110x */     
 
122
                0x8E3C783E, 0x2499339C, 32, 0, 14 * 1,
 
123
                VBI_MODULATION_BIPHASE_LSB,
 
124
        }, {
 
125
                V4L2_SLICED_CAPTION_525,
 
126
                V4L2_STD_525_60,
 
127
                { 21, 284 },
 
128
                { 21, 284 },
 
129
                10500, 1006976, 503488, /* 32 x FH */
 
130
                /* Test of CRI bits has been removed to handle the
 
131
                   incorrect signal observed by Rich Kandel (see
 
132
                   _VBI_RAW_SHIFT_CC_CRI). */
 
133
                0x03, 0x0F, 4, 0, 2 * 8,
 
134
                VBI_MODULATION_NRZ_LSB,
 
135
        }
 
136
};
 
137
 
 
138
static const unsigned int DEF_THR_FRAC = 9;
 
139
static const unsigned int LP_AVG = 4;
 
140
 
 
141
static inline unsigned int vbi_sample(const uint8_t *raw, unsigned i)
 
142
{
 
143
        unsigned ii = i >> 8;
 
144
        unsigned int raw0 = raw[ii];
 
145
        unsigned int raw1 = raw[ii + 1];
 
146
 
 
147
        return (int)(raw1 - raw0) * (i & 255) + (raw0 << 8);
 
148
}
 
149
 
 
150
// Slice the raw data
 
151
static bool low_pass_bit_slicer_Y8(struct vbi_bit_slicer *bs, uint8_t *buffer, const uint8_t *raw)
 
152
{
 
153
        unsigned int i, j;
 
154
        unsigned int cl;        /* clock */
 
155
        unsigned int thresh0;   /* old 0/1 threshold */
 
156
        unsigned int tr;        /* current threshold */
 
157
        unsigned int c;         /* current byte */
 
158
        unsigned int t;         /* t = raw[0] * j + raw[1] * (1 - j) */
 
159
        unsigned int raw0;      /* oversampling temporary */
 
160
        unsigned int raw1;
 
161
        unsigned char b1;       /* previous bit */
 
162
        unsigned int oversampling = 4;
 
163
 
 
164
        thresh0 = bs->thresh;
 
165
 
 
166
        c = 0;
 
167
        cl = 0;
 
168
        b1 = 0;
 
169
 
 
170
        for (i = bs->cri_samples; i > 0; --i) {
 
171
                int r;
 
172
                tr = bs->thresh >> bs->thresh_frac;
 
173
                raw0 = raw[0];
 
174
                raw1 = raw[1];
 
175
                raw1 -= raw0;
 
176
                r = raw1;
 
177
                bs->thresh += (int)(raw0 - tr) * (r < 0 ? -r : r);
 
178
                t = raw0 * oversampling;
 
179
 
 
180
                for (j = oversampling; j > 0; --j) {
 
181
                        unsigned int tavg;
 
182
                        unsigned char b; /* current bit */
 
183
 
 
184
                        tavg = (t + (oversampling / 2)) / oversampling;
 
185
                        b = (tavg >= tr);
 
186
 
 
187
                        if ((b ^ b1)) {
 
188
                                cl = bs->oversampling_rate >> 1;
 
189
                        } else {
 
190
                                cl += bs->cri_rate;
 
191
 
 
192
                                if (cl >= bs->oversampling_rate) {
 
193
                                        cl -= bs->oversampling_rate;
 
194
                                        c = c * 2 + b;
 
195
                                        if ((c & bs->cri_mask) == bs->cri)
 
196
                                                break;
 
197
                                }
 
198
                        }
 
199
 
 
200
                        b1 = b;
 
201
 
 
202
                        if (oversampling > 1)
 
203
                                t += raw1;
 
204
                }
 
205
                if (j)
 
206
                        break;
 
207
 
 
208
                raw++;
 
209
        }
 
210
        if (i == 0) {
 
211
                bs->thresh = thresh0;
 
212
                return false;
 
213
        }
 
214
 
 
215
        i = bs->phase_shift; /* current bit position << 8 */
 
216
        tr *= 256;
 
217
        c = 0;
 
218
 
 
219
        for (j = bs->frc_bits; j > 0; --j) {
 
220
                raw0 = vbi_sample(raw, i);
 
221
                c = c * 2 + (raw0 >= tr);
 
222
                i += bs->step; /* next bit */
 
223
        }
 
224
 
 
225
        if (c != bs->frc) {
 
226
                bs->thresh = thresh0;
 
227
                return false;
 
228
        }
 
229
 
 
230
        c = 0;
 
231
 
 
232
        if (bs->endian) {
 
233
                /* bitwise, lsb first */
 
234
                for (j = 0; j < bs->payload; ++j) {
 
235
                        raw0 = vbi_sample(raw, i);
 
236
                        c = (c >> 1) + ((raw0 >= tr) << 7);
 
237
                        i += bs->step;
 
238
                        if ((j & 7) == 7)
 
239
                                *buffer++ = c;
 
240
                }
 
241
                *buffer = c >> ((8 - bs->payload) & 7);
 
242
        } else {
 
243
                /* bitwise, msb first */
 
244
                for (j = 0; j < bs->payload; ++j) {
 
245
                        raw0 = vbi_sample(raw, i);
 
246
                        c = c * 2 + (raw0 >= tr);
 
247
                        i += bs->step;
 
248
                        if ((j & 7) == 7)
 
249
                                *buffer++ = c;
 
250
                }
 
251
                *buffer = c & ((1 << (bs->payload & 7)) - 1);
 
252
        }
 
253
 
 
254
        return true;
 
255
}
 
256
 
 
257
// Prepare the vbi_bit_slicer struct
 
258
static bool vbi_bit_slicer_prepare(struct vbi_bit_slicer *bs,
 
259
                const struct service *s,
 
260
                const struct v4l2_vbi_format *fmt)
 
261
{
 
262
        unsigned int c_mask;
 
263
        unsigned int f_mask;
 
264
        unsigned int min_samples_per_bit;
 
265
        unsigned int oversampling;
 
266
        unsigned int data_bits;
 
267
        unsigned int data_samples;
 
268
        unsigned int cri, cri_mask, frc;
 
269
        unsigned int cri_end;
 
270
 
 
271
        assert (s->cri_bits <= 32);
 
272
        assert (s->frc_bits <= 32);
 
273
        assert (s->payload <= 32767);
 
274
        assert (fmt->samples_per_line <= 32767);
 
275
 
 
276
        cri = s->cri_frc >> s->frc_bits;
 
277
        cri_mask = s->cri_frc_mask >> s->frc_bits;
 
278
        frc = (s->cri_frc & ((1U << s->frc_bits) - 1));
 
279
        if (s->cri_rate > fmt->sampling_rate) {
 
280
                fprintf(stderr, "cri_rate %u > sampling_rate %u.\n",
 
281
                         s->cri_rate, fmt->sampling_rate);
 
282
                return false;
 
283
        }
 
284
 
 
285
        if (s->bit_rate > fmt->sampling_rate) {
 
286
                fprintf(stderr, "bit_rate %u > sampling_rate %u.\n",
 
287
                         s->bit_rate, fmt->sampling_rate);
 
288
                return false;
 
289
        }
 
290
 
 
291
        min_samples_per_bit = fmt->sampling_rate / ((s->cri_rate > s->bit_rate) ? s->cri_rate : s->bit_rate);
 
292
 
 
293
        c_mask = (s->cri_bits == 32) ? ~0U : (1U << s->cri_bits) - 1;
 
294
        f_mask = (s->frc_bits == 32) ? ~0U : (1U << s->frc_bits) - 1;
 
295
 
 
296
        oversampling = 4;
 
297
 
 
298
        /* 0-1 threshold, start value. */
 
299
        bs->thresh = 105 << DEF_THR_FRAC;
 
300
        bs->thresh_frac = DEF_THR_FRAC;
 
301
 
 
302
        if (min_samples_per_bit > (3U << (LP_AVG - 1))) {
 
303
                oversampling = 1;
 
304
                bs->thresh <<= LP_AVG - 2;
 
305
                bs->thresh_frac += LP_AVG - 2;
 
306
        }
 
307
 
 
308
        bs->cri_mask = cri_mask & c_mask;
 
309
        bs->cri = cri & bs->cri_mask;
 
310
 
 
311
        data_bits = s->payload + s->frc_bits;
 
312
        data_samples = (fmt->sampling_rate * (int64_t) data_bits) / s->bit_rate;
 
313
 
 
314
        cri_end = fmt->samples_per_line - data_samples;
 
315
 
 
316
        bs->cri_samples = cri_end;
 
317
        bs->cri_rate = s->cri_rate;
 
318
 
 
319
        bs->oversampling_rate = fmt->sampling_rate * oversampling;
 
320
 
 
321
        bs->frc = frc & f_mask;
 
322
        bs->frc_bits = s->frc_bits;
 
323
 
 
324
        /* Payload bit distance in 1/256 raw samples. */
 
325
        bs->step = (fmt->sampling_rate * (int64_t) 256) / s->bit_rate;
 
326
 
 
327
        bs->payload = s->payload;
 
328
        bs->endian = 1;
 
329
 
 
330
        switch (s->modulation) {
 
331
        case VBI_MODULATION_NRZ_LSB:
 
332
                bs->phase_shift = (int)
 
333
                        (fmt->sampling_rate * 256.0 / s->cri_rate * .5
 
334
                         + bs->step * .5 + 128);
 
335
                break;
 
336
 
 
337
        case VBI_MODULATION_BIPHASE_MSB:
 
338
                bs->endian = 0;
 
339
                /* fall through */
 
340
        case VBI_MODULATION_BIPHASE_LSB:
 
341
                /* Phase shift between the NRZ modulated CRI and the
 
342
                   biphase modulated rest. */
 
343
                bs->phase_shift = (int)
 
344
                        (fmt->sampling_rate * 256.0 / s->cri_rate * .5
 
345
                         + bs->step * .25 + 128);
 
346
                break;
 
347
        }
 
348
        return true;
 
349
}
 
350
 
 
351
bool vbi_prepare(struct vbi_handle *vh, const struct v4l2_vbi_format *fmt, v4l2_std_id std)
 
352
{
 
353
        unsigned i;
 
354
 
 
355
        memset(vh, 0, sizeof(*vh));
 
356
        // Sanity check
 
357
        if ((std & V4L2_STD_525_60) && (std & V4L2_STD_625_50))
 
358
                return false;
 
359
        vh->start_of_field_2 = (std & V4L2_STD_525_60) ? 263 : 313;
 
360
        vh->stride = fmt->samples_per_line;
 
361
        vh->interlaced = fmt->flags & V4L2_VBI_INTERLACED;
 
362
        vh->start[0] = fmt->start[0];
 
363
        vh->start[1] = fmt->start[1];
 
364
        vh->count[0] = fmt->count[0];
 
365
        vh->count[1] = fmt->count[1];
 
366
        for (i = 0; i < sizeof(services) / sizeof(services[0]); i++) {
 
367
                const struct service *s = services + i;
 
368
                struct vbi_bit_slicer *slicer = vh->slicers + vh->services;
 
369
 
 
370
                if (!(std & s->std))
 
371
                        continue;
 
372
                if (s->last[0] < vh->start[0] &&
 
373
                    s->last[1] < vh->start[1])
 
374
                        continue;
 
375
                if (s->first[0] >= vh->start[0] + vh->count[0] &&
 
376
                    s->first[1] >= vh->start[1] + vh->count[1])
 
377
                        continue;
 
378
                slicer->service = i;
 
379
                vbi_bit_slicer_prepare(slicer, s, fmt);
 
380
                vh->services++;
 
381
        }
 
382
        return vh->services;
 
383
}
 
384
 
 
385
void vbi_parse(struct vbi_handle *vh, const unsigned char *buf,
 
386
                struct v4l2_sliced_vbi_format *vbi,
 
387
                struct v4l2_sliced_vbi_data *data)
 
388
{
 
389
        const unsigned char *p;
 
390
        unsigned i;
 
391
        int y;
 
392
 
 
393
        memset(vbi, 0, sizeof(*vbi));
 
394
        vbi->io_size = sizeof(*data) * (vh->count[0] + vh->count[1]);
 
395
        for (i = 0; i < vh->services; i++) {
 
396
                const struct service *s = services + vh->slicers[i].service;
 
397
 
 
398
                for (y = s->first[0] - vh->start[0]; y <= s->last[0] - vh->start[0]; y++) {
 
399
                        if (y < 0 || y >= vh->count[0])
 
400
                                continue;
 
401
                        if (vh->interlaced)
 
402
                                p = buf + vh->stride * y * 2;
 
403
                        else
 
404
                                p = buf + vh->stride * y;
 
405
                        data[y].id = data[y].reserved = 0;
 
406
                        if (low_pass_bit_slicer_Y8(vh->slicers + i, data[y].data, p)) {
 
407
                                vbi->service_set |= s->service;
 
408
                                vbi->service_lines[0][y + vh->start[0]] = s->service;
 
409
                                data[y].id = s->service;
 
410
                                data[y].field = 0;
 
411
                                data[y].line = y + vh->start[0];
 
412
                        }
 
413
                }
 
414
 
 
415
                for (y = s->first[1] - vh->start[1]; y <= s->last[1] - vh->start[1]; y++) {
 
416
                        unsigned yy = y + vh->count[0];
 
417
 
 
418
                        if (y < 0 || y >= vh->count[1])
 
419
                                continue;
 
420
                        if (vh->interlaced)
 
421
                                p = buf + vh->stride * y * 2 + 1;
 
422
                        else
 
423
                                p = buf + vh->stride * yy;
 
424
                        data[yy].id = data[yy].reserved = 0;
 
425
                        if (low_pass_bit_slicer_Y8(vh->slicers + i, data[yy].data, p)) {
 
426
                                vbi->service_set |= s->service;
 
427
                                vbi->service_lines[1][y + vh->start[1] - vh->start_of_field_2] = s->service;
 
428
                                data[yy].id = s->service;
 
429
                                data[yy].field = 1;
 
430
                                data[yy].line = y + vh->start[1] - vh->start_of_field_2;
 
431
                        }
 
432
                }
 
433
        }
 
434
}