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
This commit is contained in:
Edward Hervey 2018-03-15 07:07:16 +01:00 committed by Edward Hervey
parent 483892d16a
commit b0b02e7cb5
13 changed files with 5893 additions and 1 deletions

View file

@ -1,6 +1,24 @@
plugin_LTLIBRARIES = libgstclosedcaption.la
zvbi_sources = \
bit_slicer.c \
decoder.c \
raw_decoder.c \
sampling_par.c
zvbi_headers = \
bcd.h \
bit_slicer.h \
decoder.h \
macros.h \
misc.h \
raw_decoder.h \
sampling_par.h \
sliced.h
libgstclosedcaption_la_SOURCES = \
$(zvbi_sources) \
$(zvbi_headers) \
gstccextractor.c \
gstccextractor.h \
gstclosedcaption.c
@ -18,4 +36,5 @@ libgstclosedcaption_la_LIBADD = \
libgstclosedcaption_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = \
gstccextractor.h
gstccextractor.h \
$(zvbi_headers)

223
ext/closedcaption/bcd.h Normal file
View file

@ -0,0 +1,223 @@
/*
* libzvbi -- BCD arithmetic for Teletext page numbers
*
* Copyright (C) 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: bcd.h,v 1.19 2008-02-21 07:18:52 mschimek Exp $ */
#ifndef BCD_H
#define BCD_H
#include "misc.h"
/**
* @addtogroup BCD BCD arithmetic for Teletext page numbers
* @ingroup HiDec
*
* Teletext page numbers are expressed as packed binary coded decimal
* numbers in range 0x100 to 0x8FF. The bcd format encodes one decimal
* digit in every hex nibble (four bits) of the number. Page numbers
* containing digits 0xA to 0xF are reserved for various system purposes
* and not intended for display.
*/
/* Public */
/**
* @ingroup HiDec
*
* Teletext or Closed Caption page number. For Teletext pages
* this is a packed bcd number in range 0x100 ... 0x8FF. Page
* numbers containing digits 0xA to 0xF are reserved for various
* system purposes, these pages are not intended for display.
*
* Closed Caption page numbers between 1 ... 8 correspond
* to the four Caption and Text channels:
* <table>
* <tr><td>1</td><td>Caption 1</td><td>
* "Primary synchronous caption service [English]"</td></tr>
* <tr><td>2</td><td>Caption 2</td><td>
* "Special non-synchronous data that is intended to
* augment information carried in the program"</td></tr>
* <tr><td>3</td><td>Caption 3</td><td>
* "Secondary synchronous caption service, usually
* second language [Spanish, French]"</td></tr>
* <tr><td>4</td><td>Caption 4</td><td>
* "Special non-synchronous data similar to Caption 2"</td></tr>
* <tr><td>5</td><td>Text 1</td><td>
* "First text service, data usually not program related"</td></tr>
* <tr><td>6</td><td>Text 2</td><td>
* "Second text service, additional data usually not program related
* [ITV data]"</td></tr>
* <tr><td>7</td><td>Text 3</td><td>
* "Additional text channel"</td></tr>
* <tr><td>8</td><td>Text 4</td><td>
* "Additional text channel"</td></tr>
* </table>
*/
/* XXX unsigned? */
typedef int vbi_pgno;
/**
* @ingroup HiDec
*
* This is the subpage number only applicable to Teletext pages,
* a packed bcd number in range 0x00 ... 0x99. On special 'clock' pages
* (for example listing the current time in different time zones)
* it can assume values between 0x0000 ... 0x2359 expressing
* local time. These are not actually subpages.
*/
typedef int vbi_subno;
/**
* @ingroup HiDec
*/
#define VBI_ANY_SUBNO 0x3F7F
/**
* @ingroup HiDec
*/
#define VBI_NO_SUBNO 0x3F7F
/**
* @ingroup BCD
* @param dec Decimal number.
*
* Converts a two's complement binary between 0 ... 999 to a
* packed bcd number in range 0x000 ... 0x999. Extra digits in
* the input will be discarded.
*
* @return
* BCD number.
*/
_vbi_inline unsigned int
vbi_dec2bcd(unsigned int dec)
{
return (dec % 10) + ((dec / 10) % 10) * 16 + ((dec / 100) % 10) * 256;
}
/**
* @ingroup BCD
* @since 0.2.28
*/
#define vbi_bin2bcd(n) vbi_dec2bcd(n)
/**
* @ingroup BCD
* @param bcd BCD number.
*
* Converts a packed bcd number between 0x000 ... 0xFFF to a two's
* complement binary in range 0 ... 999. Extra digits in the input
* will be discarded.
*
* @return
* Decimal number. The result is undefined when the bcd number contains
* hex digits 0xA ... 0xF.
**/
_vbi_inline unsigned int
vbi_bcd2dec(unsigned int bcd)
{
return (bcd & 15) + ((bcd >> 4) & 15) * 10 + ((bcd >> 8) & 15) * 100;
}
/**
* @ingroup BCD
* @since 0.2.28
*/
#define vbi_bcd2bin(n) vbi_bcd2dec(n)
/**
* @ingroup BCD
* @param a BCD number.
* @param b BCD number.
*
* Adds two packed bcd numbers, returning a packed bcd sum. Arguments
* and result are in range 0xF000&nbsp;0000 ... 0x0999&nbsp;9999, that
* is -10**7 ... +10**7 - 1 in decimal notation. To subtract you can
* add the 10's complement, e. g. -1 = 0xF999&nbsp;9999.
*
* @return
* Packed bcd number. The result is undefined when any of the arguments
* contain hex digits 0xA ... 0xF.
*/
_vbi_inline unsigned int
vbi_add_bcd(unsigned int a, unsigned int b)
{
unsigned int t;
a += 0x06666666;
t = a + b;
b ^= a ^ t;
b = (~b & 0x11111110) >> 3;
b |= b * 2;
return t - b;
}
/**
* @ingroup BCD
* @param bcd BCD number.
*
* Tests if @a bcd forms a valid BCD number. The argument must be
* in range 0x0000&nbsp;0000 ... 0x0999&nbsp;9999.
*
* @return
* @c FALSE if @a bcd contains hex digits 0xA ... 0xF.
*/
_vbi_inline vbi_bool
vbi_is_bcd(unsigned int bcd)
{
static const unsigned int x = 0x06666666;
return (((bcd + x) ^ (bcd ^ x)) & 0x11111110) == 0;
}
/**
* @ingroup BCD
* @param bcd Unsigned BCD number.
* @param maximum Unsigned maximum value.
*
* Compares an unsigned packed bcd number digit-wise against a maximum
* value, for example 0x295959. @a maximum can contain digits 0x0
* ... 0xF.
*
* @return
* @c TRUE if any digit of @a bcd is greater than the
* corresponding digit of @a maximum.
*
* @since 0.2.28
*/
_vbi_inline vbi_bool
vbi_bcd_digits_greater (unsigned int bcd,
unsigned int maximum)
{
maximum ^= ~0;
return 0 != (((bcd + maximum) ^ bcd ^ maximum) & 0x11111110);
}
/* Private */
#endif /* BCD_H */
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,197 @@
/*
* libzvbi -- Bit slicer
*
* Copyright (C) 2000-2007 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: bit_slicer.h,v 1.11 2008-02-24 14:18:13 mschimek Exp $ */
#ifndef __ZVBI_BIT_SLICER_H__
#define __ZVBI_BIT_SLICER_H__
#include "sampling_par.h"
VBI_BEGIN_DECLS
/**
* @addtogroup BitSlicer
* @{
*/
/**
* @brief Modulation used for VBI data transmission.
*/
typedef enum {
/**
* The data is 'non-return to zero' coded, logical '1' bits
* are described by high sample values, logical '0' bits by
* low values. The data is last significant bit first transmitted.
*/
VBI3_MODULATION_NRZ_LSB,
/**
* 'Non-return to zero' coded, most significant bit first
* transmitted.
*/
VBI3_MODULATION_NRZ_MSB,
/**
* The data is 'bi-phase' coded. Each data bit is described
* by two complementary signalling elements, a logical '1'
* by a sequence of '10' elements, a logical '0' by a '01'
* sequence. The data is last significant bit first transmitted.
*/
VBI3_MODULATION_BIPHASE_LSB,
/** 'Bi-phase' coded, most significant bit first transmitted. */
VBI3_MODULATION_BIPHASE_MSB
} vbi3_modulation;
/**
* @brief Bit slicer context.
*
* The contents of this structure are private.
* Call vbi3_bit_slicer_new() to allocate a bit slicer context.
*/
typedef struct _vbi3_bit_slicer vbi3_bit_slicer;
typedef enum {
VBI3_CRI_BIT = 1,
VBI3_FRC_BIT,
VBI3_PAYLOAD_BIT
} vbi3_bit_slicer_bit;
/**
* @brief Bit slicer sampling point.
*
* This structure contains information about
* a bit sampled by the bit slicer.
*/
typedef struct {
/** Whether this struct refers to a CRI, FRC or payload bit. */
vbi3_bit_slicer_bit kind;
/** Number of the sample times 256. */
unsigned int index;
/** Signal amplitude at this sample, in range 0 to 65535. */
unsigned int level;
/** 0/1 threshold at this sample, in range 0 to 65535. */
unsigned int thresh;
} vbi3_bit_slicer_point;
extern 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)
_vbi_nonnull ((1, 2, 4, 5, 7));
extern vbi_bool
vbi3_bit_slicer_slice (vbi3_bit_slicer * bs,
uint8_t * buffer,
unsigned int buffer_size,
const uint8_t * raw)
_vbi_nonnull ((1, 2, 4));
extern 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)
_vbi_nonnull ((1));
extern void
vbi3_bit_slicer_set_log_fn (vbi3_bit_slicer * bs,
vbi_log_mask mask,
vbi_log_fn * log_fn,
void * user_data)
_vbi_nonnull ((1));
extern void
vbi3_bit_slicer_delete (vbi3_bit_slicer * bs);
extern vbi3_bit_slicer *
vbi3_bit_slicer_new (void)
_vbi_alloc;
/* Private */
typedef vbi_bool
_vbi3_bit_slicer_fn (vbi3_bit_slicer * bs,
uint8_t * buffer,
vbi3_bit_slicer_point *points,
unsigned int * n_points,
const uint8_t * raw);
/** @internal */
struct _vbi3_bit_slicer {
_vbi3_bit_slicer_fn * func;
vbi_pixfmt sample_format;
unsigned int cri;
unsigned int cri_mask;
unsigned int thresh;
unsigned int thresh_frac;
unsigned int cri_samples;
unsigned int cri_rate;
unsigned int oversampling_rate;
unsigned int phase_shift;
unsigned int step;
unsigned int frc;
unsigned int frc_bits;
unsigned int total_bits;
unsigned int payload;
unsigned int endian;
unsigned int bytes_per_sample;
unsigned int skip;
unsigned int green_mask;
_vbi_log_hook log;
};
extern void
_vbi3_bit_slicer_destroy (vbi3_bit_slicer * bs)
_vbi_nonnull ((1));
extern vbi_bool
_vbi3_bit_slicer_init (vbi3_bit_slicer * bs)
_vbi_nonnull ((1));
/** @} */
VBI_END_DECLS
#endif /* __ZVBI_BIT_SLICER_H__ */
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

