1 /*
2 * libzvbi - Bit slicer
3 *
4 * Copyright (C) 2000-2007 Michael H. Schimek
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA.
20 */
21
22 /* $Id: bit_slicer.c,v 1.16 2008-02-19 00:35:14 mschimek Exp $ */
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include "misc.h"
29 #include "bit_slicer.h"
30
31 # define VBI_PIXFMT_Y8 VBI_PIXFMT_YUV420
32 # define VBI_PIXFMT_RGB24_LE VBI_PIXFMT_RGB24
33 # define VBI_PIXFMT_BGR24_LE VBI_PIXFMT_BGR24
34 # define VBI_PIXFMT_RGBA24_LE VBI_PIXFMT_RGBA32_LE
35 # define VBI_PIXFMT_BGRA24_LE VBI_PIXFMT_BGRA32_LE
36 # define VBI_PIXFMT_RGBA24_BE VBI_PIXFMT_RGBA32_BE
37 # define VBI_PIXFMT_BGRA24_BE VBI_PIXFMT_BGRA32_BE
38 # define vbi_pixfmt_bytes_per_pixel VBI_PIXFMT_BPP
39
40 /**
41 * $addtogroup BitSlicer Bit Slicer
42 * $ingroup Raw
43 * $brief Converting a single scan line of raw VBI
44 * data to sliced VBI data.
45 *
46 * These are low level functions most useful if you want to decode
47 * data services not covered by libzvbi. Usually you will want to
48 * use the raw VBI decoder, converting several lines of different
49 * data services at once.
50 */
51
52 /* This is time critical, tinker with care.
53
54 What about all these macros? They are templates to avoid a
55 pixel format switch within time critical loops. Instead we
56 compile bit slicer functions for different pixel formats.
57
58 I would use inline functions for proper type checking, but
59 there's no guarantee the compiler really will inline. */
60
61 /* Read a green sample, e.g. rrrrrggg gggbbbbb. endian is const. */
62 #define GREEN2(raw, endian) \
63 (((raw)[0 + endian] + (raw)[1 - endian] * 256) & bs->green_mask)
64
65 /* Read a sample with pixfmt conversion. pixfmt is const. */
66 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
67 #define GREEN(raw) \
68 ((VBI_PIXFMT_RGB16_LE == pixfmt) ? \
69 *(const uint16_t *)(raw) & bs->green_mask : \
70 ((VBI_PIXFMT_RGB16_BE == pixfmt) ? \
71 GREEN2 (raw, 1) : \
72 (raw)[0]))
73 #elif G_BYTE_ORDER == G_BIG_ENDIAN
74 #define GREEN(raw) \
75 ((VBI_PIXFMT_RGB16_LE == pixfmt) ? \
76 GREEN2 (raw, 0) : \
77 ((VBI_PIXFMT_RGB16_BE == pixfmt) ? \
78 *(const uint16_t *)(raw) & bs->green_mask : \
79 (raw)[0]))
80 #else
81 #define GREEN(raw) \
82 ((VBI_PIXFMT_RGB16_LE == pixfmt) ? \
83 GREEN2 (raw, 0) : \
84 ((VBI_PIXFMT_RGB16_BE == pixfmt) ? \
85 GREEN2 (raw, 1) : \
86 (raw)[0]))
87 #endif
88
89 /* raw0 = raw[index >> 8], linear interpolated. */
90 #define SAMPLE(_kind) \
91 do { \
92 const uint8_t *r; \
93 \
94 r = raw + (i >> 8) * bpp; \
95 raw0 = GREEN (r); \
96 raw1 = GREEN (r + bpp); \
97 raw0 = (int)(raw1 - raw0) * (i & 255) + (raw0 << 8); \
98 if (collect_points) { \
99 points->kind = _kind; \
100 points->index = (raw - raw_start) * 256 + i; \
101 points->level = raw0; \
102 points->thresh = tr; \
103 ++points; \
104 } \
105 } while (0)
106
107 #define PAYLOAD() \
108 do { \
109 i = bs->phase_shift; /* current bit position << 8 */ \
110 tr *= 256; \
111 c = 0; \
112 \
113 for (j = bs->frc_bits; j > 0; --j) { \
114 SAMPLE (VBI3_FRC_BIT); \
115 c = c * 2 + (raw0 >= tr); \
116 i += bs->step; /* next bit */ \
117 } \
118 \
119 if (c != bs->frc) \
120 return FALSE; \
121 \
122 switch (bs->endian) { \
123 case 3: /* bitwise, lsb first */ \
124 for (j = 0; j < bs->payload; ++j) { \
125 SAMPLE (VBI3_PAYLOAD_BIT); \
126 c = (c >> 1) + ((raw0 >= tr) << 7); \
127 i += bs->step; \
128 if ((j & 7) == 7) \
129 *buffer++ = c; \
130 } \
131 *buffer = c >> ((8 - bs->payload) & 7); \
132 break; \
133 \
134 case 2: /* bitwise, msb first */ \
135 for (j = 0; j < bs->payload; ++j) { \
136 SAMPLE (VBI3_PAYLOAD_BIT); \
137 c = c * 2 + (raw0 >= tr); \
138 i += bs->step; \
139 if ((j & 7) == 7) \
140 *buffer++ = c; \
141 } \
142 *buffer = c & ((1 << (bs->payload & 7)) - 1); \
143 break; \
144 \
145 case 1: /* octets, lsb first */ \
146 for (j = bs->payload; j > 0; --j) { \
147 for (k = 0, c = 0; k < 8; ++k) { \
148 SAMPLE (VBI3_PAYLOAD_BIT); \
149 c += (raw0 >= tr) << k; \
150 i += bs->step; \
151 } \
152 *buffer++ = c; \
153 } \
154 break; \
155 \
156 default: /* octets, msb first */ \
157 for (j = bs->payload; j > 0; --j) { \
158 for (k = 0; k < 8; ++k) { \
159 SAMPLE (VBI3_PAYLOAD_BIT); \
160 c = c * 2 + (raw0 >= tr); \
161 i += bs->step; \
162 } \
163 *buffer++ = c; \
164 } \
165 break; \
166 } \
167 } while (0)
168
169 #define CRI() \
170 do { \
171 unsigned int tavg; \
172 unsigned char b; /* current bit */ \
173 \
174 tavg = (t + (oversampling / 2)) / oversampling; \
175 b = (tavg >= tr); \
176 \
177 if (unlikely (b ^ b1)) { \
178 cl = bs->oversampling_rate >> 1; \
179 } else { \
180 cl += bs->cri_rate; \
181 \
182 if (cl >= bs->oversampling_rate) { \
183 if (collect_points) { \
184 points->kind = VBI3_CRI_BIT; \
185 points->index = (raw - raw_start) << 8; \
186 points->level = tavg << 8; \
187 points->thresh = tr << 8; \
188 ++points; \
189 } \
190 \
191 cl -= bs->oversampling_rate; \
192 c = c * 2 + b; \
193 if ((c & bs->cri_mask) == bs->cri) { \
194 PAYLOAD (); \
195 if (collect_points) { \
196 *n_points = points \
197 - points_start; \
198 } \
199 return TRUE; \
200 } \
201 } \
202 } \
203 \
204 b1 = b; \
205 \
206 if (oversampling > 1) \
207 t += raw1; \
208 } while (0)
209
210 #define CORE() \
211 do { \
212 const uint8_t *raw_start; \
213 unsigned int i, j, k; \
214 unsigned int cl; /* clock */ \
215 unsigned int thresh0; /* old 0/1 threshold */ \
216 unsigned int tr; /* current threshold */ \
217 unsigned int c; /* current byte */ \
218 unsigned int t; /* t = raw[0] * j + raw[1] * (1 - j) */ \
219 unsigned int raw0; /* oversampling temporary */ \
220 unsigned int raw1; \
221 unsigned char b1; /* previous bit */ \
222 \
223 thresh0 = bs->thresh; \
224 raw_start = raw; \
225 raw += bs->skip; \
226 \
227 cl = 0; \
228 c = 0; \
229 b1 = 0; \
230 \
231 for (i = bs->cri_samples; i > 0; --i) { \
232 tr = bs->thresh >> thresh_frac; \
233 raw0 = GREEN (raw); \
234 raw1 = GREEN (raw + bpp); \
235 raw1 -= raw0; \
236 bs->thresh += (int)(raw0 - tr) * (int) ABS ((int) raw1); \
237 t = raw0 * oversampling; \
238 \
239 for (j = oversampling; j > 0; --j) \
240 CRI (); \
241 \
242 raw += bpp; \
243 } \
244 \
245 bs->thresh = thresh0; \
246 \
247 if (collect_points) \
248 *n_points = points - points_start; \
249 \
250 return FALSE; \
251 } while (0)
252
253 #define BIT_SLICER(fmt, os, tf) \
254 static vbi_bool \
255 bit_slicer_ ## fmt (vbi3_bit_slicer * bs, \
256 uint8_t * buffer, \
257 vbi3_bit_slicer_point *points, \
258 unsigned int * n_points, \
259 const uint8_t * raw) \
260 { \
261 static const vbi_pixfmt pixfmt = VBI_PIXFMT_ ## fmt; \
262 unsigned int bpp = \
263 vbi_pixfmt_bytes_per_pixel (VBI_PIXFMT_ ## fmt); \
264 static const unsigned int oversampling = os; \
265 static const vbi3_bit_slicer_point *points_start = NULL; \
266 static const vbi_bool collect_points = FALSE; \
267 unsigned int thresh_frac = tf; \
268 \
269 CORE (); \
270 }
271
272 #define DEF_THR_FRAC 9
273
274 BIT_SLICER (Y8, 4, DEF_THR_FRAC) /* any format with 0 bytes between Y or G */
275 BIT_SLICER (YUYV, 4, DEF_THR_FRAC) /* 1 byte */
276 BIT_SLICER (RGB24_LE, 4, DEF_THR_FRAC) /* 2 bytes */
277 BIT_SLICER (RGBA24_LE, 4, DEF_THR_FRAC) /* 3 bytes */
278 BIT_SLICER (RGB16_LE, 4, bs->thresh_frac)
279 BIT_SLICER (RGB16_BE, 4, bs->thresh_frac)
280
281 static const unsigned int LP_AVG = 4;
282
283 static vbi_bool
low_pass_bit_slicer_Y8(vbi3_bit_slicer * bs,uint8_t * buffer,vbi3_bit_slicer_point * points,unsigned int * n_points,const uint8_t * raw)284 low_pass_bit_slicer_Y8 (vbi3_bit_slicer * bs,
285 uint8_t * buffer,
286 vbi3_bit_slicer_point * points, unsigned int *n_points, const uint8_t * raw)
287 {
288 vbi3_bit_slicer_point *points_start;
289 const uint8_t *raw_start;
290 unsigned int i, j, k, m;
291 unsigned int cl; /* clock */
292 unsigned int thresh0; /* old 0/1 threshold */
293 unsigned int tr; /* current threshold */
294 unsigned int c; /* current byte */
295 unsigned int raw0; /* oversampling temporary */
296 unsigned char b1; /* previous bit */
297 unsigned int bps;
298 unsigned int raw0sum;
299
300 points_start = points;
301
302 raw_start = raw;
303 raw += bs->skip;
304
305 bps = bs->bytes_per_sample;
306
307 thresh0 = bs->thresh;
308
309 c = -1;
310 cl = 0;
311 b1 = 0;
312
313 raw0sum = raw[0];
314 for (m = bps; m < (bps << LP_AVG); m += bps) {
315 raw0sum += raw[m];
316 }
317
318 i = bs->cri_samples;
319
320 for (;;) {
321 unsigned char b; /* current bit */
322
323 tr = bs->thresh >> bs->thresh_frac;
324 raw0 = raw0sum;
325 raw0sum = raw0sum + raw[bps << LP_AVG]
326 - raw[0];
327 raw += bps;
328 bs->thresh += (int) (raw0 - tr)
329 * (int) ABS ((int) (raw0sum - raw0));
330
331 b = (raw0 >= tr);
332
333 if (unlikely (b ^ b1)) {
334 cl = bs->oversampling_rate >> 1;
335 } else {
336 cl += bs->cri_rate;
337
338 if (cl >= bs->oversampling_rate) {
339 if (unlikely (NULL != points)) {
340 points->kind = VBI3_CRI_BIT;
341 points->index = (raw - raw_start)
342 * 256 / bs->bytes_per_sample + (1 << LP_AVG) * 128;
343 points->level = raw0 << (8 - LP_AVG);
344 points->thresh = tr << (8 - LP_AVG);
345 ++points;
346 }
347
348 cl -= bs->oversampling_rate;
349 c = c * 2 + b;
350 if ((c & bs->cri_mask) == bs->cri) {
351 break;
352 }
353 }
354 }
355
356 b1 = b;
357
358 if (0 == --i) {
359 bs->thresh = thresh0;
360
361 if (unlikely (NULL != points))
362 *n_points = points - points_start;
363
364 return FALSE;
365 }
366 }
367
368 #define LP_SAMPLE(_kind) \
369 do { \
370 unsigned int ii = (i >> 8) * bps; \
371 \
372 raw0 = raw[ii]; \
373 for (m = bps; m < (bps << LP_AVG); m += bps) \
374 raw0 += raw[ii + m]; \
375 if (unlikely (NULL != points)) { \
376 points->kind = _kind; \
377 points->index = (raw - raw_start) \
378 * 256 / bs->bytes_per_sample \
379 + (1 << LP_AVG) * 128 \
380 + ii * 256; \
381 points->level = raw0 << (8 - LP_AVG); \
382 points->thresh = tr << (8 - LP_AVG); \
383 ++points; \
384 } \
385 } while (0)
386
387 i = bs->phase_shift; /* current bit position << 8 */
388 c = 0;
389
390 for (j = bs->frc_bits; j > 0; --j) {
391 LP_SAMPLE (VBI3_FRC_BIT);
392 c = c * 2 + (raw0 >= tr);
393 i += bs->step; /* next bit */
394 }
395
396 if (c != bs->frc)
397 return FALSE;
398
399 c = 0;
400
401 switch (bs->endian) {
402 case 3: /* bitwise, lsb first */
403 for (j = 0; j < bs->payload; ++j) {
404 LP_SAMPLE (VBI3_PAYLOAD_BIT);
405 c = (c >> 1) + ((raw0 >= tr) << 7);
406 i += bs->step;
407 if ((j & 7) == 7)
408 *buffer++ = c;
409 }
410 *buffer = c >> ((8 - bs->payload) & 7);
411 break;
412
413 case 2: /* bitwise, msb first */
414 for (j = 0; j < bs->payload; ++j) {
415 LP_SAMPLE (VBI3_PAYLOAD_BIT);
416 c = c * 2 + (raw0 >= tr);
417 i += bs->step;
418 if ((j & 7) == 7)
419 *buffer++ = c;
420 }
421 *buffer = c & ((1 << (bs->payload & 7)) - 1);
422 break;
423
424 case 1: /* octets, lsb first */
425 j = bs->payload;
426 do {
427 for (k = 0; k < 8; ++k) {
428 LP_SAMPLE (VBI3_PAYLOAD_BIT);
429 c = (c >> 1) + ((raw0 >= tr) << 7);
430 i += bs->step;
431 }
432 *buffer++ = c;
433 } while (--j > 0);
434 break;
435
436 default: /* octets, msb first */
437 j = bs->payload;
438 do {
439 for (k = 0; k < 8; ++k) {
440 LP_SAMPLE (VBI3_PAYLOAD_BIT);
441 c = c * 2 + (raw0 >= tr);
442 i += bs->step;
443 }
444 *buffer++ = c;
445 } while (--j > 0);
446 break;
447 }
448
449 if (unlikely (NULL != points)) {
450 *n_points = points - points_start;
451 }
452
453 return TRUE;
454 }
455
456 static vbi_bool
null_function(vbi3_bit_slicer * bs,uint8_t * buffer,vbi3_bit_slicer_point * points,unsigned int * n_points,const uint8_t * raw)457 null_function (vbi3_bit_slicer * bs,
458 uint8_t * buffer,
459 vbi3_bit_slicer_point * points, unsigned int *n_points, const uint8_t * raw)
460 {
461 /* buffer = buffer; /\* unused *\/ */
462 /* points = points; */
463 /* n_points = n_points; */
464 /* raw = raw; */
465
466 warn (&bs->log, "vbi3_bit_slicer_set_params() not called.");
467
468 return FALSE;
469 }
470
471 /**
472 * @param bs Pointer to vbi3_bit_slicer object allocated with
473 * vbi3_bit_slicer_new().
474 * @param buffer Output data.
475 * @param buffer_size Size of the output buffer. The buffer must be
476 + large enough to store the number of bits given as @a payload_bits to
477 * vbi3_bit_slicer_new().
478 * @param points Information about the bits sampled by the bit slicer
479 * are stored here.
480 * @param n_points The number of sampling points stored in the
481 * @a points array will be stored here.
482 * @param max_points Size of the @a points array. The array must be
483 * large enough to store one sampling point for all @a crc_bits,
484 * @a frc_bits and @a payload_bits given to vbi3_bit_slicer_new().
485 * @param raw Input data. At least the number of pixels or samples
486 * given as @a samples_per_line to vbi3_bit_slicer_new().
487 *
488 * Like vbi3_bit_slicer_slice() but additionally provides information
489 * about where and how bits were sampled. This is mainly interesting
490 * for debugging.
491 *
492 * @returns
493 * @c FALSE if the @a buffer or @a points array is too small, if the
494 * pixel format is not supported or if the raw data does not contain
495 * the expected information, i. e. the CRI/FRC has not been found. In
496 * these cases the @a buffer remains unmodified but the @a points
497 * array may contain data.
498 *
499 * @bug
500 * Currently this function is only implemented for
501 * raw data in planar YUV formats and @c VBI3_PIXFMT_Y8.
502 */
503 vbi_bool
vbi3_bit_slicer_slice_with_points(vbi3_bit_slicer * bs,uint8_t * buffer,unsigned int buffer_size,vbi3_bit_slicer_point * points,unsigned int * n_points,unsigned int max_points,const uint8_t * raw)504 vbi3_bit_slicer_slice_with_points
505 (vbi3_bit_slicer * bs,
506 uint8_t * buffer,
507 unsigned int buffer_size,
508 vbi3_bit_slicer_point * points,
509 unsigned int *n_points, unsigned int max_points, const uint8_t * raw) {
510 static const vbi_pixfmt pixfmt = VBI_PIXFMT_Y8;
511 static const unsigned int bpp = 1;
512 static const unsigned int oversampling = 4; /* see above */
513 static const unsigned int thresh_frac = DEF_THR_FRAC;
514 static const vbi_bool collect_points = TRUE;
515 vbi3_bit_slicer_point *points_start;
516
517 assert (NULL != bs);
518 assert (NULL != buffer);
519 assert (NULL != points);
520 assert (NULL != n_points);
521 assert (NULL != raw);
522
523 points_start = points;
524 *n_points = 0;
525
526 if (bs->payload > buffer_size * 8) {
527 warn (&bs->log,
528 "buffer_size %u < %u bits of payload.", buffer_size * 8, bs->payload);
529 return FALSE;
530 }
531
532 if (bs->total_bits > max_points) {
533 warn (&bs->log,
534 "max_points %u < %u CRI, FRC and payload bits.",
535 max_points, bs->total_bits);
536 return FALSE;
537 }
538
539 if (low_pass_bit_slicer_Y8 == bs->func) {
540 return bs->func (bs, buffer, points, n_points, raw);
541 } else if (bit_slicer_Y8 != bs->func) {
542 warn (&bs->log,
543 "Function not implemented for pixfmt %u.", bs->sample_format);
544 return bs->func (bs, buffer,
545 /* points */ NULL,
546 /* n_points */ NULL,
547 raw);
548 }
549
550 CORE ();
551 }
552
553 /**
554 * @param bs Pointer to vbi3_bit_slicer object allocated with
555 * vbi3_bit_slicer_new(). You must also call
556 * vbi3_bit_slicer_set_params() before calling this function.
557 * @param buffer Output data.
558 * @param buffer_size Size of the output buffer. The buffer must be
559 + large enough to store the number of bits given as @a payload to
560 * vbi3_bit_slicer_new().
561 * @param raw Input data. At least the number of pixels or samples
562 * given as @a samples_per_line to vbi3_bit_slicer_new().
563 *
564 * Decodes one scan line of raw vbi data. Note the bit slicer tries
565 * to adapt to the average signal amplitude, you should avoid
566 * using the same vbi3_bit_slicer object for data from different
567 * devices.
568 *
569 * @return
570 * @c FALSE if the @a buffer is too small or if the raw data does not
571 * contain the expected information, i. e. the CRI/FRC has not been
572 * found. This may also result from a too weak or noisy signal. Error
573 * correction must be implemented at a higher layer. When the function
574 * fails, the @a buffer remains unmodified.
575 */
576 vbi_bool
vbi3_bit_slicer_slice(vbi3_bit_slicer * bs,uint8_t * buffer,unsigned int buffer_size,const uint8_t * raw)577 vbi3_bit_slicer_slice (vbi3_bit_slicer * bs,
578 uint8_t * buffer, unsigned int buffer_size, const uint8_t * raw)
579 {
580 assert (NULL != bs);
581 assert (NULL != buffer);
582 assert (NULL != raw);
583
584 if (bs->payload > buffer_size * 8) {
585 warn (&bs->log,
586 "buffer_size %u < %u bits of payload.", buffer_size * 8, bs->payload);
587 return FALSE;
588 }
589
590 return bs->func (bs, buffer,
591 /* points */ NULL,
592 /* n_points */ NULL,
593 raw);
594 }
595
596 /**
597 * @param bs Pointer to vbi3_bit_slicer object allocated with
598 * vbi3_bit_slicer_new().
599 * @param sample_format Format of the raw data, see vbi3_pixfmt.
600 * Note the bit slicer looks only at the green component of RGB
601 * pixels.
602 * @param sampling_rate Raw vbi sampling rate in Hz, that is the number
603 * of samples or pixels sampled per second by the hardware.
604 * @param sample_offset The bit slicer shall skip this number of samples at
605 * the start of the line.
606 * @param samples_per_line Number of samples or pixels in one raw vbi
607 * line later passed to vbi3_bit_slicer_slice(). This limits the number of
608 * bytes read from the raw data buffer. Do not to confuse the value
609 * with bytes per line.
610 * @param cri The Clock Run In is a NRZ modulated sequence of '1'
611 * and '0' bits prepending most data transmissions to synchronize data
612 * acquisition circuits. The bit slicer compares the bits in this
613 * word, lsb last transmitted, against the transmitted CRI. Decoding
614 * of FRC and payload starts with the next bit after a match, thus
615 * @a cri must contain a unique bit sequence. For example 0xAB to
616 * match '101010101011xxx'.
617 * @param cri_mask Of the CRI bits in @a cri, only these bits are
618 * significant for a match. For instance it is wise not to rely on
619 * the very first CRI bits transmitted.
620 * @param cri_bits Number of CRI bits, must not exceed 32.
621 * @param cri_rate CRI bit rate in Hz, the number of CRI bits
622 * transmitted per second.
623 * @param cri_end Number of samples between the start of the line and
624 * the latest possible end of the CRI. This is useful when
625 * the transmission is much shorter than samples_per_line, otherwise
626 * just pass @c ~0 and a limit will be calculated.
627 * @param frc The FRaming Code usually following the CRI is a bit
628 * sequence identifying the data service. There is no mask parameter,
629 * all bits must match. We assume FRC has the same @a modulation as
630 * the payload and is transmitted at @a payload_rate.
631 * @param frc_bits Number of FRC bits, must not exceed 32.
632 * @param payload_bits Number of payload bits. Only this data
633 * will be stored in the vbi3_bit_slicer_slice() output. If this number
634 * is no multiple of eight, the most significant bits of the
635 * last byte are undefined.
636 * @param payload_rate Payload bit rate in Hz, the number of payload
637 * bits transmitted per second.
638 * @param modulation Modulation of the payload, see vbi3_modulation.
639 *
640 * Initializes a vbi3_bit_slicer object for use with
641 * vbi3_bit_slicer_slice(). This is a low level function, see also
642 * vbi3_raw_decoder_new().
643 *
644 * @returns
645 * @c FALSE when the parameters are invalid (e. g.
646 * @a samples_per_line too small to contain CRI, FRC and payload).
647 */
648 vbi_bool
vbi3_bit_slicer_set_params(vbi3_bit_slicer * bs,vbi_pixfmt sample_format,unsigned int sampling_rate,unsigned int sample_offset,unsigned int samples_per_line,unsigned int cri,unsigned int cri_mask,unsigned int cri_bits,unsigned int cri_rate,unsigned int cri_end,unsigned int frc,unsigned int frc_bits,unsigned int payload_bits,unsigned int payload_rate,vbi3_modulation modulation)649 vbi3_bit_slicer_set_params (vbi3_bit_slicer * bs,
650 vbi_pixfmt sample_format,
651 unsigned int sampling_rate,
652 unsigned int sample_offset,
653 unsigned int samples_per_line,
654 unsigned int cri,
655 unsigned int cri_mask,
656 unsigned int cri_bits,
657 unsigned int cri_rate,
658 unsigned int cri_end,
659 unsigned int frc,
660 unsigned int frc_bits,
661 unsigned int payload_bits,
662 unsigned int payload_rate, vbi3_modulation modulation)
663 {
664 unsigned int c_mask;
665 unsigned int f_mask;
666 unsigned int min_samples_per_bit;
667 unsigned int oversampling;
668 unsigned int data_bits;
669 unsigned int data_samples;
670 unsigned int cri_samples;
671 unsigned int skip;
672
673 assert (NULL != bs);
674 assert (cri_bits <= 32);
675 assert (frc_bits <= 32);
676 assert (payload_bits <= 32767);
677 assert (samples_per_line <= 32767);
678
679 if (cri_rate > sampling_rate) {
680 warn (&bs->log, "cri_rate %u > sampling_rate %u.", cri_rate, sampling_rate);
681 goto failure;
682 }
683
684 if (payload_rate > sampling_rate) {
685 warn (&bs->log,
686 "payload_rate %u > sampling_rate %u.", payload_rate, sampling_rate);
687 goto failure;
688 }
689
690 min_samples_per_bit = sampling_rate / MAX (cri_rate, payload_rate);
691
692 bs->sample_format = sample_format;
693
694 c_mask = (cri_bits == 32) ? ~0U : (1U << cri_bits) - 1;
695 f_mask = (frc_bits == 32) ? ~0U : (1U << frc_bits) - 1;
696
697 oversampling = 4;
698 skip = 0;
699
700 /* 0-1 threshold, start value. */
701 bs->thresh = 105 << DEF_THR_FRAC;
702 bs->thresh_frac = DEF_THR_FRAC;
703
704 switch (sample_format) {
705 case VBI_PIXFMT_YUV420:
706 bs->bytes_per_sample = 1;
707 bs->func = bit_slicer_Y8;
708 if (min_samples_per_bit > (3U << (LP_AVG - 1))) {
709 bs->func = low_pass_bit_slicer_Y8;
710 oversampling = 1;
711 bs->thresh <<= LP_AVG - 2;
712 bs->thresh_frac += LP_AVG - 2;
713 }
714 break;
715
716
717 case VBI_PIXFMT_YUYV:
718 case VBI_PIXFMT_YVYU:
719 bs->bytes_per_sample = 2;
720 bs->func = bit_slicer_YUYV;
721 if (min_samples_per_bit > (3U << (LP_AVG - 1))) {
722 bs->func = low_pass_bit_slicer_Y8;
723 oversampling = 1;
724 bs->thresh <<= LP_AVG - 2;
725 bs->thresh_frac += LP_AVG - 2;
726 }
727 break;
728
729 case VBI_PIXFMT_UYVY:
730 case VBI_PIXFMT_VYUY:
731 skip = 1;
732 bs->bytes_per_sample = 2;
733 bs->func = bit_slicer_YUYV;
734 if (min_samples_per_bit > (3U << (LP_AVG - 1))) {
735 bs->func = low_pass_bit_slicer_Y8;
736 oversampling = 1;
737 bs->thresh <<= LP_AVG - 2;
738 bs->thresh_frac += LP_AVG - 2;
739 }
740 break;
741
742 case VBI_PIXFMT_RGBA24_LE:
743 case VBI_PIXFMT_BGRA24_LE:
744 skip = 1;
745 bs->bytes_per_sample = 4;
746 bs->func = bit_slicer_RGBA24_LE;
747 if (min_samples_per_bit > (3U << (LP_AVG - 1))) {
748 bs->func = low_pass_bit_slicer_Y8;
749 oversampling = 1;
750 bs->thresh <<= LP_AVG - 2;
751 bs->thresh_frac += LP_AVG - 2;
752 }
753 break;
754
755 case VBI_PIXFMT_RGBA24_BE:
756 case VBI_PIXFMT_BGRA24_BE:
757 skip = 2;
758 bs->bytes_per_sample = 4;
759 bs->func = bit_slicer_RGBA24_LE;
760 if (min_samples_per_bit > (3U << (LP_AVG - 1))) {
761 bs->func = low_pass_bit_slicer_Y8;
762 oversampling = 1;
763 bs->thresh <<= LP_AVG - 2;
764 bs->thresh_frac += LP_AVG - 2;
765 }
766 break;
767
768 case VBI_PIXFMT_RGB24_LE:
769 case VBI_PIXFMT_BGR24_LE:
770 skip = 1;
771 bs->bytes_per_sample = 3;
772 bs->func = bit_slicer_RGB24_LE;
773 if (min_samples_per_bit > (3U << (LP_AVG - 1))) {
774 bs->func = low_pass_bit_slicer_Y8;
775 oversampling = 1;
776 bs->thresh <<= LP_AVG - 2;
777 bs->thresh_frac += LP_AVG - 2;
778 }
779 break;
780
781 case VBI_PIXFMT_RGB16_LE:
782 case VBI_PIXFMT_BGR16_LE:
783 bs->func = bit_slicer_RGB16_LE;
784 bs->green_mask = 0x07E0;
785 bs->thresh = 105 << (5 - 2 + 12);
786 bs->thresh_frac = 12;
787 bs->bytes_per_sample = 2;
788 break;
789
790 case VBI_PIXFMT_RGB16_BE:
791 case VBI_PIXFMT_BGR16_BE:
792 bs->func = bit_slicer_RGB16_BE;
793 bs->green_mask = 0x07E0;
794 bs->thresh = 105 << (5 - 2 + 12);
795 bs->thresh_frac = 12;
796 bs->bytes_per_sample = 2;
797 break;
798
799 case VBI_PIXFMT_RGBA15_LE:
800 case VBI_PIXFMT_BGRA15_LE:
801 bs->func = bit_slicer_RGB16_LE;
802 bs->green_mask = 0x03E0;
803 bs->thresh = 105 << (5 - 3 + 11);
804 bs->thresh_frac = 11;
805 bs->bytes_per_sample = 2;
806 break;
807
808 case VBI_PIXFMT_RGBA15_BE:
809 case VBI_PIXFMT_BGRA15_BE:
810 bs->func = bit_slicer_RGB16_BE;
811 bs->green_mask = 0x03E0;
812 bs->thresh = 105 << (5 - 3 + 11);
813 bs->thresh_frac = 11;
814 bs->bytes_per_sample = 2;
815 break;
816
817 case VBI_PIXFMT_ARGB15_LE:
818 case VBI_PIXFMT_ABGR15_LE:
819 bs->func = bit_slicer_RGB16_LE;
820 bs->green_mask = 0x07C0;
821 bs->thresh = 105 << (6 - 3 + 12);
822 bs->thresh_frac = 12;
823 bs->bytes_per_sample = 2;
824 break;
825
826 case VBI_PIXFMT_ARGB15_BE:
827 case VBI_PIXFMT_ABGR15_BE:
828 bs->func = bit_slicer_RGB16_BE;
829 bs->green_mask = 0x07C0;
830 bs->thresh = 105 << (6 - 3 + 12);
831 bs->thresh_frac = 12;
832 bs->bytes_per_sample = 2;
833 break;
834
835
836 default:
837 warn (&bs->log,
838 "Unknown sample_format 0x%x.", (unsigned int) sample_format);
839 return FALSE;
840 }
841
842 bs->skip = sample_offset * bs->bytes_per_sample + skip;
843
844 bs->cri_mask = cri_mask & c_mask;
845 bs->cri = cri & bs->cri_mask;
846
847 /* We stop searching for CRI when CRI, FRC and payload
848 cannot possibly fit anymore. Additionally this eliminates
849 a data end check in the payload loop. */
850 cri_samples = (sampling_rate * (int64_t) cri_bits) / cri_rate;
851
852 data_bits = payload_bits + frc_bits;
853 data_samples = (sampling_rate * (int64_t) data_bits) / payload_rate;
854
855 bs->total_bits = cri_bits + data_bits;
856
857 if ((sample_offset > samples_per_line)
858 || ((cri_samples + data_samples)
859 > (samples_per_line - sample_offset))) {
860 warn (&bs->log,
861 "%u samples_per_line too small for "
862 "sample_offset %u + %u cri_bits (%u samples) "
863 "+ %u frc_bits and %u payload_bits "
864 "(%u samples).",
865 samples_per_line, sample_offset,
866 cri_bits, cri_samples, frc_bits, payload_bits, data_samples);
867 goto failure;
868 }
869
870 cri_end = MIN (cri_end, samples_per_line - data_samples);
871
872 bs->cri_samples = cri_end - sample_offset;
873 bs->cri_rate = cri_rate;
874
875 bs->oversampling_rate = sampling_rate * oversampling;
876
877 bs->frc = frc & f_mask;
878 bs->frc_bits = frc_bits;
879
880 /* Payload bit distance in 1/256 raw samples. */
881 bs->step = (sampling_rate * (int64_t) 256) / payload_rate;
882
883 if (payload_bits & 7) {
884 /* Use bit routines. */
885 bs->payload = payload_bits;
886 bs->endian = 3;
887 } else {
888 /* Use faster octet routines. */
889 bs->payload = payload_bits >> 3;
890 bs->endian = 1;
891 }
892
893 switch (modulation) {
894 case VBI3_MODULATION_NRZ_MSB:
895 --bs->endian;
896
897 /* fall through */
898
899 case VBI3_MODULATION_NRZ_LSB:
900 bs->phase_shift = (int)
901 (sampling_rate * 256.0 / cri_rate * .5 + bs->step * .5 + 128);
902 break;
903
904 case VBI3_MODULATION_BIPHASE_MSB:
905 --bs->endian;
906
907 /* fall through */
908
909 case VBI3_MODULATION_BIPHASE_LSB:
910 /* Phase shift between the NRZ modulated CRI and the
911 biphase modulated rest. */
912 bs->phase_shift = (int)
913 (sampling_rate * 256.0 / cri_rate * .5 + bs->step * .25 + 128);
914 break;
915 }
916
917 return TRUE;
918
919 failure:
920 bs->func = null_function;
921
922 return FALSE;
923 }
924
925 void
vbi3_bit_slicer_set_log_fn(vbi3_bit_slicer * bs,vbi_log_mask mask,vbi_log_fn * log_fn,void * user_data)926 vbi3_bit_slicer_set_log_fn (vbi3_bit_slicer * bs,
927 vbi_log_mask mask, vbi_log_fn * log_fn, void *user_data)
928 {
929 assert (NULL != bs);
930
931 if (NULL == log_fn)
932 mask = 0;
933
934 bs->log.mask = mask;
935 bs->log.fn = log_fn;
936 bs->log.user_data = user_data;
937 }
938
939 /**
940 * @internal
941 */
942 void
_vbi3_bit_slicer_destroy(vbi3_bit_slicer * bs)943 _vbi3_bit_slicer_destroy (vbi3_bit_slicer * bs)
944 {
945 assert (NULL != bs);
946
947 /* Make unusable. */
948 CLEAR (*bs);
949 }
950
951 /**
952 * @internal
953 */
954 vbi_bool
_vbi3_bit_slicer_init(vbi3_bit_slicer * bs)955 _vbi3_bit_slicer_init (vbi3_bit_slicer * bs)
956 {
957 assert (NULL != bs);
958
959 CLEAR (*bs);
960
961 bs->func = null_function;
962
963 return TRUE;
964 }
965
966 /**
967 * @param bs Pointer to a vbi3_bit_slicer object allocated with
968 * vbi3_bit_slicer_new(), can be NULL.
969 *
970 * Deletes a vbi3_bit_slicer object.
971 */
972 void
vbi3_bit_slicer_delete(vbi3_bit_slicer * bs)973 vbi3_bit_slicer_delete (vbi3_bit_slicer * bs)
974 {
975 if (NULL == bs)
976 return;
977
978 _vbi3_bit_slicer_destroy (bs);
979
980 vbi_free (bs);
981 }
982
983 /**
984 * Allocates a new vbi3_bit_slicer object.
985 *
986 * @returns
987 * @c NULL when out of memory.
988 */
989 vbi3_bit_slicer *
vbi3_bit_slicer_new(void)990 vbi3_bit_slicer_new (void)
991 {
992 vbi3_bit_slicer *bs;
993
994 bs = vbi_malloc (sizeof (*bs));
995 if (NULL == bs) {
996 return NULL;
997 }
998
999 _vbi3_bit_slicer_init (bs);
1000
1001 return bs;
1002 }
1003
1004 /*
1005 Local variables:
1006 c-set-style: K&R
1007 c-basic-offset: 8
1008 End:
1009 */
1010