diff options
author | Edward Hervey <edward@centricular.com> | 2018-03-15 07:07:16 +0100 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2018-05-28 14:50:01 +0200 |
commit | b0b02e7cb5b701c05b0ba92c8ca9bc857571e06d (patch) | |
tree | 26fcf195b7a69dc850c13cc230f54d385baf7a05 /ext/closedcaption/decoder.c | |
parent | 483892d16a77fcb41bc96a243472bae78d119f6a (diff) | |
download | gstreamer-plugins-bad-b0b02e7cb5b701c05b0ba92c8ca9bc857571e06d.tar.gz |
closedcaption: Include zvbi raw vbi decoder code
Current code from zapping/zvbi as of 2018-03-14. Files copied
are all LGPL v2+.
Changes from original zvbi code:
* Switch to gst-debug logging system
* Use glib for endianness detection
* Fix compilation warnings
Diffstat (limited to 'ext/closedcaption/decoder.c')
-rw-r--r-- | ext/closedcaption/decoder.c | 832 |
1 files changed, 832 insertions, 0 deletions
diff --git a/ext/closedcaption/decoder.c b/ext/closedcaption/decoder.c new file mode 100644 index 000000000..98933b1c8 --- /dev/null +++ b/ext/closedcaption/decoder.c @@ -0,0 +1,832 @@ +/* + * libzvbi -- Old raw VBI decoder + * + * Copyright (C) 2000, 2001, 2002 Michael H. Schimek + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +/* $Id: decoder.c,v 1.25 2008-02-19 00:35:15 mschimek Exp $ */ + +/* Note this code is only retained for compatibility with older versions + of libzvbi. vbi_raw_decoder is now just a wrapper for the new raw + decoder (raw_decoder.c) and bit slicer (bit_slicer.c). We'll drop + the old API in libzvbi 0.3. Other modules (e.g. io-v4l2k.c) should + already use the new raw VBI decoder directly. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <pthread.h> + +#include "misc.h" +#include "decoder.h" +#include "raw_decoder.h" + +/** + * @addtogroup Rawdec Raw VBI decoder + * @ingroup Raw + * @brief Converting raw VBI samples to bits and bytes. + * + * The libzvbi already offers hardware interfaces to obtain sliced + * VBI data for further processing. However if you want to write your own + * interface or decode data services not covered by libzvbi you can use + * these lower level functions. + */ + +/* + * Bit Slicer + */ + +#define OVERSAMPLING 4 /* 1, 2, 4, 8 */ +#define THRESH_FRAC 9 + +/* + * Note this is just a template. The code is inlined, + * with bpp and endian being const. + * + * This function translates from the image format to + * plain bytes, with linear interpolation of samples. + * Could be further improved with a lowpass filter. + */ +static inline unsigned int +sample (uint8_t * raw, int offs, int bpp, int endian) +{ + unsigned char frac = offs; + int raw0, raw1; + + switch (bpp) { + case 14: /* 1:5:5:5 LE/BE */ + raw += (offs >> 8) * 2; + raw0 = (raw[0 + endian] + raw[1 - endian] * 256) & 0x07C0; + raw1 = (raw[2 + endian] + raw[3 - endian] * 256) & 0x07C0; + return (raw1 - raw0) * frac + (raw0 << 8); + + case 15: /* 5:5:5:1 LE/BE */ + raw += (offs >> 8) * 2; + raw0 = (raw[0 + endian] + raw[1 - endian] * 256) & 0x03E0; + raw1 = (raw[2 + endian] + raw[3 - endian] * 256) & 0x03E0; + return (raw1 - raw0) * frac + (raw0 << 8); + + case 16: /* 5:6:5 LE/BE */ + raw += (offs >> 8) * 2; + raw0 = (raw[0 + endian] + raw[1 - endian] * 256) & 0x07E0; + raw1 = (raw[2 + endian] + raw[3 - endian] * 256) & 0x07E0; + return (raw1 - raw0) * frac + (raw0 << 8); + + default: /* 8 (intermediate bytes skipped by caller) */ + raw += (offs >> 8) * bpp; + return (raw[bpp] - raw[0]) * frac + (raw[0] << 8); + } +} + +/* + * Note this is just a template. The code is inlined, + * with bpp being const. + */ +static inline vbi_bool +bit_slicer_tmpl (vbi_bit_slicer * d, uint8_t * raw, + uint8_t * buf, int bpp, int endian) +{ + unsigned int i, j, k; + unsigned int cl = 0, thresh0 = d->thresh, tr; + unsigned int c = 0, t; + unsigned char b, b1 = 0; + int raw0, raw1, mask; + + raw += d->skip; + + if (bpp == 14) + mask = 0x07C0; + else if (bpp == 15) + mask = 0x03E0; + else if (bpp == 16) + mask = 0x07E0; + + for (i = d->cri_bytes; i > 0; raw += (bpp >= 14 && bpp <= 16) ? 2 : bpp, i--) { + if (bpp >= 14 && bpp <= 16) { + raw0 = (raw[0 + endian] + raw[1 - endian] * 256) & mask; + raw1 = (raw[2 + endian] + raw[3 - endian] * 256) & mask; + tr = d->thresh >> THRESH_FRAC; + d->thresh += ((raw0 - tr) * (int) ABS (raw1 - raw0)) >> + ((bpp == 15) ? 2 : 3); + t = raw0 * OVERSAMPLING; + } else { + tr = d->thresh >> THRESH_FRAC; + d->thresh += ((int) raw[0] - tr) * (int) ABS (raw[bpp] - raw[0]); + t = raw[0] * OVERSAMPLING; + } + + for (j = OVERSAMPLING; j > 0; j--) { + b = ((t + (OVERSAMPLING / 2)) / OVERSAMPLING >= tr); + + if (b ^ b1) { + cl = d->oversampling_rate >> 1; + } else { + cl += d->cri_rate; + + if (cl >= (unsigned int) d->oversampling_rate) { + cl -= d->oversampling_rate; + + c = c * 2 + b; + + if ((c & d->cri_mask) == d->cri) { + i = d->phase_shift; + tr *= 256; + c = 0; + + for (j = d->frc_bits; j > 0; j--) { + c = c * 2 + (sample (raw, i, bpp, endian) >= tr); + i += d->step; + } + + if (c ^= d->frc) + return FALSE; + + /* CRI/FRC found, now get the + payload and exit */ + + switch (d->endian) { + case 3: + for (j = 0; j < (unsigned int) d->payload; j++) { + c >>= 1; + c += (sample (raw, i, bpp, endian) >= tr) << 7; + i += d->step; + + if ((j & 7) == 7) + *buf++ = c; + } + + *buf = c >> ((8 - d->payload) & 7); + break; + + case 2: + for (j = 0; j < (unsigned int) d->payload; j++) { + c = c * 2 + (sample (raw, i, bpp, endian) >= tr); + i += d->step; + + if ((j & 7) == 7) + *buf++ = c; + } + + *buf = c & ((1 << (d->payload & 7)) - 1); + break; + + case 1: + for (j = d->payload; j > 0; j--) { + for (k = 0; k < 8; k++) { + c >>= 1; + c += (sample (raw, i, bpp, endian) >= tr) << 7; + i += d->step; + } + + *buf++ = c; + } + + break; + + case 0: + for (j = d->payload; j > 0; j--) { + for (k = 0; k < 8; k++) { + c = c * 2 + (sample (raw, i, bpp, endian) >= tr); + i += d->step; + } + + *buf++ = c; + } + + break; + } + + return TRUE; + } + } + } + + b1 = b; + + if (OVERSAMPLING > 1) { + if (bpp >= 14 && bpp <= 16) { + t += raw1; + t -= raw0; + } else { + t += raw[bpp]; + t -= raw[0]; + } + } + } + } + + d->thresh = thresh0; + + return FALSE; +} + +static vbi_bool +bit_slicer_1 (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 1, 0); +} + +static vbi_bool +bit_slicer_2 (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 2, 0); +} + +static vbi_bool +bit_slicer_3 (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 3, 0); +} + +static vbi_bool +bit_slicer_4 (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 4, 0); +} + +static vbi_bool +bit_slicer_1555_le (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 14, 0); +} + +static vbi_bool +bit_slicer_5551_le (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 15, 0); +} + +static vbi_bool +bit_slicer_565_le (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 16, 0); +} + +static vbi_bool +bit_slicer_1555_be (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 14, 1); +} + +static vbi_bool +bit_slicer_5551_be (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 15, 1); +} + +static vbi_bool +bit_slicer_565_be (vbi_bit_slicer * d, uint8_t * raw, uint8_t * buf) +{ + return bit_slicer_tmpl (d, raw, buf, 16, 1); +} + +/** + * @param slicer Pointer to vbi_bit_slicer object to be initialized. + * @param raw_samples Number of samples or pixels in one raw vbi line + * later passed to vbi_bit_slice(). This limits the number of + * bytes read from the sample buffer. + * @param sampling_rate Raw vbi sampling rate in Hz, that is the number of + * samples or pixels sampled per second by the hardware. + * @param cri_rate The Clock Run In is a NRZ modulated + * sequence of '0' and '1' bits prepending most data transmissions to + * synchronize data acquisition circuits. This parameter gives the CRI bit + * rate in Hz, that is the number of CRI bits transmitted per second. + * @param bit_rate The transmission bit rate of all data bits following the CRI + * in Hz. + * @param cri_frc The FRaming Code usually following the CRI is a bit sequence + * identifying the data service, and per libzvbi definition modulated + * and transmitted at the same bit rate as the payload (however nothing + * stops you from counting all nominal CRI and FRC bits as CRI). + * The bit slicer compares the bits in this word, lsb last transmitted, + * against the transmitted CRI and FRC. Decoding of payload starts + * with the next bit after a match. + * @param cri_mask Of the CRI bits in @c cri_frc, only these bits are + * actually significant for a match. For instance it is wise + * not to rely on the very first CRI bits transmitted. Note this + * mask is not shifted left by @a frc_bits. + * @param cri_bits + * @param frc_bits Number of CRI and FRC bits in @a cri_frc, respectively. + * Their sum is limited to 32. + * @param payload Number of payload <em>bits</em>. Only this data + * will be stored in the vbi_bit_slice() output. If this number + * is no multiple of eight, the most significant bits of the + * last byte are undefined. + * @param modulation Modulation of the vbi data, see vbi_modulation. + * @param fmt Format of the raw data, see vbi_pixfmt. + * + * Initializes vbi_bit_slicer object. Usually you will not use this + * function but vbi_raw_decode(), the vbi image decoder which handles + * all these details. + */ +void +vbi_bit_slicer_init (vbi_bit_slicer * slicer, + int raw_samples, int sampling_rate, + int cri_rate, int bit_rate, + unsigned int cri_frc, unsigned int cri_mask, + int cri_bits, int frc_bits, int payload, + vbi_modulation modulation, vbi_pixfmt fmt) +{ + unsigned int c_mask = (unsigned int) (-(cri_bits > 0)) >> (32 - cri_bits); + unsigned int f_mask = (unsigned int) (-(frc_bits > 0)) >> (32 - frc_bits); + int gsh = 0; + + slicer->func = bit_slicer_1; + + switch (fmt) { + case VBI_PIXFMT_RGB24: + case VBI_PIXFMT_BGR24: + slicer->func = bit_slicer_3; + slicer->skip = 1; + break; + + case VBI_PIXFMT_RGBA32_LE: + case VBI_PIXFMT_BGRA32_LE: + slicer->func = bit_slicer_4; + slicer->skip = 1; + break; + + case VBI_PIXFMT_RGBA32_BE: + case VBI_PIXFMT_BGRA32_BE: + slicer->func = bit_slicer_4; + slicer->skip = 2; + break; + + case VBI_PIXFMT_RGB16_LE: + case VBI_PIXFMT_BGR16_LE: + slicer->func = bit_slicer_565_le; + gsh = 3; /* (green << 3) & 0x07E0 */ + slicer->skip = 0; + break; + + case VBI_PIXFMT_RGBA15_LE: + case VBI_PIXFMT_BGRA15_LE: + slicer->func = bit_slicer_5551_le; + gsh = 2; /* (green << 2) & 0x03E0 */ + slicer->skip = 0; + break; + + case VBI_PIXFMT_ARGB15_LE: + case VBI_PIXFMT_ABGR15_LE: + slicer->func = bit_slicer_1555_le; + gsh = 3; /* (green << 2) & 0x07C0 */ + slicer->skip = 0; + break; + + case VBI_PIXFMT_RGB16_BE: + case VBI_PIXFMT_BGR16_BE: + slicer->func = bit_slicer_565_be; + gsh = 3; /* (green << 3) & 0x07E0 */ + slicer->skip = 0; + break; + + case VBI_PIXFMT_RGBA15_BE: + case VBI_PIXFMT_BGRA15_BE: + slicer->func = bit_slicer_5551_be; + gsh = 2; /* (green << 2) & 0x03E0 */ + slicer->skip = 0; + break; + + case VBI_PIXFMT_ARGB15_BE: + case VBI_PIXFMT_ABGR15_BE: + slicer->func = bit_slicer_1555_be; + gsh = 3; /* (green << 2) & 0x07C0 */ + slicer->skip = 0; + break; + + case VBI_PIXFMT_YUV420: + slicer->func = bit_slicer_1; + slicer->skip = 0; + break; + + case VBI_PIXFMT_YUYV: + case VBI_PIXFMT_YVYU: + slicer->func = bit_slicer_2; + slicer->skip = 0; + break; + + case VBI_PIXFMT_UYVY: + case VBI_PIXFMT_VYUY: + slicer->func = bit_slicer_2; + slicer->skip = 1; + break; + + default: + fprintf (stderr, "vbi_bit_slicer_init: unknown pixfmt %d\n", fmt); + exit (EXIT_FAILURE); + } + + slicer->cri_mask = cri_mask & c_mask; + slicer->cri = (cri_frc >> frc_bits) & slicer->cri_mask; + /* We stop searching for CRI/FRC when the payload + cannot possibly fit anymore. */ + slicer->cri_bytes = raw_samples + - ((long long) sampling_rate * (payload + frc_bits)) / bit_rate; + slicer->cri_rate = cri_rate; + /* Raw vbi data is oversampled to account for low sampling rates. */ + slicer->oversampling_rate = sampling_rate * OVERSAMPLING; + /* 0/1 threshold */ + slicer->thresh = 105 << (THRESH_FRAC + gsh); + slicer->frc = cri_frc & f_mask; + slicer->frc_bits = frc_bits; + /* Payload bit distance in 1/256 raw samples. */ + slicer->step = (int) (sampling_rate * 256.0 / bit_rate); + + if (payload & 7) { + slicer->payload = payload; + slicer->endian = 3; + } else { + slicer->payload = payload >> 3; + slicer->endian = 1; + } + + switch (modulation) { + case VBI_MODULATION_NRZ_MSB: + slicer->endian--; + case VBI_MODULATION_NRZ_LSB: + slicer->phase_shift = (int) + (sampling_rate * 256.0 / cri_rate * .5 + + sampling_rate * 256.0 / bit_rate * .5 + 128); + break; + + case VBI_MODULATION_BIPHASE_MSB: + slicer->endian--; + case VBI_MODULATION_BIPHASE_LSB: + /* Phase shift between the NRZ modulated CRI and the rest */ + slicer->phase_shift = (int) + (sampling_rate * 256.0 / cri_rate * .5 + + sampling_rate * 256.0 / bit_rate * .25 + 128); + break; + } +} + +/** + * @example examples/wss.c + * WSS capture example. + */ + +/** + * @param rd Initialized vbi_raw_decoder structure. + * @param raw A raw vbi image as defined in the vbi_raw_decoder structure + * (rd->sampling_format, rd->bytes_per_line, rd->count[0] + rd->count[1] + * scan lines). + * @param out Buffer to store the decoded vbi_sliced data. Since every + * vbi scan line may contain data, this must be an array of vbi_sliced + * with the same number of entries as scan lines in the raw image + * (rd->count[0] + rd->count[1]). + * + * Decode a raw vbi image, consisting of several scan lines of raw vbi data, + * into sliced vbi data. The output is sorted by line number. + * + * Note this function attempts to learn which lines carry which data + * service, or none, to speed up decoding. You should avoid using the same + * vbi_raw_decoder structure for different sources. + * + * @return + * The number of lines decoded, i. e. the number of vbi_sliced records + * written. + */ +int +vbi_raw_decode (vbi_raw_decoder * rd, uint8_t * raw, vbi_sliced * out) +{ + vbi3_raw_decoder *rd3; + unsigned int n_lines; + + assert (NULL != rd); + assert (NULL != raw); + assert (NULL != out); + + rd3 = (vbi3_raw_decoder *) rd->pattern; + n_lines = rd->count[0] + rd->count[1]; + + pthread_mutex_lock (&rd->mutex); + + { + n_lines = vbi3_raw_decoder_decode (rd3, out, n_lines, raw); + } + + pthread_mutex_unlock (&rd->mutex); + + return n_lines; +} + +/** + * @param rd Initialized vbi_raw_decoder structure. + * @param start Array of start line indices for both fields + * @param count Array of line counts for both fields + * + * Grows or shrinks the internal state arrays for VBI geometry changes + */ +void +vbi_raw_decoder_resize (vbi_raw_decoder * rd, int *start, unsigned int *count) +{ +#if 0 /* Set but unused */ + vbi_service_set service_set; +#endif + vbi3_raw_decoder *rd3; + + assert (NULL != rd); + assert (NULL != start); + assert (NULL != count); + + rd3 = (vbi3_raw_decoder *) rd->pattern; + + pthread_mutex_lock (&rd->mutex); + + { + if ((rd->start[0] == start[0]) + && (rd->start[1] == start[1]) + && (rd->count[0] == (int) count[0]) + && (rd->count[1] == (int) count[1])) { + pthread_mutex_unlock (&rd->mutex); + return; + } + + rd->start[0] = start[0]; + rd->start[1] = start[1]; + rd->count[0] = count[0]; + rd->count[1] = count[1]; + +#if 0 /* Set but unused */ + service_set = vbi3_raw_decoder_set_sampling_par + (rd3, (vbi_sampling_par *) rd, /* strict */ 0); +#else + vbi3_raw_decoder_set_sampling_par + (rd3, (vbi_sampling_par *) rd, /* strict */ 0); +#endif + } + + pthread_mutex_unlock (&rd->mutex); +} + +/** + * @param rd Initialized vbi_raw_decoder structure. + * @param services Set of @ref VBI_SLICED_ symbols. + * + * Removes one or more data services to be decoded from the + * vbi_raw_decoder structure. This function can be called at any + * time and does not touch sampling parameters. + * + * @return + * Set of @ref VBI_SLICED_ symbols describing the remaining data + * services that will be decoded. + */ +unsigned int +vbi_raw_decoder_remove_services (vbi_raw_decoder * rd, unsigned int services) +{ + vbi_service_set service_set; + vbi3_raw_decoder *rd3; + + assert (NULL != rd); + + rd3 = (vbi3_raw_decoder *) rd->pattern; + service_set = services; + + pthread_mutex_lock (&rd->mutex); + + { + service_set = vbi3_raw_decoder_remove_services (rd3, service_set); + } + + pthread_mutex_unlock (&rd->mutex); + + return service_set; +} + +/** + * @param rd Initialized vbi_raw_decoder structure. + * @param services Set of @ref VBI_SLICED_ symbols. + * @param strict See description of vbi_raw_decoder_add_services() + * + * Check which of the given services can be decoded with current capture + * parameters at a given strictness level. + * + * @return + * Subset of services actually decodable. + */ +unsigned int +vbi_raw_decoder_check_services (vbi_raw_decoder * rd, + unsigned int services, int strict) +{ + vbi_service_set service_set; + + assert (NULL != rd); + + service_set = services; + + pthread_mutex_lock (&rd->mutex); + + { + service_set = vbi_sampling_par_check_services + ((vbi_sampling_par *) rd, service_set, strict); + } + + pthread_mutex_unlock (&rd->mutex); + + return (unsigned int) service_set; +} + +/** + * @param rd Initialized vbi_raw_decoder structure. + * @param services Set of @ref VBI_SLICED_ symbols. + * @param strict A value of 0, 1 or 2 requests loose, reliable or strict + * matching of sampling parameters. For example if the data service + * requires knowledge of line numbers while they are not known, @c 0 + * will accept the service (which may work if the scan lines are + * populated in a non-confusing way) but @c 1 or @c 2 will not. If the + * data service <i>may</i> use more lines than are sampled, @c 1 will + * accept but @c 2 will not. If unsure, set to @c 1. + * + * After you initialized the sampling parameters in @a rd (according to + * the abilities of your raw vbi source), this function adds one or more + * data services to be decoded. The libzvbi raw vbi decoder can decode up + * to eight data services in parallel. You can call this function while + * already decoding, it does not change sampling parameters and you must + * not change them either after calling this. + * + * @return + * Set of @ref VBI_SLICED_ symbols describing the data services that actually + * will be decoded. This excludes those services not decodable given + * the sampling parameters in @a rd. + */ +unsigned int +vbi_raw_decoder_add_services (vbi_raw_decoder * rd, + unsigned int services, int strict) +{ + vbi_service_set service_set; + vbi3_raw_decoder *rd3; + + assert (NULL != rd); + + rd3 = (vbi3_raw_decoder *) rd->pattern; + service_set = services; + + pthread_mutex_lock (&rd->mutex); + + { + vbi3_raw_decoder_set_sampling_par (rd3, (vbi_sampling_par *) rd, strict); + + service_set = vbi3_raw_decoder_add_services (rd3, service_set, strict); + } + + pthread_mutex_unlock (&rd->mutex); + + return service_set; +} + +/** + * @param rd Initialized vbi_raw_decoder structure. + * @param services Set of VBI_SLICED_ symbols. Here (and only here) you + * can add @c VBI_SLICED_VBI_625 or @c VBI_SLICED_VBI_525 to include all + * vbi scan lines in the calculated sampling parameters. + * @param scanning When 525 accept only NTSC services, when 625 + * only PAL/SECAM services. When scanning is 0, determine the scanning + * from the requested services, an ambiguous set will pick + * a 525 or 625 line system at random. + * @param max_rate If given, the highest data bit rate in Hz of all + * services requested is stored here. (The sampling rate + * should be at least twice as high; rd->sampling_rate will + * be set to a more reasonable value of 27 MHz derived + * from ITU-R Rec. 601.) + * + * Calculate the sampling parameters in @a rd required to receive and + * decode the requested data @a services. rd->sampling_format will be + * @c VBI_PIXFMT_YUV420, rd->bytes_per_line set accordingly to a + * reasonable minimum. This function can be used to initialize hardware + * prior to calling vbi_raw_decoder_add_service(). + * + * @return + * Set of @ref VBI_SLICED_ symbols describing the data services covered + * by the calculated sampling parameters. This excludes services the libzvbi + * raw decoder cannot decode. + */ +unsigned int +vbi_raw_decoder_parameters (vbi_raw_decoder * rd, + unsigned int services, int scanning, int *max_rate) +{ + vbi_videostd_set videostd_set; + vbi_service_set service_set; + + switch (scanning) { + case 525: + videostd_set = VBI_VIDEOSTD_SET_525_60; + break; + + case 625: + videostd_set = VBI_VIDEOSTD_SET_625_50; + break; + + default: + videostd_set = 0; + break; + } + + service_set = services; + + pthread_mutex_lock (&rd->mutex); + + { + service_set = vbi_sampling_par_from_services + ((vbi_sampling_par *) rd, + (unsigned int *) max_rate, videostd_set, service_set); + } + + pthread_mutex_unlock (&rd->mutex); + + return (unsigned int) service_set; +} + +/** + * @param rd Initialized vbi_raw_decoder structure. + * + * Reset a vbi_raw_decoder structure. This removes + * all previously added services to be decoded (if any) + * but does not touch the sampling parameters. You are + * free to change the sampling parameters after calling this. + */ +void +vbi_raw_decoder_reset (vbi_raw_decoder * rd) +{ + vbi3_raw_decoder *rd3; + + if (!rd) + return; /* compatibility */ + + assert (NULL != rd); + + rd3 = (vbi3_raw_decoder *) rd->pattern; + + pthread_mutex_lock (&rd->mutex); + + { + vbi3_raw_decoder_reset (rd3); + } + + pthread_mutex_unlock (&rd->mutex); +} + +/** + * @param rd Pointer to initialized vbi_raw_decoder + * structure, can be @c NULL. + * + * Free all resources associated with @a rd. + */ +void +vbi_raw_decoder_destroy (vbi_raw_decoder * rd) +{ + vbi3_raw_decoder *rd3; + + assert (NULL != rd); + + rd3 = (vbi3_raw_decoder *) rd->pattern; + + vbi3_raw_decoder_delete (rd3); + + pthread_mutex_destroy (&rd->mutex); + + CLEAR (*rd); +} + +/** + * @param rd Pointer to a vbi_raw_decoder structure. + * + * Initializes a vbi_raw_decoder structure. + */ +void +vbi_raw_decoder_init (vbi_raw_decoder * rd) +{ + vbi3_raw_decoder *rd3; + + assert (NULL != rd); + + CLEAR (*rd); + + pthread_mutex_init (&rd->mutex, NULL); + + rd3 = vbi3_raw_decoder_new ( /* sampling_par */ NULL); + assert (NULL != rd3); + + rd->pattern = (int8_t *) rd3; +} + +/* +Local variables: +c-set-style: K&R +c-basic-offset: 8 +End: +*/ |