• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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