832
ext/closedcaption/decoder.c Normal file
View file

@ -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:
*/

415
ext/closedcaption/decoder.h Normal file
View file

@ -0,0 +1,415 @@
/*
* 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.h,v 1.11 2008-02-19 00:35:15 mschimek Exp $ */
#ifndef DECODER_H
#define DECODER_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "bcd.h"
#include "sliced.h"
/* Public */
#include <pthread.h>
/* Bit slicer */
/**
* @ingroup Rawdec
* @brief Image format used as source to vbi_bit_slice() and vbi_raw_decode().
*
* @htmlonly
<table border=1>
<tr><th>Symbol</th><th>Byte&nbsp;0</th><th>Byte&nbsp;1</th><th>Byte&nbsp;2</th><th>Byte&nbsp;3</th></tr>
<tr><td colspan=5>Planar YUV 4:2:0 data.</td></tr>
<tr><td>VBI_PIXFMT_YUV420</td><td colspan=4>
<table>
<tr><th>Y plane</th><th>U plane</th><th>V plane</th></tr>
<tr><td><table border=1>
<tr><td>Y00</td><td>Y01</td><td>Y02</td><td>Y03</td></tr>
<tr><td>Y10</td><td>Y11</td><td>Y12</td><td>Y13</td></tr>
<tr><td>Y20</td><td>Y21</td><td>Y22</td><td>Y23</td></tr>
<tr><td>Y30</td><td>Y31</td><td>Y32</td><td>Y33</td></tr>
</table></td>
<td><table border=1>
<tr><td>Cb00</td><td>Cb01</td></tr>
<tr><td>Cb10</td><td>Cb11</td></tr>
</table></td>
<td><table border=1>
<tr><td>Cr00</td><td>Cr01</td></tr>
<tr><td>Cr10</td><td>Cr11</td></tr>
</table></td>
</tr></table></td>
</tr>
<tr><td colspan=5>Packed YUV 4:2:2 data.</td></tr>
<tr><td>VBI_PIXFMT_YUYV</td><td>Y0</td><td>Cb</td><td>Y1</td><td>Cr</td></tr>
<tr><td>VBI_PIXFMT_YVYU</td><td>Y0</td><td>Cr</td><td>Y1</td><td>Cb</td></tr>
<tr><td>VBI_PIXFMT_UYVY</td><td>Cb</td><td>Y0</td><td>Cr</td><td>Y1</td></tr>
<tr><td>VBI_PIXFMT_VYUY</td><td>Cr</td><td>Y0</td><td>Cb</td><td>Y1</td></tr>
<tr><td colspan=5>Packed 32 bit RGB data.</td></tr>
<tr><td>VBI_PIXFMT_RGBA32_LE VBI_PIXFMT_ARGB32_BE</td>
<td>r7&nbsp;...&nbsp;r0</td><td>g7&nbsp;...&nbsp;g0</td>
<td>b7&nbsp;...&nbsp;b0</td><td>a7&nbsp;...&nbsp;a0</td></tr>
<tr><td>VBI_PIXFMT_BGRA32_LE VBI_PIXFMT_ARGB32_BE</td>
<td>b7&nbsp;...&nbsp;b0</td><td>g7&nbsp;...&nbsp;g0</td>
<td>r7&nbsp;...&nbsp;r0</td><td>a7&nbsp;...&nbsp;a0</td></tr>
<tr><td>VBI_PIXFMT_ARGB32_LE VBI_PIXFMT_BGRA32_BE</td>
<td>a7&nbsp;...&nbsp;a0</td><td>r7&nbsp;...&nbsp;r0</td>
<td>g7&nbsp;...&nbsp;g0</td><td>b7&nbsp;...&nbsp;b0</td></tr>
<tr><td>VBI_PIXFMT_ABGR32_LE VBI_PIXFMT_RGBA32_BE</td>
<td>a7&nbsp;...&nbsp;a0</td><td>b7&nbsp;...&nbsp;b0</td>
<td>g7&nbsp;...&nbsp;g0</td><td>r7&nbsp;...&nbsp;r0</td></tr>
<tr><td colspan=5>Packed 24 bit RGB data.</td></tr>
<tr><td>VBI_PIXFMT_RGBA24</td>
<td>r7&nbsp;...&nbsp;r0</td><td>g7&nbsp;...&nbsp;g0</td>
<td>b7&nbsp;...&nbsp;b0</td><td>&nbsp;</td></tr>
<tr><td>VBI_PIXFMT_BGRA24</td>
<td>b7&nbsp;...&nbsp;b0</td><td>g7&nbsp;...&nbsp;g0</td>
<td>r7&nbsp;...&nbsp;r0</td><td>&nbsp;</td></tr>
<tr><td colspan=5>Packed 16 bit RGB data.</td></tr>
<tr><td>VBI_PIXFMT_RGB16_LE</td>
<td>g2&nbsp;g1&nbsp;g0&nbsp;r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0</td>
<td>b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0&nbsp;g5&nbsp;g4&nbsp;g3</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_BGR16_LE</td>
<td>g2&nbsp;g1&nbsp;g0&nbsp;b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0</td>
<td>r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0&nbsp;g5&nbsp;g4&nbsp;g3</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_RGB16_BE</td>
<td>b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0&nbsp;g5&nbsp;g4&nbsp;g3</td>
<td>g2&nbsp;g1&nbsp;g0&nbsp;r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_BGR16_BE</td>
<td>r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0&nbsp;g5&nbsp;g4&nbsp;g3</td>
<td>g2&nbsp;g1&nbsp;g0&nbsp;b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0</td>
<td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td colspan=5>Packed 15 bit RGB data.</td></tr>
<tr><td>VBI_PIXFMT_RGBA15_LE</td>
<td>g2&nbsp;g1&nbsp;g0&nbsp;r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0</td>
<td>a0&nbsp;b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0&nbsp;g4&nbsp;g3</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_BGRA15_LE</td>
<td>g2&nbsp;g1&nbsp;g0&nbsp;b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0</td>
<td>a0&nbsp;r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0&nbsp;g4&nbsp;g3</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_ARGB15_LE</td>
<td>g1&nbsp;g0&nbsp;r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0&nbsp;a0</td>
<td>b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0&nbsp;g4&nbsp;g3&nbsp;g2</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_ABGR15_LE</td>
<td>g1&nbsp;g0&nbsp;b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0&nbsp;a0</td>
<td>r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0&nbsp;g4&nbsp;g3&nbsp;g2</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_RGBA15_BE</td>
<td>a0&nbsp;b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0&nbsp;g4&nbsp;g3</td>
<td>g2&nbsp;g1&nbsp;g0&nbsp;r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_BGRA15_BE</td>
<td>a0&nbsp;r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0&nbsp;g4&nbsp;g3</td>
<td>g2&nbsp;g1&nbsp;g0&nbsp;b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_ARGB15_BE</td>
<td>b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0&nbsp;g4&nbsp;g3&nbsp;g2</td>
<td>g1&nbsp;g0&nbsp;r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0&nbsp;a0</td>
<td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>VBI_PIXFMT_ABGR15_BE</td>
<td>r4&nbsp;r3&nbsp;r2&nbsp;r1&nbsp;r0&nbsp;g4&nbsp;g3&nbsp;g2</td>
<td>g1&nbsp;g0&nbsp;b4&nbsp;b3&nbsp;b2&nbsp;b1&nbsp;b0&nbsp;a0</td>
<td>&nbsp;</td><td>&nbsp;</td></tr>
</table>
@endhtmlonly */
/* Attn: keep this in sync with rte, don't change order */
typedef enum {
VBI_PIXFMT_YUV420 = 1,
VBI_PIXFMT_YUYV,
VBI_PIXFMT_YVYU,
VBI_PIXFMT_UYVY,
VBI_PIXFMT_VYUY,
VBI_PIXFMT_PAL8,
VBI_PIXFMT_RGBA32_LE = 32,
VBI_PIXFMT_RGBA32_BE,
VBI_PIXFMT_BGRA32_LE,
VBI_PIXFMT_BGRA32_BE,
VBI_PIXFMT_ABGR32_BE = 32, /* synonyms */
VBI_PIXFMT_ABGR32_LE,
VBI_PIXFMT_ARGB32_BE,
VBI_PIXFMT_ARGB32_LE,
VBI_PIXFMT_RGB24,
VBI_PIXFMT_BGR24,
VBI_PIXFMT_RGB16_LE,
VBI_PIXFMT_RGB16_BE,
VBI_PIXFMT_BGR16_LE,
VBI_PIXFMT_BGR16_BE,
VBI_PIXFMT_RGBA15_LE,
VBI_PIXFMT_RGBA15_BE,
VBI_PIXFMT_BGRA15_LE,
VBI_PIXFMT_BGRA15_BE,
VBI_PIXFMT_ARGB15_LE,
VBI_PIXFMT_ARGB15_BE,
VBI_PIXFMT_ABGR15_LE,
VBI_PIXFMT_ABGR15_BE
} vbi_pixfmt;
/* Private */
typedef uint64_t vbi_pixfmt_set;
#define VBI_MAX_PIXFMTS 64
#define VBI_PIXFMT_SET(pixfmt) (((vbi_pixfmt_set) 1) << (pixfmt))
#define VBI_PIXFMT_SET_YUV (VBI_PIXFMT_SET (VBI_PIXFMT_YUV420) | \
VBI_PIXFMT_SET (VBI_PIXFMT_YUYV) | \
VBI_PIXFMT_SET (VBI_PIXFMT_YVYU) | \
VBI_PIXFMT_SET (VBI_PIXFMT_UYVY) | \
VBI_PIXFMT_SET (VBI_PIXFMT_VYUY))
#define VBI_PIXFMT_SET_RGB (VBI_PIXFMT_SET (VBI_PIXFMT_RGBA32_LE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_RGBA32_BE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_BGRA32_LE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_BGRA32_BE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_RGB24) | \
VBI_PIXFMT_SET (VBI_PIXFMT_BGR24) | \
VBI_PIXFMT_SET (VBI_PIXFMT_RGB16_LE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_RGB16_BE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_BGR16_LE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_BGR16_BE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_RGBA15_LE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_RGBA15_BE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_BGRA15_LE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_BGRA15_BE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_ARGB15_LE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_ARGB15_BE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_ABGR15_LE) | \
VBI_PIXFMT_SET (VBI_PIXFMT_ABGR15_BE))
#define VBI_PIXFMT_SET_ALL (VBI_PIXFMT_SET_YUV | \
VBI_PIXFMT_SET_RGB)
#define VBI_PIXFMT_BPP(fmt) \
(((fmt) == VBI_PIXFMT_YUV420) ? 1 : \
(((fmt) >= VBI_PIXFMT_RGBA32_LE \
&& (fmt) <= VBI_PIXFMT_BGRA32_BE) ? 4 : \
(((fmt) == VBI_PIXFMT_RGB24 \
|| (fmt) == VBI_PIXFMT_BGR24) ? 3 : 2)))
/* Public */
/**
* @ingroup Rawdec
* @brief Modulation used for VBI data transmission.
*/
typedef enum {
/**
* The data is 'non-return to zero' coded, logical '1' bits
* are described by high sample values, logical '0' bits by
* low values. The data is last significant bit first transmitted.
*/
VBI_MODULATION_NRZ_LSB,
/**
* 'Non-return to zero' coded, most significant bit first
* transmitted.
*/
VBI_MODULATION_NRZ_MSB,
/**
* The data is 'bi-phase' coded. Each data bit is described
* by two complementary signalling elements, a logical '1'
* by a sequence of '10' elements, a logical '0' by a '01'
* sequence. The data is last significant bit first transmitted.
*/
VBI_MODULATION_BIPHASE_LSB,
/**
* 'Bi-phase' coded, most significant bit first transmitted.
*/
VBI_MODULATION_BIPHASE_MSB
} vbi_modulation;
/**
* @ingroup Rawdec
* @brief Bit slicer context.
*
* The contents of this structure are private,
* use vbi_bit_slicer_init() to initialize.
*/
typedef struct vbi_bit_slicer {
vbi_bool (* func)(struct vbi_bit_slicer *slicer,
uint8_t *raw, uint8_t *buf);
unsigned int cri;
unsigned int cri_mask;
int thresh;
int cri_bytes;
int cri_rate;
int oversampling_rate;
int phase_shift;
int step;
unsigned int frc;
int frc_bits;
int payload;
int endian;
int skip;
} vbi_bit_slicer;
/**
* @addtogroup Rawdec
* @{
*/
extern 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);
/**
* @param slicer Pointer to initialized vbi_bit_slicer object.
* @param raw Input data. At least the number of pixels or samples
* given as @a raw_samples to vbi_bit_slicer_init().
* @param buf Output data. The buffer must be large enough to store
* the number of bits given as @a payload to vbi_bit_slicer_init().
*
* Decode one scan line of raw vbi data. Note the bit slicer tries
* to adapt to the average signal amplitude, you should avoid
* using the same vbi_bit_slicer object for data from different
* devices.
*
* @note As a matter of speed this function does not lock the
* @a slicer. When you want to share a vbi_bit_slicer object between
* multiple threads you must implement your own locking mechanism.
*
* @return
* @c FALSE if the raw data does not contain the expected
* information, i. e. the CRI/FRC has not been found. This may also
* result from a too weak or noisy signal. Error correction must be
* implemented at a higher layer.
*/
_vbi_inline vbi_bool
vbi_bit_slice(vbi_bit_slicer *slicer, uint8_t *raw, uint8_t *buf)
{
return slicer->func(slicer, raw, buf);
}
/** @} */
/**
* @ingroup Rawdec
* @brief Raw vbi decoder context.
*
* Only the sampling parameters are public. See
* vbi_raw_decoder_parameters() and vbi_raw_decoder_add_services()
* for usage.
*/
typedef struct vbi_raw_decoder {
/* Sampling parameters */
/**
* Either 525 (M/NTSC, M/PAL) or 625 (PAL, SECAM), describing the
* scan line system all line numbers refer to.
*/
int scanning;
/**
* Format of the raw vbi data.
*/
vbi_pixfmt sampling_format;
/**
* Sampling rate in Hz, the number of samples or pixels
* captured per second.
*/
int sampling_rate; /* Hz */
/**
* Number of samples or pixels captured per scan line,
* in bytes. This determines the raw vbi image width and you
* want it large enough to cover all data transmitted in the line (with
* headroom).
*/
int bytes_per_line;
/**
* The distance from 0H (leading edge hsync, half amplitude point)
* to the first sample (pixel) captured, in samples (pixels). You want
* an offset small enough not to miss the start of the data
* transmitted.
*/
int offset; /* 0H, samples */
/**
* First scan line to be captured, first and second field
* respectively, according to the ITU-R line numbering scheme
* (see vbi_sliced). Set to zero if the exact line number isn't
* known.
*/
int start[2]; /* ITU-R numbering */
/**
* Number of scan lines captured, first and second
* field respectively. This can be zero if only data from one
* field is required. The sum @a count[0] + @a count[1] determines the
* raw vbi image height.
*/
int count[2]; /* field lines */
/**
* In the raw vbi image, normally all lines of the second
* field are supposed to follow all lines of the first field. When
* this flag is set, the scan lines of first and second field
* will be interleaved in memory. This implies @a count[0] and @a count[1]
* are equal.
*/
vbi_bool interlaced;
/**
* Fields must be stored in temporal order, i. e. as the
* lines have been captured. It is assumed that the first field is
* also stored first in memory, however if the hardware cannot reliable
* distinguish fields this flag shall be cleared, which disables
* decoding of data services depending on the field number.
*/
vbi_bool synchronous;
/*< private >*/
pthread_mutex_t mutex;
unsigned int services;
int num_jobs;
int8_t * pattern;
struct _vbi_raw_decoder_job {
unsigned int id;
int offset;
vbi_bit_slicer slicer;
} jobs[8];
} vbi_raw_decoder;
/**
* @addtogroup Rawdec
* @{
*/
extern void vbi_raw_decoder_init(vbi_raw_decoder *rd);
extern void vbi_raw_decoder_reset(vbi_raw_decoder *rd);
extern void vbi_raw_decoder_destroy(vbi_raw_decoder *rd);
extern unsigned int vbi_raw_decoder_add_services(vbi_raw_decoder *rd,
unsigned int services,
int strict);
extern unsigned int vbi_raw_decoder_check_services(vbi_raw_decoder *rd,
unsigned int services, int strict);
extern unsigned int vbi_raw_decoder_remove_services(vbi_raw_decoder *rd,
unsigned int services);
extern void vbi_raw_decoder_resize( vbi_raw_decoder *rd,
int * start, unsigned int * count );
extern unsigned int vbi_raw_decoder_parameters(vbi_raw_decoder *rd, unsigned int services,
int scanning, int *max_rate);
extern int vbi_raw_decode(vbi_raw_decoder *rd, uint8_t *raw, vbi_sliced *out);
/** @} */
/* Private */
#endif /* DECODER_H */
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

