mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
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:
parent
483892d16a
commit
b0b02e7cb5
13 changed files with 5893 additions and 1 deletions
|
@ -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
223
ext/closedcaption/bcd.h
Normal 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 0000 ... 0x0999 9999, that
|
||||
* is -10**7 ... +10**7 - 1 in decimal notation. To subtract you can
|
||||
* add the 10's complement, e. g. -1 = 0xF999 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 0000 ... 0x0999 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:
|
||||
*/
|
1017
ext/closedcaption/bit_slicer.c
Normal file
1017
ext/closedcaption/bit_slicer.c
Normal file
File diff suppressed because it is too large
Load diff
197
ext/closedcaption/bit_slicer.h
Normal file
197
ext/closedcaption/bit_slicer.h
Normal 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
832
ext/closedcaption/decoder.c
Normal 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
415
ext/closedcaption/decoder.h
Normal 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 0</th><th>Byte 1</th><th>Byte 2</th><th>Byte 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 ... r0</td><td>g7 ... g0</td>
|
||||
<td>b7 ... b0</td><td>a7 ... a0</td></tr>
|
||||
<tr><td>VBI_PIXFMT_BGRA32_LE VBI_PIXFMT_ARGB32_BE</td>
|
||||
<td>b7 ... b0</td><td>g7 ... g0</td>
|
||||
<td>r7 ... r0</td><td>a7 ... a0</td></tr>
|
||||
<tr><td>VBI_PIXFMT_ARGB32_LE VBI_PIXFMT_BGRA32_BE</td>
|
||||
<td>a7 ... a0</td><td>r7 ... r0</td>
|
||||
<td>g7 ... g0</td><td>b7 ... b0</td></tr>
|
||||
<tr><td>VBI_PIXFMT_ABGR32_LE VBI_PIXFMT_RGBA32_BE</td>
|
||||
<td>a7 ... a0</td><td>b7 ... b0</td>
|
||||
<td>g7 ... g0</td><td>r7 ... r0</td></tr>
|
||||
<tr><td colspan=5>Packed 24 bit RGB data.</td></tr>
|
||||
<tr><td>VBI_PIXFMT_RGBA24</td>
|
||||
<td>r7 ... r0</td><td>g7 ... g0</td>
|
||||
<td>b7 ... b0</td><td> </td></tr>
|
||||
<tr><td>VBI_PIXFMT_BGRA24</td>
|
||||
<td>b7 ... b0</td><td>g7 ... g0</td>
|
||||
<td>r7 ... r0</td><td> </td></tr>
|
||||
<tr><td colspan=5>Packed 16 bit RGB data.</td></tr>
|
||||
<tr><td>VBI_PIXFMT_RGB16_LE</td>
|
||||
<td>g2 g1 g0 r4 r3 r2 r1 r0</td>
|
||||
<td>b4 b3 b2 b1 b0 g5 g4 g3</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_BGR16_LE</td>
|
||||
<td>g2 g1 g0 b4 b3 b2 b1 b0</td>
|
||||
<td>r4 r3 r2 r1 r0 g5 g4 g3</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_RGB16_BE</td>
|
||||
<td>b4 b3 b2 b1 b0 g5 g4 g3</td>
|
||||
<td>g2 g1 g0 r4 r3 r2 r1 r0</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_BGR16_BE</td>
|
||||
<td>r4 r3 r2 r1 r0 g5 g4 g3</td>
|
||||
<td>g2 g1 g0 b4 b3 b2 b1 b0</td>
|
||||
<td> </td><td> </td></tr>
|
||||
<tr><td colspan=5>Packed 15 bit RGB data.</td></tr>
|
||||
<tr><td>VBI_PIXFMT_RGBA15_LE</td>
|
||||
<td>g2 g1 g0 r4 r3 r2 r1 r0</td>
|
||||
<td>a0 b4 b3 b2 b1 b0 g4 g3</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_BGRA15_LE</td>
|
||||
<td>g2 g1 g0 b4 b3 b2 b1 b0</td>
|
||||
<td>a0 r4 r3 r2 r1 r0 g4 g3</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_ARGB15_LE</td>
|
||||
<td>g1 g0 r4 r3 r2 r1 r0 a0</td>
|
||||
<td>b4 b3 b2 b1 b0 g4 g3 g2</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_ABGR15_LE</td>
|
||||
<td>g1 g0 b4 b3 b2 b1 b0 a0</td>
|
||||
<td>r4 r3 r2 r1 r0 g4 g3 g2</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_RGBA15_BE</td>
|
||||
<td>a0 b4 b3 b2 b1 b0 g4 g3</td>
|
||||
<td>g2 g1 g0 r4 r3 r2 r1 r0</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_BGRA15_BE</td>
|
||||
<td>a0 r4 r3 r2 r1 r0 g4 g3</td>
|
||||
<td>g2 g1 g0 b4 b3 b2 b1 b0</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_ARGB15_BE</td>
|
||||
<td>b4 b3 b2 b1 b0 g4 g3 g2</td>
|
||||
<td>g1 g0 r4 r3 r2 r1 r0 a0</td>
|
||||
<td> </td><td> </td></tr><tr><td>VBI_PIXFMT_ABGR15_BE</td>
|
||||
<td>r4 r3 r2 r1 r0 g4 g3 g2</td>
|
||||
<td>g1 g0 b4 b3 b2 b1 b0 a0</td>
|
||||
<td> </td><td> </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
168
ext/closedcaption/macros.h
Normal 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
525
ext/closedcaption/misc.h
Normal 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:
|
||||
*/
|
1279
ext/closedcaption/raw_decoder.c
Normal file
1279
ext/closedcaption/raw_decoder.c
Normal file
File diff suppressed because it is too large
Load diff
212
ext/closedcaption/raw_decoder.h
Normal file
212
ext/closedcaption/raw_decoder.h
Normal 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:
|
||||
*/
|
551
ext/closedcaption/sampling_par.c
Normal file
551
ext/closedcaption/sampling_par.c
Normal 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:
|
||||
*/
|
87
ext/closedcaption/sampling_par.h
Normal file
87
ext/closedcaption/sampling_par.h
Normal 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
367
ext/closedcaption/sliced.h
Normal 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:
|
||||
*/
|
Loading…
Reference in a new issue