168
ext/closedcaption/macros.h Normal file
View file

@ -0,0 +1,168 @@
/*
* libzvbi -- Useful macros
*
* Copyright (C) 2002, 2003, 2004, 2007 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: macros.h,v 1.12 2013-07-10 23:11:18 mschimek Exp $ */
#ifndef __ZVBI_MACROS_H__
#define __ZVBI_MACROS_H__
#ifdef __cplusplus
# define VBI_BEGIN_DECLS extern "C" {
# define VBI_END_DECLS }
#else
# define VBI_BEGIN_DECLS
# define VBI_END_DECLS
#endif
VBI_BEGIN_DECLS
/* Public */
#if __GNUC__ >= 4
# define _vbi_sentinel __attribute__ ((__sentinel__(0)))
# define _vbi_deprecated __attribute__ ((__deprecated__))
#else
# define _vbi_sentinel
# define _vbi_deprecated
# define __restrict__
#endif
#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ >= 4
# define _vbi_nonnull(params) __attribute__ ((__nonnull__ params))
# define _vbi_format(params) __attribute__ ((__format__ params))
#else
# define _vbi_nonnull(params)
# define _vbi_format(params)
#endif
#if __GNUC__ >= 3
# define _vbi_pure __attribute__ ((__pure__))
# define _vbi_alloc __attribute__ ((__malloc__))
#else
# define _vbi_pure
# define _vbi_alloc
#endif
#if __GNUC__ >= 2
# define _vbi_unused __attribute__ ((__unused__))
# define _vbi_const __attribute__ ((__const__))
# define _vbi_inline static __inline__
#else
# define _vbi_unused
# define _vbi_const
# define _vbi_inline static
#endif
/**
* @ingroup Basic
* @name Boolean type
* @{
*/
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
typedef int vbi_bool;
/** @} */
#ifndef NULL
# ifdef __cplusplus
# define NULL (0L)
# else
# define NULL ((void *) 0)
# endif
#endif
/* XXX Document me - for variadic funcs. */
#define VBI_END ((void *) 0)
#if 0
typedef void
vbi_lock_fn (void * user_data);
typedef void
vbi_unlock_fn (void * user_data);
#endif
/**
* @ingroup Basic
* @{
*/
typedef enum {
/** External error causes, for example lack of memory. */
VBI_LOG_ERROR = 1 << 3,
/**
* Invalid parameters and similar problems which suggest
* a bug in the application using the library.
*/
VBI_LOG_WARNING = 1 << 4,
/**
* Causes of possibly undesired results, for example when a
* data service cannot be decoded with the current video
* standard setting.
*/
VBI_LOG_NOTICE = 1 << 5,
/** Progress messages. */
VBI_LOG_INFO = 1 << 6,
/** Information useful to debug the library. */
VBI_LOG_DEBUG = 1 << 7,
/** Driver responses (strace). Not implemented yet. */
VBI_LOG_DRIVER = 1 << 8,
/** More detailed debugging information. */
VBI_LOG_DEBUG2 = 1 << 9,
VBI_LOG_DEBUG3 = 1 << 10
} vbi_log_mask;
typedef void
vbi_log_fn (vbi_log_mask level,
const char * context,
const char * message,
void * user_data);
extern vbi_log_fn vbi_log_on_stderr;
/** @} */
/* Private */
typedef struct {
vbi_log_fn * fn;
void * user_data;
vbi_log_mask mask;
} _vbi_log_hook;
VBI_END_DECLS
#endif /* __ZVBI_MACROS_H__ */
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

525
ext/closedcaption/misc.h Normal file
View file

@ -0,0 +1,525 @@
/*
* libzvbi -- Miscellaneous cows and chickens
*
* Copyright (C) 2000-2003 Iñaki García Etxebarria
* Copyright (C) 2002-2007 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: misc.h,v 1.24 2013-07-02 02:32:31 mschimek Exp $ */
#ifndef MISC_H
#define MISC_H
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <inttypes.h> /* (u)intXX_t */
#include <sys/types.h> /* (s)size_t */
#include <float.h> /* DBL_MAX */
#include <limits.h> /* (S)SIZE_MAX */
#include <assert.h>
#include <glib.h>
#include <gst/gst.h>
#include "macros.h"
#define N_ELEMENTS(array) (sizeof (array) / sizeof (*(array)))
#ifdef __GNUC__
#if __GNUC__ < 3
/* Expect expression usually true/false, schedule accordingly. */
# define likely(expr) (expr)
# define unlikely(expr) (expr)
#else
# define likely(expr) __builtin_expect(expr, 1)
# define unlikely(expr) __builtin_expect(expr, 0)
#endif
#undef __i386__
#undef __i686__
/* FIXME #cpu is deprecated
#if #cpu (i386)
# define __i386__ 1
#endif
#if #cpu (i686)
# define __i686__ 1
#endif
*/
/* &x == PARENT (&x.tm_min, struct tm, tm_min),
safer than &x == (struct tm *) &x.tm_min. A NULL _ptr is safe and
will return NULL, not -offsetof(_member). */
#undef PARENT
#define PARENT(_ptr, _type, _member) ({ \
__typeof__ (&((_type *) 0)->_member) _p = (_ptr); \
(_p != 0) ? (_type *)(((char *) _p) - offsetof (_type, \
_member)) : (_type *) 0; \
})
/* Like PARENT(), to be used with const _ptr. */
#define CONST_PARENT(_ptr, _type, _member) ({ \
__typeof__ (&((const _type *) 0)->_member) _p = (_ptr); \
(_p != 0) ? (const _type *)(((const char *) _p) - offsetof \
(const _type, _member)) : (const _type *) 0; \
})
/* Note the following macros have no side effects only when you
compile with GCC, so don't expect this. */
/* Absolute value of int, long or long long without a branch.
Note ABS (INT_MIN) -> INT_MAX + 1. */
#undef ABS
#define ABS(n) ({ \
register __typeof__ (n) _n = (n), _t = _n; \
if (-1 == (-1 >> 1)) { /* do we have signed shifts? */ \
_t >>= sizeof (_t) * 8 - 1; \
_n ^= _t; \
_n -= _t; \
} else if (_n < 0) { /* also warns if n is unsigned type */ \
_n = -_n; \
} \
/* return */ _n; \
})
#undef MIN
#define MIN(x, y) ({ \
__typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
(void)(&_x == &_y); /* warn if types do not match */ \
/* return */ (_x < _y) ? _x : _y; \
})
#undef MAX
#define MAX(x, y) ({ \
__typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
(void)(&_x == &_y); /* warn if types do not match */ \
/* return */ (_x > _y) ? _x : _y; \
})
/* Note other compilers may swap only int, long or pointer. */
#undef SWAP
#define SWAP(x, y) \
do { \
__typeof__ (x) _x = x; \
x = y; \
y = _x; \
} while (0)
#undef SATURATE
#ifdef __i686__ /* has conditional move */
#define SATURATE(n, min, max) ({ \
__typeof__ (n) _n = (n); \
__typeof__ (n) _min = (min); \
__typeof__ (n) _max = (max); \
(void)(&_n == &_min); /* warn if types do not match */ \
(void)(&_n == &_max); \
if (_n < _min) \
_n = _min; \
if (_n > _max) \
_n = _max; \
/* return */ _n; \
})
#else
#define SATURATE(n, min, max) ({ \
__typeof__ (n) _n = (n); \
__typeof__ (n) _min = (min); \
__typeof__ (n) _max = (max); \
(void)(&_n == &_min); /* warn if types do not match */ \
(void)(&_n == &_max); \
if (_n < _min) \
_n = _min; \
else if (_n > _max) \
_n = _max; \
/* return */ _n; \
})
#endif
#else /* !__GNUC__ */
#define likely(expr) (expr)
#define unlikely(expr) (expr)
#undef __i386__
#undef __i686__
static char *
PARENT_HELPER (char *p, unsigned int offset)
{ return (0 == p) ? ((char *) 0) : p - offset; }
static const char *
CONST_PARENT_HELPER (const char *p, unsigned int offset)
{ return (0 == p) ? ((char *) 0) : p - offset; }
#define PARENT(_ptr, _type, _member) \
((0 == offsetof (_type, _member)) ? (_type *)(_ptr) \
: (_type *) PARENT_HELPER ((char *)(_ptr), offsetof (_type, _member)))
#define CONST_PARENT(_ptr, _type, _member) \
((0 == offsetof (const _type, _member)) ? (const _type *)(_ptr) \
: (const _type *) CONST_PARENT_HELPER ((const char *)(_ptr), \
offsetof (const _type, _member)))
#undef ABS
#define ABS(n) (((n) < 0) ? -(n) : (n))
#undef MIN
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#undef MAX
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#undef SWAP
#define SWAP(x, y) \
do { \
long _x = x; \
x = y; \
y = _x; \
} while (0)
#undef SATURATE
#define SATURATE(n, min, max) MIN (MAX (min, n), max)
#endif /* !__GNUC__ */
/* 32 bit constant byte reverse, e.g. 0xAABBCCDD -> 0xDDCCBBAA. */
#define SWAB32(m) \
(+ (((m) & 0xFF000000) >> 24) \
+ (((m) & 0xFF0000) >> 8) \
+ (((m) & 0xFF00) << 8) \
+ (((m) & 0xFF) << 24))
#ifdef HAVE_BUILTIN_POPCOUNT
# define popcnt(x) __builtin_popcount ((uint32_t)(x))
#else
# define popcnt(x) _vbi_popcnt (x)
#endif
extern unsigned int
_vbi_popcnt (uint32_t x);
/* NB GCC inlines and optimizes these functions when size is const. */
#define SET(var) memset (&(var), ~0, sizeof (var))
#define CLEAR(var) memset (&(var), 0, sizeof (var))
/* Useful to copy arrays, otherwise use assignment. */
#define COPY(d, s) \
(assert (sizeof (d) == sizeof (s)), memcpy (d, s, sizeof (d)))
/* Copy string const into char array. */
#define STRACPY(array, s) \
do { \
/* Complain if s is no string const or won't fit. */ \
const char t_[sizeof (array) - 1] _vbi_unused = s; \
\
memcpy (array, s, sizeof (s)); \
} while (0)
/* Copy bits through mask. */
#define COPY_SET_MASK(dest, from, mask) \
(dest ^= (from) ^ (dest & (mask)))
/* Set bits if cond is TRUE, clear if FALSE. */
#define COPY_SET_COND(dest, bits, cond) \
((cond) ? (dest |= (bits)) : (dest &= ~(bits)))
/* Set and clear bits. */
#define COPY_SET_CLEAR(dest, set, clear) \
(dest = (dest & ~(clear)) | (set))
/* For applications, debugging and fault injection during unit tests. */
#define vbi_malloc malloc
#define vbi_realloc realloc
#define vbi_strdup strdup
#define vbi_free free
#define vbi_cache_malloc vbi_malloc
#define vbi_cache_free vbi_free
/* Helper functions. */
_vbi_inline int
_vbi_to_ascii (int c)
{
if (c < 0)
return '?';
c &= 0x7F;
if (c < 0x20 || c >= 0x7F)
return '.';
return c;
}
typedef struct {
const char * key;
int value;
} _vbi_key_value_pair;
extern vbi_bool
_vbi_keyword_lookup (int * value,
const char ** inout_s,
const _vbi_key_value_pair * table,
unsigned int n_pairs)
_vbi_nonnull ((1, 2, 3));
extern void
_vbi_shrink_vector_capacity (void ** vector,
size_t * capacity,
size_t min_capacity,
size_t element_size)
_vbi_nonnull ((1, 2));
extern vbi_bool
_vbi_grow_vector_capacity (void ** vector,
size_t * capacity,
size_t min_capacity,
size_t element_size)
_vbi_nonnull ((1, 2));
/* Logging stuff. */
#ifdef G_HAVE_ISO_VARARGS
#define VBI_CAT_LEVEL_LOG(cat,level,object,...) G_STMT_START{ \
if (G_UNLIKELY ((level) <= GST_LEVEL_MAX && (level) <= _gst_debug_min)) { \
gst_debug_log ((cat), (level), __FILE__, GST_FUNCTION, __LINE__, \
(GObject *) (object), __VA_ARGS__); \
} \
}G_STMT_END
#else /* G_HAVE_GNUC_VARARGS */
#ifdef G_HAVE_GNUC_VARARGS
#define VBI_CAT_LEVEL_LOG(cat,level,object,args...) G_STMT_START{ \
if (G_UNLIKELY ((level) <= GST_LEVEL_MAX && (level) <= _gst_debug_min)) { \
gst_debug_log ((cat), (level), __FILE__, GST_FUNCTION, __LINE__, \
(GObject *) (object), ##args ); \
} \
}G_STMT_END
#else /* no variadic macros, use inline */
static inline void
VBI_CAT_LEVEL_LOG_valist (GstDebugCategory * cat,
GstDebugLevel level, gpointer object, const char *format, va_list varargs)
{
if (G_UNLIKELY ((level) <= GST_LEVEL_MAX && (level) <= _gst_debug_min)) {
gst_debug_log_valist (cat, level, "", "", 0, (GObject *) object, format,
varargs);
}
}
static inline void
VBI_CAT_LEVEL_LOG (GstDebugCategory * cat, GstDebugLevel level,
gpointer object, const char *format, ...)
{
va_list varargs;
va_start (varargs, format);
GST_CAT_LEVEL_LOG_valist (cat, level, object, format, varargs);
va_end (varargs);
}
#endif
#endif /* G_HAVE_ISO_VARARGS */
#define error(hook, templ, args...) \
VBI_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_ERROR, NULL, templ , ##args)
#define warning(hook, templ, args...) \
VBI_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_WARNING, NULL, templ , ##args)
#define notice(hook, templ, args...) \
VBI_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_INFO, NULL, templ , ##args)
#define info(hook, templ, args...) \
VBI_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_INFO, NULL, templ , ##args)
#define debug1(hook, templ, args...) \
VBI_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_DEBUG, NULL, templ , ##args)
#define debug2(hook, templ, args...) \
VBI_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_LOG, NULL, templ , ##args)
#define debug3(hook, templ, args...) \
VBI_CAT_LEVEL_LOG (GST_CAT_DEFAULT, GST_LEVEL_TRACE, NULL, templ , ##args)
#if 0 /* Replaced logging with GStreamer logging system */
extern _vbi_log_hook _vbi_global_log;
extern void
_vbi_log_vprintf (vbi_log_fn * log_fn,
void * user_data,
vbi_log_mask level,
const char * source_file,
const char * context,
const char * templ,
va_list ap)
_vbi_nonnull ((1, 4, 5, 6));
extern void
_vbi_log_printf (vbi_log_fn * log_fn,
void * user_data,
vbi_log_mask level,
const char * source_file,
const char * context,
const char * templ,
...)
_vbi_nonnull ((1, 4, 5, 6)) _vbi_format ((printf, 6, 7));
#define _vbi_log(hook, level, templ, args...) \
do { \
_vbi_log_hook *_h = hook; \
\
if ((NULL != _h && 0 != (_h->mask & level)) \
|| (_h = &_vbi_global_log, 0 != (_h->mask & level))) \
_vbi_log_printf (_h->fn, _h->user_data, \
level, __FILE__, __FUNCTION__, \
templ , ##args); \
} while (0)
#define _vbi_vlog(hook, level, templ, ap) \
do { \
_vbi_log_hook *_h = hook; \
\
if ((NULL != _h && 0 != (_h->mask & level)) \
|| (_h = &_vbi_global_log, 0 != (_h->mask & level))) \
_vbi_log_vprintf (_h->fn, _h->user_data, \
level, __FILE__, __FUNCTION__, \
templ, ap); \
} while (0)
#define error(hook, templ, args...) \
_vbi_log (hook, VBI_LOG_ERROR, templ , ##args)
#define warning(hook, templ, args...) \
_vbi_log (hook, VBI_LOG_ERROR, templ , ##args)
#define notice(hook, templ, args...) \
_vbi_log (hook, VBI_LOG_NOTICE, templ , ##args)
#define info(hook, templ, args...) \
_vbi_log (hook, VBI_LOG_INFO, templ , ##args)
#define debug1(hook, templ, args...) \
_vbi_log (hook, VBI_LOG_DEBUG, templ , ##args)
#define debug2(hook, templ, args...) \
_vbi_log (hook, VBI_LOG_DEBUG2, templ , ##args)
#define debug3(hook, templ, args...) \
_vbi_log (hook, VBI_LOG_DEBUG3, templ , ##args)
#endif
/* Portability stuff. */
/* These should be defined in inttypes.h. */
#ifndef PRId64
# define PRId64 "lld"
#endif
#ifndef PRIu64
# define PRIu64 "llu"
#endif
#ifndef PRIx64
# define PRIx64 "llx"
#endif
/* Should be defined in C99 limits.h? */
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
#ifndef TIME_MIN
# define TIME_MIN (_vbi_time_min ())
_vbi_inline time_t
_vbi_time_min (void)
{
const time_t t = (time_t) -1.25;
if (t < -1) {
return (time_t)((sizeof (time_t) > 4) ? DBL_MIN : FLT_MIN);
} else if (t < 0) {
return ((uint64_t) 1) << (sizeof (time_t) * 8 - 1);
} else {
return 0;
}
}
#endif
#ifndef TIME_MAX
# define TIME_MAX (_vbi_time_max ())
_vbi_inline time_t
_vbi_time_max (void)
{
const time_t t = (time_t) -1.25;
if (t < -1) {
return (time_t)((sizeof (time_t) > 4) ? DBL_MAX : FLT_MAX);
} else if (t < 0) {
/* Most likely signed 32 or 64 bit. */
return (((uint64_t) 1) << (sizeof (time_t) * 8 - 1)) - 1;
} else {
return -1;
}
}
#endif
/* __va_copy is a GNU extension. */
#ifndef __va_copy
# define __va_copy(ap1, ap2) do { ap1 = ap2; } while (0)
#endif
/* Use this instead of strncpy(). strlcpy() is a BSD extension. */
#ifndef HAVE_STRLCPY
# define strlcpy _vbi_strlcpy
#endif
#undef strncpy
#define strncpy use_strlcpy_instead
extern size_t
_vbi_strlcpy (char * dst,
const char * src,
size_t size)
_vbi_nonnull ((1, 2));
/* strndup() is a BSD/GNU extension. */
#ifndef HAVE_STRNDUP
# define strndup _vbi_strndup
#endif
extern char *
_vbi_strndup (const char * s,
size_t len)
_vbi_nonnull ((1));
/* vasprintf() is a GNU extension. */
#ifndef HAVE_VASPRINTF
# define vasprintf _vbi_vasprintf
#endif
extern int
_vbi_vasprintf (char ** dstp,
const char * templ,
va_list ap)
_vbi_nonnull ((1, 2));
/* asprintf() is a GNU extension. */
#ifndef HAVE_ASPRINTF
# define asprintf _vbi_asprintf
#endif
extern int
_vbi_asprintf (char ** dstp,
const char * templ,
...)
_vbi_nonnull ((1, 2)) _vbi_format ((printf, 2, 3));
#undef sprintf
#define sprintf use_snprintf_or_asprintf_instead
#endif /* MISC_H */
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,212 @@
/*
* libzvbi -- Raw VBI decoder
*
* Copyright (C) 2000-2004 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: raw_decoder.h,v 1.12 2008-02-19 00:35:21 mschimek Exp $ */
#ifndef __ZVBI_RAW_DECODER_H__
#define __ZVBI_RAW_DECODER_H__
#include <stdio.h>
#include "decoder.h"
#include "sampling_par.h"
#include "bit_slicer.h"
VBI_BEGIN_DECLS
/*
* $ingroup RawDecoder
* $brief Raw VBI decoder.
*
* The contents of this structure are private.
* Call vbi3_raw_decoder_new() to allocate a raw VBI decoder.
*/
typedef struct _vbi3_raw_decoder vbi3_raw_decoder;
/*
* $addtogroup RawDecoder
* ${
*/
extern vbi_bool
vbi3_raw_decoder_sampling_point (vbi3_raw_decoder * rd,
vbi3_bit_slicer_point *point,
unsigned int row,
unsigned int nth_bit);
extern unsigned int
vbi3_raw_decoder_decode (vbi3_raw_decoder * rd,
vbi_sliced * sliced,
unsigned int sliced_lines,
const uint8_t * raw);
extern void
vbi3_raw_decoder_reset (vbi3_raw_decoder * rd);
extern vbi_service_set
vbi3_raw_decoder_services (vbi3_raw_decoder * rd);
extern vbi_service_set
vbi3_raw_decoder_remove_services
(vbi3_raw_decoder * rd,
vbi_service_set services);
extern vbi_service_set
vbi3_raw_decoder_add_services (vbi3_raw_decoder * rd,
vbi_service_set services,
int strict);
extern vbi_bool
vbi3_raw_decoder_debug (vbi3_raw_decoder * rd,
vbi_bool enable);
extern vbi_service_set
vbi3_raw_decoder_set_sampling_par
(vbi3_raw_decoder * rd,
const vbi_sampling_par *sp,
int strict);
extern void
vbi3_raw_decoder_get_sampling_par
(const vbi3_raw_decoder *rd,
vbi_sampling_par * sp);
extern void
vbi3_raw_decoder_set_log_fn (vbi3_raw_decoder * rd,
vbi_log_fn * log_fn,
void * user_data,
vbi_log_mask mask);
extern void
vbi3_raw_decoder_delete (vbi3_raw_decoder * rd);
extern vbi3_raw_decoder *
vbi3_raw_decoder_new (const vbi_sampling_par *sp);
/* $} */
/* Private */
/** @internal */
#define _VBI3_RAW_DECODER_MAX_JOBS 8
/** @internal */
#define _VBI3_RAW_DECODER_MAX_WAYS 8
/** @internal */
typedef struct {
vbi_service_set id;
vbi3_bit_slicer slicer;
} _vbi3_raw_decoder_job;
/** @internal */
typedef struct {
vbi3_bit_slicer_point points[512];
unsigned int n_points;
} _vbi3_raw_decoder_sp_line;
/**
* @internal
* Don't dereference pointers to this structure.
* I guarantee it will change.
*/
struct _vbi3_raw_decoder {
vbi_sampling_par sampling;
vbi_service_set services;
_vbi_log_hook log;
vbi_bool debug;
unsigned int n_jobs;
unsigned int n_sp_lines;
int readjust;
int8_t * pattern; /* n scan lines * MAX_WAYS */
_vbi3_raw_decoder_job jobs[_VBI3_RAW_DECODER_MAX_JOBS];
_vbi3_raw_decoder_sp_line *sp_lines;
};
/** @internal */
typedef enum {
/** Requires field line numbers. */
_VBI_SP_LINE_NUM = (1 << 0),
/** Requires field numbers. */
_VBI_SP_FIELD_NUM = (1 << 1),
} _vbi_service_par_flag;
typedef struct _vbi_service_par _vbi_service_par;
/** @internal */
struct _vbi_service_par {
vbi_service_set id;
const char * label;
/**
* Video standard
* - 525 lines, FV = 59.94 Hz, FH = 15734 Hz
* - 625 lines, FV = 50 Hz, FH = 15625 Hz
*/
vbi_videostd_set videostd_set;
/**
* Most scan lines used by the data service, first and last
* line of first and second field. ITU-R numbering scheme.
* Zero if no data from this field, requires field sync.
*/
unsigned int first[2];
unsigned int last[2];
/**
* Leading edge hsync to leading edge first CRI one bit,
* half amplitude points, in nanoseconds.
*/
unsigned int offset;
unsigned int cri_rate; /**< Hz */
unsigned int bit_rate; /**< Hz */
/** Clock Run In and FRaming Code, LSB last txed bit of FRC. */
unsigned int cri_frc;
/** CRI and FRC bits significant for identification. */
unsigned int cri_frc_mask;
/**
* Number of significat cri_bits (at cri_rate),
* frc_bits (at bit_rate).
*/
unsigned int cri_bits;
unsigned int frc_bits;
unsigned int payload; /**< bits */
vbi_modulation modulation;
_vbi_service_par_flag flags;
};
extern const _vbi_service_par _vbi_service_table [];
extern void
_vbi3_raw_decoder_dump (const vbi3_raw_decoder *rd,
FILE * fp);
extern void
_vbi3_raw_decoder_destroy (vbi3_raw_decoder * rd);
extern vbi_bool
_vbi3_raw_decoder_init (vbi3_raw_decoder * rd,
const vbi_sampling_par *sp);
VBI_END_DECLS
#endif /* __ZVBI_RAW_DECODER_H__ */
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

View file

@ -0,0 +1,551 @@
/*
* libzvbi -- Raw VBI sampling parameters
*
* Copyright (C) 2000-2004 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: sampling_par.c,v 1.12 2013-08-28 14:45:00 mschimek Exp $ */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <errno.h>
#include "misc.h"
#include "raw_decoder.h"
#include "sampling_par.h"
#include "sliced.h"
# define vbi_pixfmt_bytes_per_pixel VBI_PIXFMT_BPP
# define sp_sample_format sampling_format
/**
* @addtogroup Sampling Raw VBI sampling
* @ingroup Raw
* @brief Raw VBI data sampling interface.
*/
/**
* @internal
* Compatibility.
*/
vbi_videostd_set
_vbi_videostd_set_from_scanning (int scanning)
{
switch (scanning) {
case 525:
return VBI_VIDEOSTD_SET_525_60;
case 625:
return VBI_VIDEOSTD_SET_625_50;
default:
break;
}
return 0;
}
_vbi_inline vbi_bool
range_check (unsigned int start,
unsigned int count, unsigned int min, unsigned int max)
{
/* Check bounds and overflow. */
return (start >= min && (start + count) <= max && (start + count) >= start);
}
/**
* @internal
* @param sp Sampling parameters to verify.
*
* @return
* TRUE if the sampling parameters are valid (as far as we can tell).
*/
vbi_bool
_vbi_sampling_par_valid_log (const vbi_sampling_par * sp, _vbi_log_hook * log)
{
vbi_videostd_set videostd_set;
unsigned int bpp;
assert (NULL != sp);
switch (sp->sp_sample_format) {
case VBI_PIXFMT_YUV420:
/* This conflicts with the ivtv driver, which returns an
odd number of bytes per line. The driver format is
_GREY but libzvbi 0.2 has no VBI_PIXFMT_Y8. */
break;
default:
bpp = vbi_pixfmt_bytes_per_pixel (sp->sp_sample_format);
if (0 != (sp->bytes_per_line % bpp))
goto bad_samples;
break;
}
if (0 == sp->bytes_per_line)
goto no_samples;
if (0 == sp->count[0]
&& 0 == sp->count[1])
goto bad_range;
videostd_set = _vbi_videostd_set_from_scanning (sp->scanning);
if (VBI_VIDEOSTD_SET_525_60 & videostd_set) {
if (VBI_VIDEOSTD_SET_625_50 & videostd_set)
goto ambiguous;
if (0 != sp->start[0]
&& !range_check (sp->start[0], sp->count[0], 1, 262))
goto bad_range;
if (0 != sp->start[1]
&& !range_check (sp->start[1], sp->count[1], 263, 525))
goto bad_range;
} else if (VBI_VIDEOSTD_SET_625_50 & videostd_set) {
if (0 != sp->start[0]
&& !range_check (sp->start[0], sp->count[0], 1, 311))
goto bad_range;
if (0 != sp->start[1]
&& !range_check (sp->start[1], sp->count[1], 312, 625))
goto bad_range;
} else {
ambiguous:
info (log, "Ambiguous videostd_set 0x%lx.", (unsigned long) videostd_set);
return FALSE;
}
if (sp->interlaced && (sp->count[0] != sp->count[1]
|| 0 == sp->count[0])) {
info (log,
"Line counts %u, %u must be equal and "
"non-zero when raw VBI data is interlaced.",
sp->count[0], sp->count[1]);
return FALSE;
}
return TRUE;
no_samples:
info (log, "samples_per_line is zero.");
return FALSE;
bad_samples:
info (log,
"bytes_per_line value %u is no multiple of "
"the sample size %u.",
sp->bytes_per_line, vbi_pixfmt_bytes_per_pixel (sp->sp_sample_format));
return FALSE;
bad_range:
info (log,
"Invalid VBI scan range %u-%u (%u lines), "
"%u-%u (%u lines).",
sp->start[0], sp->start[0] + sp->count[0] - 1,
sp->count[0],
sp->start[1], sp->start[1] + sp->count[1] - 1, sp->count[1]);
return FALSE;
}
static vbi_bool
_vbi_sampling_par_permit_service
(const vbi_sampling_par * sp,
const _vbi_service_par * par, unsigned int strict, _vbi_log_hook * log)
{
const unsigned int unknown = 0;
double signal;
unsigned int field;
unsigned int samples_per_line;
vbi_videostd_set videostd_set;
assert (NULL != sp);
assert (NULL != par);
videostd_set = _vbi_videostd_set_from_scanning (sp->scanning);
if (0 == (par->videostd_set & videostd_set)) {
info (log,
"Service 0x%08x (%s) requires "
"videostd_set 0x%lx, "
"have 0x%lx.",
par->id, par->label,
(unsigned long) par->videostd_set, (unsigned long) videostd_set);
return FALSE;
}
if (par->flags & _VBI_SP_LINE_NUM) {
if ((par->first[0] > 0 && unknown == (unsigned int) sp->start[0])
|| (par->first[1] > 0 && unknown == (unsigned int) sp->start[1])) {
info (log,
"Service 0x%08x (%s) requires known "
"line numbers.", par->id, par->label);
return FALSE;
}
}
{
unsigned int rate;
rate = MAX (par->cri_rate, par->bit_rate);
switch (par->id) {
case VBI_SLICED_WSS_625:
/* Effective bit rate is just 1/3 max_rate,
so 1 * max_rate should suffice. */
break;
default:
rate = (rate * 3) >> 1;
break;
}
if (rate > (unsigned int) sp->sampling_rate) {
info (log,
"Sampling rate %f MHz too low "
"for service 0x%08x (%s).",
sp->sampling_rate / 1e6, par->id, par->label);
return FALSE;
}
}
signal = par->cri_bits / (double) par->cri_rate
+ (par->frc_bits + par->payload) / (double) par->bit_rate;
samples_per_line = sp->bytes_per_line / VBI_PIXFMT_BPP (sp->sampling_format);
if (0 && sp->offset > 0 && strict > 0) {
double sampling_rate;
double offset;
double end;
sampling_rate = (double) sp->sampling_rate;
offset = sp->offset / sampling_rate;
end = (sp->offset + samples_per_line) / sampling_rate;
if (offset > (par->offset / 1e3 - 0.5e-6)) {
info (log,
"Sampling starts at 0H + %f us, too "
"late for service 0x%08x (%s) at "
"%f us.", offset * 1e6, par->id, par->label, par->offset / 1e3);
return FALSE;
}
if (end < (par->offset / 1e9 + signal + 0.5e-6)) {
info (log,
"Sampling ends too early at 0H + "
"%f us for service 0x%08x (%s) "
"which ends at %f us",
end * 1e6,
par->id, par->label, par->offset / 1e3 + signal * 1e6 + 0.5);
return FALSE;
}
} else {
double samples;
samples = samples_per_line / (double) sp->sampling_rate;
if (strict > 0)
samples -= 1e-6; /* headroom */
if (samples < signal) {
info (log,
"Service 0x%08x (%s) signal length "
"%f us exceeds %f us sampling length.",
par->id, par->label, signal * 1e6, samples * 1e6);
return FALSE;
}
}
if ((par->flags & _VBI_SP_FIELD_NUM)
&& !sp->synchronous) {
info (log,
"Service 0x%08x (%s) requires "
"synchronous field order.", par->id, par->label);
return FALSE;
}
for (field = 0; field < 2; ++field) {
unsigned int start;
unsigned int end;
start = sp->start[field];
end = start + sp->count[field] - 1;
if (0 == par->first[field]
|| 0 == par->last[field]) {
/* No data on this field. */
continue;
}
if (0 == sp->count[field]) {
info (log,
"Service 0x%08x (%s) requires "
"data from field %u", par->id, par->label, field + 1);
return FALSE;
}
/* (int) <= 0 for compatibility with libzvbi 0.2.x */
if ((int) strict <= 0 || 0 == sp->start[field])
continue;
if (1 == strict && par->first[field] > par->last[field]) {
/* May succeed if not all scanning lines
available for the service are actually used. */
continue;
}
if (start > par->first[field]
|| end < par->last[field]) {
info (log,
"Service 0x%08x (%s) requires "
"lines %u-%u, have %u-%u.",
par->id, par->label, par->first[field], par->last[field], start, end);
return FALSE;
}
}
return TRUE;
}
/**
* @internal
*/
vbi_service_set
_vbi_sampling_par_check_services_log
(const vbi_sampling_par * sp,
vbi_service_set services, unsigned int strict, _vbi_log_hook * log) {
const _vbi_service_par *par;
vbi_service_set rservices;
assert (NULL != sp);
rservices = 0;
for (par = _vbi_service_table; par->id; ++par) {
if (0 == (par->id & services))
continue;
if (_vbi_sampling_par_permit_service (sp, par, strict, log))
rservices |= par->id;
}
return rservices;
}
/**
* @internal
*/
vbi_service_set
_vbi_sampling_par_from_services_log
(vbi_sampling_par * sp,
unsigned int *max_rate,
vbi_videostd_set videostd_set_req,
vbi_service_set services, _vbi_log_hook * log) {
const _vbi_service_par *par;
vbi_service_set rservices;
vbi_videostd_set videostd_set;
unsigned int rate;
unsigned int samples_per_line;
assert (NULL != sp);
videostd_set = 0;
if (0 != videostd_set_req) {
if (0 == (VBI_VIDEOSTD_SET_ALL & videostd_set_req)
|| ((VBI_VIDEOSTD_SET_525_60 & videostd_set_req)
&& (VBI_VIDEOSTD_SET_625_50 & videostd_set_req))) {
warning (log,
"Ambiguous videostd_set 0x%lx.", (unsigned long) videostd_set_req);
CLEAR (*sp);
return 0;
}
videostd_set = videostd_set_req;
}
samples_per_line = 0;
sp->sampling_rate = 27000000; /* ITU-R BT.601 */
sp->offset = (int) (64e-6 * sp->sampling_rate);
sp->start[0] = 30000;
sp->count[0] = 0;
sp->start[1] = 30000;
sp->count[1] = 0;
sp->interlaced = FALSE;
sp->synchronous = TRUE;
rservices = 0;
rate = 0;
for (par = _vbi_service_table; par->id; ++par) {
#if 0 /* Set but unused */
double margin;
#endif
double signal;
int offset;
unsigned int samples;
unsigned int i;
if (0 == (par->id & services))
continue;
if (0 == videostd_set_req) {
vbi_videostd_set set;
set = par->videostd_set | videostd_set;
if (0 == (set & ~VBI_VIDEOSTD_SET_525_60)
|| 0 == (set & ~VBI_VIDEOSTD_SET_625_50))
videostd_set |= par->videostd_set;
}
#if 0 /* Set but unused */
if (VBI_VIDEOSTD_SET_525_60 & videostd_set)
margin = 1.0e-6;
else
margin = 2.0e-6;
#endif
if (0 == (par->videostd_set & videostd_set)) {
info (log,
"Service 0x%08x (%s) requires "
"videostd_set 0x%lx, "
"have 0x%lx.",
par->id, par->label,
(unsigned long) par->videostd_set, (unsigned long) videostd_set);
continue;
}
rate = MAX (rate, par->cri_rate);
rate = MAX (rate, par->bit_rate);
signal = par->cri_bits / (double) par->cri_rate
+ ((par->frc_bits + par->payload) / (double) par->bit_rate);
offset = (int) ((par->offset / 1e9) * sp->sampling_rate);
samples = (int) ((signal + 1.0e-6) * sp->sampling_rate);
sp->offset = MIN (sp->offset, offset);
samples_per_line = MAX (samples_per_line + sp->offset,
samples + offset) - sp->offset;
for (i = 0; i < 2; ++i)
if (par->first[i] > 0 && par->last[i] > 0) {
sp->start[i] = MIN
((unsigned int) sp->start[i], (unsigned int) par->first[i]);
sp->count[i] = MAX ((unsigned int) sp->start[i]
+ sp->count[i], (unsigned int) par->last[i] + 1)
- sp->start[i];
}
rservices |= par->id;
}
if (0 == rservices) {
CLEAR (*sp);
return 0;
}
if (0 == sp->count[1]) {
sp->start[1] = 0;
if (0 == sp->count[0]) {
sp->start[0] = 0;
sp->offset = 0;
}
} else if (0 == sp->count[0]) {
sp->start[0] = 0;
}
sp->scanning = (videostd_set & VBI_VIDEOSTD_SET_525_60)
? 525 : 625;
sp->sp_sample_format = VBI_PIXFMT_YUV420;
/* Note bpp is 1. */
sp->bytes_per_line = MAX (1440U, samples_per_line);
if (max_rate)
*max_rate = rate;
return rservices;
}
/**
* @param sp Sampling parameters to check against.
* @param services Set of data services.
* @param strict See description of vbi_raw_decoder_add_services().
*
* Check which of the given services can be decoded with the given
* sampling parameters at the given strictness level.
*
* @return
* Subset of @a services decodable with the given sampling parameters.
*/
vbi_service_set
vbi_sampling_par_check_services
(const vbi_sampling_par * sp,
vbi_service_set services, unsigned int strict) {
return _vbi_sampling_par_check_services_log (sp, services, strict,
/* log_hook */ NULL);
}
/**
* @param sp Sampling parameters calculated by this function
* will be stored here.
* @param max_rate If not NULL, the highest data bit rate in Hz of
* all services requested will be stored here. The sampling rate
* should be at least twice as high; @sp sampling_rate will
* be set to a more reasonable value of 27 MHz, which is twice
* the video sampling rate defined by ITU-R Rec. BT.601.
* @param videostd_set Create sampling parameters matching these
* video standards. When 0 determine video standard from requested
* services.
* @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.
*
* Calculate the sampling parameters required to receive and decode the
* requested data @a services. The @a sp sampling_format will be
* @c VBI_PIXFMT_Y8, offset and bytes_per_line will be set to
* reasonable minimums. This function can be used to initialize hardware
* prior to creating a vbi_raw_decoder object.
*
* @return
* Subset of @a services covered by the calculated sampling parameters.
*/
vbi_service_set
vbi_sampling_par_from_services (vbi_sampling_par * sp,
unsigned int *max_rate,
vbi_videostd_set videostd_set, vbi_service_set services)
{
return _vbi_sampling_par_from_services_log (sp, max_rate,
videostd_set, services,
/* log_hook */ NULL);
}
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

View file

@ -0,0 +1,87 @@
/*
* libzvbi -- Raw VBI sampling parameters
*
* Copyright (C) 2000-2004 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: sampling_par.h,v 1.9 2008-02-24 14:17:06 mschimek Exp $ */
#ifndef __SAMPLING_PAR_H__
#define __SAMPLING_PAR_H__
#include "decoder.h"
VBI_BEGIN_DECLS
/* Public */
typedef vbi_raw_decoder vbi_sampling_par;
#define VBI_VIDEOSTD_SET_EMPTY 0
#define VBI_VIDEOSTD_SET_PAL_BG 1
#define VBI_VIDEOSTD_SET_625_50 1
#define VBI_VIDEOSTD_SET_525_60 2
#define VBI_VIDEOSTD_SET_ALL 3
typedef uint64_t vbi_videostd_set;
/* Private */
extern vbi_service_set
vbi_sampling_par_from_services (vbi_sampling_par * sp,
unsigned int * max_rate,
vbi_videostd_set videostd_set,
vbi_service_set services);
extern vbi_service_set
vbi_sampling_par_check_services
(const vbi_sampling_par *sp,
vbi_service_set services,
unsigned int strict)
_vbi_pure;
extern vbi_videostd_set
_vbi_videostd_set_from_scanning (int scanning);
extern vbi_service_set
_vbi_sampling_par_from_services_log
(vbi_sampling_par * sp,
unsigned int * max_rate,
vbi_videostd_set videostd_set,
vbi_service_set services,
_vbi_log_hook * log);
extern vbi_service_set
_vbi_sampling_par_check_services_log
(const vbi_sampling_par *sp,
vbi_service_set services,
unsigned int strict,
_vbi_log_hook * log)
_vbi_pure;
extern vbi_bool
_vbi_sampling_par_valid_log (const vbi_sampling_par *sp,
_vbi_log_hook * log)
_vbi_pure;
VBI_END_DECLS
#endif /* __SAMPLING_PAR_H__ */
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

367
ext/closedcaption/sliced.h Normal file
View file

@ -0,0 +1,367 @@
/*
* libzvbi -- Sliced VBI data
*
* Copyright (C) 2000, 2001 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: sliced.h,v 1.11 2008-02-24 14:17:02 mschimek Exp $ */
#ifndef SLICED_H
#define SLICED_H
#ifdef __cplusplus
extern "C" {
#endif
/* Public */
#include <inttypes.h>
/**
* @addtogroup Sliced Sliced VBI data
* @ingroup Raw
* @brief Definition of sliced VBI data.
*
* The output of the libzvbi raw VBI decoder, and input to the data
* service decoder, is VBI data in binary format as defined in this
* section. It is similar to the output of hardware VBI decoders
* and VBI data transmitted in digital TV streams.
*/
/**
* @name Data service symbols
* @ingroup Sliced
* @{
*/
/**
* @anchor VBI_SLICED_
* No data service, blank vbi_sliced structure.
*/
#define VBI_SLICED_NONE 0
/**
* Unknown data service (vbi_dvb_demux).
* @since 0.2.10
*/
#define VBI_SLICED_UNKNOWN 0
/**
* Antiope a.k.a. Teletext System A
*
* Reference: <a href="http://www.itu.ch">ITU-R BT.653
* "Teletext Systems"</a>
*
* vbi_sliced payload: Last 37 bytes, without clock run-in and
* framing code, lsb first transmitted.
*
* @since 0.2.10
*/
#define VBI_SLICED_ANTIOPE 0x00002000
/**
* Synonym of VBI_SLICED_ANTIOPE.
* @since 0.2.10
*/
#define VBI_SLICED_TELETEXT_A 0x00002000
#define VBI_SLICED_TELETEXT_B_L10_625 0x00000001
#define VBI_SLICED_TELETEXT_B_L25_625 0x00000002
/**
* Teletext System B for 625 line systems
*
* Note this is separated into Level 1.0 and Level 2.5+ since the latter
* permits occupation of scan line 6 which is frequently out of
* range of raw VBI capture drivers. Clients should request decoding of both,
* may then verify Level 2.5 is covered. vbi_sliced id can be
* VBI_SLICED_TELETEXT_B, _B_L10_625 or _B_L25_625 regardless of line number.
*
* Reference: <a href="http://www.etsi.org">EN 300 706
* "Enhanced Teletext specification"</a>, <a href="http://www.itu.ch">
* ITU-R BT.653 "Teletext Systems"</a>
*
* vbi_sliced payload: Last 42 of the 45 byte Teletext packet, that is
* without clock run-in and framing code, lsb first transmitted.
*/
#define VBI_SLICED_TELETEXT_B (VBI_SLICED_TELETEXT_B_L10_625 | \
VBI_SLICED_TELETEXT_B_L25_625)
/**
* Synonym of VBI_SLICED_TELETEXT_B.
* @since 0.2.10
*/
#define VBI_SLICED_TELETEXT_B_625 VBI_SLICED_TELETEXT_B
/**
* Teletext System C for 625 line systems
*
* Reference: <a href="http://www.itu.ch">ITU-R BT.653
* "Teletext Systems"</a>
*
* vbi_sliced payload: Last 33 bytes, without clock run-in and
* framing code, lsb first transmitted.
*
* @since 0.2.10
*/
#define VBI_SLICED_TELETEXT_C_625 0x00004000
/**
* Teletext System D for 625 line systems
*
* Reference: <a href="http://www.itu.ch">ITU-R BT.653
* "Teletext Systems"</a>
*
* vbi_sliced payload: Last 34 bytes, without clock run-in and
* framing code, lsb first transmitted.
*
* @since 0.2.10
*/
#define VBI_SLICED_TELETEXT_D_625 0x00008000
/**
* Video Program System
*
* Reference: <a href="http://www.etsi.org">ETS 300 231
* "Specification of the domestic video Programme
* Delivery Control system (PDC)"</a>, <a href="http://www.irt.de">
* IRT 8R2 "Video-Programm-System (VPS)"</a>.
*
* vbi_sliced payload: Byte number 3 to 15 according to ETS 300 231
* Figure 9, lsb first transmitted.
*/
#define VBI_SLICED_VPS 0x00000004
/**
* Pseudo-VPS signal transmitted on field 2
*
* vbi_sliced payload: 13 bytes.
*
* @since 0.2.10
*/
#define VBI_SLICED_VPS_F2 0x00001000
#define VBI_SLICED_CAPTION_625_F1 0x00000008
#define VBI_SLICED_CAPTION_625_F2 0x00000010
/**
* Closed Caption for 625 line systems
*
* Note this is split into field one and two services since for basic
* caption decoding only field one is required. vbi_sliced id can be
* VBI_SLICED_CAPTION_625, _625_F1 or _625_F2 regardless of line number.
*
* Reference: <a href="http://global.ihs.com">EIA 608
* "Recommended Practice for Line 21 Data Service"</a>.
*
* vbi_sliced payload: First and second byte including parity,
* lsb first transmitted.
*/
#define VBI_SLICED_CAPTION_625 (VBI_SLICED_CAPTION_625_F1 | \
VBI_SLICED_CAPTION_625_F2)
/**
* Wide Screen Signalling for 625 line systems
*
* Reference: <a href="http://www.etsi.org">EN 300 294
* "625-line television Wide Screen Signalling (WSS)"</a>.
*
* vbi_sliced payload:
* <pre>
* Byte 0 1
* msb lsb msb lsb
* bit 7 6 5 4 3 2 1 0 x x 13 12 11 10 9 8<br></pre>
* according to EN 300 294, Table 1, lsb first transmitted.
*/
#define VBI_SLICED_WSS_625 0x00000400
#define VBI_SLICED_CAPTION_525_F1 0x00000020
#define VBI_SLICED_CAPTION_525_F2 0x00000040
/**
* Closed Caption for 525 line systems (NTSC).
*
* Note this is split into field one and two services since for basic
* caption decoding only field one is required. vbi_sliced id can be
* VBI_SLICED_CAPTION_525, _525_F1 or _525_F2 regardless of line number.
*
* VBI_SLICED_CAPTION_525 also covers XDS (Extended Data Service),
* V-Chip data and ITV / WebTV data.
*
* Reference: <a href="http://global.ihs.com">EIA 608
* "Recommended Practice for Line 21 Data Service"</a>.
*
* vbi_sliced payload: First and second byte including parity,
* lsb first transmitted.
*/
#define VBI_SLICED_CAPTION_525 (VBI_SLICED_CAPTION_525_F1 | \
VBI_SLICED_CAPTION_525_F2)
/**
* Closed Caption at double bit rate for 525 line systems.
*
* Reference: ?
*
* vbi_sliced payload: First to fourth byte including parity bit,
* lsb first transmitted.
*/
#define VBI_SLICED_2xCAPTION_525 0x00000080
/**
* Teletext System B for 525 line systems
*
* Reference: <a href="http://www.itu.ch">ITU-R BT.653
* "Teletext Systems"</a>
*
* vbi_sliced payload: Last 34 bytes, without clock run-in and
* framing code, lsb first transmitted.
*
* @since 0.2.10
*/
#define VBI_SLICED_TELETEXT_B_525 0x00010000
/**
* North American Basic Teletext Specification
* a.k.a. Teletext System C for 525 line systems
*
* Reference: <a href="http://global.ihs.com">EIA-516
* "North American Basic Teletext Specification (NABTS)"</a>,
* <a href="http://www.itu.ch">ITU-R BT.653 "Teletext Systems"</a>
*
* vbi_sliced payload: Last 33 bytes, without clock run-in and
* framing code, lsb first transmitted.
*
* @since 0.2.10
*/
#define VBI_SLICED_NABTS 0x00000100
/**
* Synonym of VBI_SLICED_NABTS.
* @since 0.2.10
*/
#define VBI_SLICED_TELETEXT_C_525 0x00000100
/**
* Misdefined.
*
* vbi_sliced payload: 34 bytes.
*
* @deprecated
* This service was misdefined.
* Use VBI_SLICED_TELETEXT_B_525 or VBI_SLICED_TELETEXT_D_525 in new code.
*/
#define VBI_SLICED_TELETEXT_BD_525 0x00000200
/**
* Teletext System D for 525 line systems
*
* Reference: <a href="http://www.itu.ch">ITU-R BT.653
* "Teletext Systems"</a>
*
* vbi_sliced payload: Last 34 bytes, without clock run-in and
* framing code, lsb first transmitted.
*
* @since 0.2.10
*/
#define VBI_SLICED_TELETEXT_D_525 0x00020000
/**
* Wide Screen Signalling for NTSC Japan
*
* Reference: <a href="http://www.jeita.or.jp">EIA-J CPR-1204</a>
*
* vbi_sliced payload:
* <pre>
* Byte 0 1 2
* msb lsb msb lsb msb lsb
* bit 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 x x x x 19 18 17 16
* </pre>
*/
#define VBI_SLICED_WSS_CPR1204 0x00000800
/**
* No actual data service. This symbol is used to request capturing
* of all PAL/SECAM VBI data lines from the libzvbi driver interface,
* as opposed to just those lines used to transmit the requested
* data services.
*/
#define VBI_SLICED_VBI_625 0x20000000
/**
* No actual data service. This symbol is used to request capturing
* of all NTSC VBI data lines from the libzvbi driver interface,
* as opposed to just those lines used to transmit the requested
* data services.
*/
#define VBI_SLICED_VBI_525 0x40000000
/** @} */
typedef unsigned int vbi_service_set;
/**
* @ingroup Sliced
* @brief This structure holds one scan line of sliced vbi data.
*
* For example the contents of NTSC line 21, two bytes of Closed Caption
* data. Usually an array of vbi_sliced is used, covering all
* VBI lines of the two fields of a video frame.
*/
typedef struct {
/**
* A @ref VBI_SLICED_ symbol identifying the data service. Under cirumstances
* (see VBI_SLICED_TELETEXT_B) this can be a set of VBI_SLICED_ symbols.
*/
uint32_t id;
/**
* Source line number according to the ITU-R line numbering scheme,
* a value of @c 0 if the exact line number is unknown. Note that some
* data services cannot be reliable decoded without line number.
*
* @image html zvbi_625.gif "ITU-R PAL/SECAM line numbering scheme"
* @image html zvbi_525.gif "ITU-R NTSC line numbering scheme"
*/
uint32_t line;
/**
* The actual payload. See the documentation of @ref VBI_SLICED_ symbols
* for details.
*/
uint8_t data[56];
} vbi_sliced;
/**
* @addtogroup Sliced
* @{
*/
extern const char *
vbi_sliced_name (vbi_service_set service)
_vbi_const;
extern unsigned int
vbi_sliced_payload_bits (vbi_service_set service)
_vbi_const;
/** @} */
/* Private */
#ifdef __cplusplus
}
#endif
#endif /* SLICED_H */
/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/