854 lines
18 KiB
C++
854 lines
18 KiB
C++
/*
|
|
* libzvbi - vbi_raw_decoder unit test
|
|
*
|
|
* Copyright (C) 2004, 2007 Michael H. Schimek
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
/* $Id: test-raw_decoder.cc,v 1.4 2008/03/01 07:35:48 mschimek Exp $ */
|
|
|
|
#undef NDEBUG
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#include "src/version.h"
|
|
#if 2 == VBI_VERSION_MINOR
|
|
# include "src/raw_decoder.h"
|
|
# include "src/io-sim.h"
|
|
# define N_ELEMENTS(array) (sizeof (array) / sizeof (*(array)))
|
|
# define vbi_pixfmt_bytes_per_pixel(pf) VBI_PIXFMT_BPP(pf)
|
|
# define VBI_PIXFMT_IS_YUV(pf) (0 != (VBI_PIXFMT_SET (pf) \
|
|
& VBI_PIXFMT_SET_YUV))
|
|
#else
|
|
# include "src/misc.h"
|
|
# include "src/zvbi.h"
|
|
#endif
|
|
|
|
#include "test-common.h"
|
|
|
|
bool verbose;
|
|
|
|
typedef struct {
|
|
vbi_service_set service;
|
|
|
|
/* Scan lines. */
|
|
unsigned int first;
|
|
unsigned int last;
|
|
} block;
|
|
|
|
#define BLOCK_END { 0, 0, 0 }
|
|
|
|
static void
|
|
dump_hex (const uint8_t * p,
|
|
unsigned int n)
|
|
{
|
|
while (n-- > 0)
|
|
fprintf (stderr, "%02x ", *p++);
|
|
}
|
|
|
|
static void
|
|
sliced_rand_lines (const vbi_sliced * s_start,
|
|
const vbi_sliced * s_end,
|
|
vbi_sliced * s,
|
|
vbi_service_set service,
|
|
unsigned int first_line,
|
|
unsigned int last_line)
|
|
{
|
|
unsigned int line;
|
|
|
|
for (line = first_line; line <= last_line; ++line) {
|
|
const vbi_sliced *t;
|
|
|
|
assert (s < s_end);
|
|
|
|
for (t = s_start; t < s; ++t)
|
|
assert (t->line != line);
|
|
|
|
s->id = service;
|
|
s->line = line;
|
|
|
|
memset_rand (s->data, sizeof (s->data));
|
|
|
|
++s;
|
|
}
|
|
}
|
|
|
|
static unsigned int
|
|
sliced_rand (vbi_sliced * s,
|
|
unsigned int s_lines,
|
|
const block * b)
|
|
{
|
|
const vbi_sliced *s_start;
|
|
vbi_service_set services;
|
|
|
|
s_start = s;
|
|
services = 0;
|
|
|
|
while (b->service) {
|
|
services |= b->service;
|
|
|
|
if (b->first > 0) {
|
|
sliced_rand_lines (s_start, s_start + s_lines, s,
|
|
b->service, b->first, b->last);
|
|
|
|
s += b->last - b->first + 1;
|
|
}
|
|
|
|
++b;
|
|
}
|
|
|
|
if (0)
|
|
fprintf (stderr, "services 0x%08x\n", services);
|
|
|
|
return s - s_start;
|
|
}
|
|
|
|
static void
|
|
dump_sliced_pair (const vbi_sliced * s1,
|
|
const vbi_sliced * s2,
|
|
unsigned int n_lines)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < n_lines; ++i)
|
|
fprintf (stderr, "%2u: "
|
|
"%30s %3u %02x %02x %02x <-> "
|
|
"%30s %3u %02x %02x %02x\n",
|
|
i,
|
|
vbi_sliced_name (s1[i].id),
|
|
s1[i].line,
|
|
s1[i].data[0],
|
|
s1[i].data[1],
|
|
s1[i].data[2],
|
|
vbi_sliced_name (s2[i].id),
|
|
s2[i].line,
|
|
s2[i].data[0],
|
|
s2[i].data[1],
|
|
s2[i].data[2]);
|
|
}
|
|
|
|
static unsigned int
|
|
create_raw (uint8_t ** raw,
|
|
vbi_sliced ** sliced,
|
|
const vbi_sampling_par *sp,
|
|
const block * b,
|
|
unsigned int pixel_mask,
|
|
unsigned int raw_flags)
|
|
{
|
|
unsigned int scan_lines;
|
|
unsigned int sliced_lines;
|
|
unsigned int raw_size;
|
|
unsigned int blank_level;
|
|
unsigned int black_level;
|
|
unsigned int white_level;
|
|
vbi_bool success;
|
|
|
|
scan_lines = sp->count[0] + sp->count[1];
|
|
raw_size = sp->bytes_per_line * scan_lines;
|
|
|
|
*raw = (uint8_t *) malloc (raw_size);
|
|
assert (NULL != *raw);
|
|
|
|
*sliced = (vbi_sliced *) malloc (sizeof (**sliced) * 50);
|
|
assert (NULL != *sliced);
|
|
|
|
sliced_lines = sliced_rand (*sliced, 50, b);
|
|
|
|
/* Use defaults. */
|
|
blank_level = 0;
|
|
black_level = 0;
|
|
white_level = 0;
|
|
|
|
if (pixel_mask) {
|
|
memset_rand (*raw, raw_size);
|
|
|
|
success = _vbi_raw_video_image (*raw, raw_size, sp,
|
|
blank_level,
|
|
black_level,
|
|
white_level,
|
|
pixel_mask,
|
|
raw_flags,
|
|
*sliced, sliced_lines);
|
|
assert (success);
|
|
} else {
|
|
success = _vbi_raw_vbi_image (*raw, raw_size, sp,
|
|
blank_level,
|
|
white_level,
|
|
raw_flags,
|
|
*sliced, sliced_lines);
|
|
assert (success);
|
|
|
|
if (raw_flags & _VBI_RAW_NOISE_2) {
|
|
static uint32_t seed = 12345678;
|
|
|
|
/* Shape as in capture_stream_sim_add_noise(). */
|
|
success = vbi_raw_add_noise (*raw, sp,
|
|
/* min_freq */ 0,
|
|
/* max_freq */ 5000000,
|
|
/* amplitude */ 25,
|
|
seed);
|
|
assert (success);
|
|
|
|
seed = seed * 1103515245 + 56789;
|
|
}
|
|
}
|
|
|
|
return sliced_lines;
|
|
}
|
|
|
|
static vbi3_raw_decoder *
|
|
create_decoder (const vbi_sampling_par *sp,
|
|
const block * b,
|
|
unsigned int strict)
|
|
{
|
|
vbi3_raw_decoder *rd;
|
|
vbi_service_set in_services;
|
|
vbi_service_set out_services;
|
|
|
|
in_services = 0;
|
|
|
|
while (b->service) {
|
|
in_services |= b->service;
|
|
++b;
|
|
}
|
|
|
|
rd = vbi3_raw_decoder_new (sp);
|
|
assert (NULL != rd);
|
|
|
|
if (sp->synchronous) {
|
|
#if 2 == VBI_VERSION_MINOR
|
|
vbi3_raw_decoder_set_log_fn
|
|
(rd,
|
|
vbi_log_on_stderr,
|
|
/* user_data */ NULL,
|
|
(vbi_log_mask)(VBI_LOG_INFO * 2 - 1));
|
|
#else
|
|
vbi3_raw_decoder_set_log_fn
|
|
(rd,
|
|
(vbi_log_mask)(VBI_LOG_INFO * 2 - 1),
|
|
vbi_log_on_stderr,
|
|
/* user_data */ NULL);
|
|
#endif
|
|
} else {
|
|
/* Don't complain about expected failures.
|
|
XXX Check for those in a different function. */
|
|
}
|
|
|
|
out_services = vbi3_raw_decoder_add_services (rd, in_services, strict);
|
|
|
|
if (!sp->synchronous) {
|
|
/* Ambiguous. */
|
|
in_services &= ~(VBI_SLICED_VPS |
|
|
VBI_SLICED_VPS_F2 |
|
|
VBI_SLICED_WSS_625 |
|
|
VBI_SLICED_CAPTION_625 |
|
|
VBI_SLICED_CAPTION_525);
|
|
}
|
|
|
|
assert (in_services == out_services);
|
|
|
|
return rd;
|
|
}
|
|
|
|
static void
|
|
compare_payload (const vbi_sliced * in,
|
|
const vbi_sliced * out)
|
|
{
|
|
unsigned int payload;
|
|
|
|
payload = vbi_sliced_payload_bits (out->id);
|
|
if (0 != memcmp (in->data, out->data, payload >> 3)) {
|
|
dump_sliced_pair (in, out, /* n_lines */ 1);
|
|
assert (0);
|
|
}
|
|
|
|
if (payload & 7) {
|
|
unsigned int mask = (1 << (payload & 7)) - 1;
|
|
|
|
payload = (payload >> 3);
|
|
|
|
/* MSBs zero, rest as sent */
|
|
assert (0 == ((in->data[payload] & mask)
|
|
^ out->data[payload]));
|
|
}
|
|
}
|
|
|
|
static void
|
|
compare_sliced (const vbi_sampling_par *sp,
|
|
const vbi_sliced * in,
|
|
const vbi_sliced * out,
|
|
const vbi_sliced * old,
|
|
unsigned int in_lines,
|
|
unsigned int out_lines,
|
|
unsigned int old_lines)
|
|
{
|
|
unsigned int i;
|
|
unsigned int min;
|
|
unsigned int id;
|
|
vbi_sliced *in1;
|
|
vbi_sliced *s;
|
|
|
|
min = 0;
|
|
|
|
for (i = 0; i < out_lines; ++i) {
|
|
unsigned int payload;
|
|
|
|
if (sp->synchronous) {
|
|
/* Ascending line numbers. */
|
|
assert (out[i].line > min);
|
|
min = out[i].line;
|
|
} else {
|
|
/* Could be first or second field,
|
|
we don't know. */
|
|
assert (0 == out[i].line);
|
|
}
|
|
|
|
/* Valid service id. */
|
|
assert (0 != out[i].id);
|
|
payload = (vbi_sliced_payload_bits (out[i].id) + 7) >> 3;
|
|
assert (payload > 0);
|
|
|
|
/* vbi_sliced big enough. */
|
|
assert (payload <= sizeof (out[i].data));
|
|
|
|
/* Writes more than payload. */
|
|
assert (0 == memcmp (out[i].data + payload,
|
|
old[i].data + payload,
|
|
sizeof (out[i].data) - payload));
|
|
}
|
|
|
|
/* Respects limits. */
|
|
assert (0 == memcmp (out + out_lines,
|
|
old + out_lines,
|
|
sizeof (*old) * (old_lines - out_lines)));
|
|
|
|
in1 = (vbi_sliced *) xmemdup (in, sizeof (*in) * in_lines);
|
|
|
|
for (i = 0; i < out_lines; ++i) {
|
|
if (sp->synchronous) {
|
|
for (s = in1; s < in1 + in_lines; ++s)
|
|
if (s->line == out[i].line)
|
|
break;
|
|
|
|
/* Found something we didn't send. */
|
|
assert (s < in1 + in_lines);
|
|
|
|
/* Identified as something else. */
|
|
/* fprintf (stderr, "%3u id %08x %08x\n", s->line, s->id, out[i].id); */
|
|
assert (s->id == out[i].id);
|
|
} else {
|
|
/* fprintf (stderr, "%08x ", out[i].id); */
|
|
|
|
/* No line numbers, but data must be in
|
|
same order. */
|
|
for (s = in1; s < in1 + in_lines; ++s)
|
|
if (s->id == out[i].id)
|
|
break;
|
|
|
|
assert (s < in1 + in_lines);
|
|
|
|
/* fprintf (stderr, "from line %3u\n", s->line); */
|
|
}
|
|
|
|
compare_payload (s, &out[i]);
|
|
|
|
s->id = 0;
|
|
}
|
|
|
|
id = 0;
|
|
for (s = in1; s < in1 + in_lines; ++s)
|
|
id |= s->id;
|
|
|
|
if (!sp->synchronous) {
|
|
/* Ok these are ambiguous. */
|
|
id &= ~(VBI_SLICED_VPS |
|
|
VBI_SLICED_VPS_F2 |
|
|
VBI_SLICED_WSS_625 |
|
|
VBI_SLICED_CAPTION_625 |
|
|
VBI_SLICED_CAPTION_525);
|
|
}
|
|
|
|
/* Anything missed? */
|
|
assert (0 == id);
|
|
|
|
free (in1);
|
|
in1 = NULL;
|
|
}
|
|
|
|
static void
|
|
test_cycle (const vbi_sampling_par *sp,
|
|
const block * b,
|
|
unsigned int pixel_mask,
|
|
unsigned int raw_flags,
|
|
unsigned int strict)
|
|
{
|
|
vbi_sliced *in;
|
|
vbi_sliced out[50];
|
|
vbi_sliced old[50];
|
|
uint8_t *raw;
|
|
vbi3_raw_decoder *rd;
|
|
unsigned int in_lines;
|
|
unsigned int out_lines;
|
|
|
|
in_lines = create_raw (&raw, &in, sp, b, pixel_mask, raw_flags);
|
|
|
|
if (verbose)
|
|
dump_hex (raw + 120, 12);
|
|
|
|
rd = create_decoder (sp, b, strict);
|
|
|
|
memset_rand (out, sizeof (out));
|
|
memcpy (old, out, sizeof (old));
|
|
|
|
out_lines = vbi3_raw_decoder_decode (rd, out, 40, raw);
|
|
|
|
if (verbose) {
|
|
#if 2 == VBI_VERSION_MINOR
|
|
fprintf (stderr, "%s %08x in=%u out=%u\n",
|
|
__FUNCTION__,
|
|
sp->sampling_format,
|
|
in_lines, out_lines);
|
|
#else
|
|
fprintf (stderr, "%s %s in=%u out=%u\n",
|
|
__FUNCTION__,
|
|
vbi_pixfmt_name (sp->sample_format),
|
|
in_lines, out_lines);
|
|
#endif
|
|
}
|
|
|
|
if (sp->synchronous) {
|
|
if (verbose && in_lines != out_lines)
|
|
dump_sliced_pair (in, out, MIN (in_lines, out_lines));
|
|
|
|
assert (in_lines == out_lines);
|
|
}
|
|
|
|
compare_sliced (sp, in, out, old, in_lines, out_lines, 50);
|
|
|
|
vbi3_raw_decoder_delete (rd);
|
|
|
|
free (in);
|
|
free (raw);
|
|
}
|
|
|
|
static vbi_bool
|
|
block_contains_service (const block * b,
|
|
vbi_service_set services,
|
|
vbi_bool exclusive)
|
|
{
|
|
vbi_service_set all_services = 0;
|
|
|
|
assert (0 != services);
|
|
|
|
while (b->service) {
|
|
all_services |= b->service;
|
|
++b;
|
|
}
|
|
|
|
if (0 == (all_services & services))
|
|
return FALSE;
|
|
|
|
if (exclusive && 0 != (all_services & ~services))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
test_vbi (const vbi_sampling_par *sp,
|
|
const block * b,
|
|
unsigned int strict)
|
|
{
|
|
test_cycle (sp, b, /* pixel_mask */ 0,
|
|
/* raw_flags */ 0, strict);
|
|
|
|
/* Tests incorrect signal shape reported by Rich Kadel. */
|
|
if (block_contains_service (b, VBI_SLICED_CAPTION_525,
|
|
/* exclusive */ FALSE))
|
|
test_cycle (sp, b, /* pixel_mask */ 0,
|
|
_VBI_RAW_SHIFT_CC_CRI, strict);
|
|
|
|
/* Tests low amplitude CC signals reported by Rich Kadel. */
|
|
if (block_contains_service (b, VBI_SLICED_CAPTION_525,
|
|
/* exclusive */ TRUE)
|
|
&& sp->sampling_rate >= 27000000) {
|
|
unsigned int i;
|
|
|
|
/* Repeat because the noise varies. */
|
|
for (i = 0; i < 1000; ++i) {
|
|
test_cycle (sp, b, /* pixel_mask */ 0,
|
|
_VBI_RAW_LOW_AMP_CC |
|
|
_VBI_RAW_NOISE_2, strict);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
test_video (const vbi_sampling_par *sp,
|
|
const block * b,
|
|
unsigned int strict)
|
|
{
|
|
vbi_sampling_par sp2;
|
|
unsigned int pixel_mask;
|
|
vbi_pixfmt pixfmt;
|
|
unsigned int samples_per_line;
|
|
|
|
sp2 = *sp;
|
|
#if 2 == VBI_VERSION_MINOR
|
|
samples_per_line = sp->bytes_per_line
|
|
/ vbi_pixfmt_bytes_per_pixel (sp->sampling_format);
|
|
#else
|
|
samples_per_line = sp->samples_per_line;
|
|
#endif
|
|
|
|
for (pixfmt = (vbi_pixfmt) 0; pixfmt < VBI_MAX_PIXFMTS;
|
|
pixfmt = (vbi_pixfmt)(pixfmt + 1)) {
|
|
if (0 == (VBI_PIXFMT_SET_ALL & VBI_PIXFMT_SET (pixfmt)))
|
|
continue;
|
|
|
|
#if 2 == VBI_VERSION_MINOR
|
|
sp2.sampling_format = pixfmt;
|
|
#else
|
|
sp2.sample_format = pixfmt;
|
|
#endif
|
|
sp2.bytes_per_line = samples_per_line
|
|
* vbi_pixfmt_bytes_per_pixel (pixfmt);
|
|
|
|
/* Check bit slicer looks at Y/G */
|
|
if (VBI_PIXFMT_IS_YUV (pixfmt))
|
|
pixel_mask = 0xFF;
|
|
else
|
|
pixel_mask = 0xFF00;
|
|
|
|
test_cycle (&sp2, b, pixel_mask,
|
|
/* raw_flags */ 0, strict);
|
|
|
|
if (block_contains_service (b, VBI_SLICED_CAPTION_525,
|
|
/* exclusive */ FALSE))
|
|
test_cycle (&sp2, b, pixel_mask,
|
|
_VBI_RAW_SHIFT_CC_CRI, strict);
|
|
}
|
|
}
|
|
|
|
static const block ttx_a [] = {
|
|
{ VBI_SLICED_TELETEXT_A, 6, 22 },
|
|
{ VBI_SLICED_TELETEXT_A, 318, 335 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block ttx_c_625 [] = {
|
|
{ VBI_SLICED_TELETEXT_C_625, 6, 22 },
|
|
{ VBI_SLICED_TELETEXT_C_625, 318, 335 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block ttx_d_625 [] = {
|
|
{ VBI_SLICED_TELETEXT_D_625, 6, 22 },
|
|
{ VBI_SLICED_TELETEXT_D_625, 318, 335 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block ttx_wss_cc_625 [] = {
|
|
{ VBI_SLICED_TELETEXT_B_625, 6, 21 },
|
|
{ VBI_SLICED_CAPTION_625, 22, 22 },
|
|
{ VBI_SLICED_WSS_625, 23, 23 },
|
|
{ VBI_SLICED_TELETEXT_B_625, 318, 334 },
|
|
{ VBI_SLICED_CAPTION_625, 335, 335 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block hi_f1_625 [] = {
|
|
{ VBI_SLICED_VPS, 16, 16 },
|
|
{ VBI_SLICED_CAPTION_625_F1, 22, 22 },
|
|
{ VBI_SLICED_WSS_625, 23, 23 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block hi_f2_525 [] = {
|
|
{ VBI_SLICED_CAPTION_525_F2, 284, 284 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block vps_wss_cc_625 [] = {
|
|
{ VBI_SLICED_VPS, 16, 16 },
|
|
{ VBI_SLICED_CAPTION_625, 22, 22 },
|
|
{ VBI_SLICED_WSS_625, 23, 23 },
|
|
{ VBI_SLICED_CAPTION_625, 335, 335 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block cc_625 [] = {
|
|
{ VBI_SLICED_CAPTION_625, 22, 22 },
|
|
{ VBI_SLICED_CAPTION_625, 335, 335 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block ttx_c_525 [] = {
|
|
{ VBI_SLICED_TELETEXT_C_525, 10, 21 },
|
|
{ VBI_SLICED_TELETEXT_C_525, 272, 284 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block ttx_d_525 [] = {
|
|
{ VBI_SLICED_TELETEXT_D_525, 10, 21 },
|
|
{ VBI_SLICED_TELETEXT_D_525, 272, 284 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block hi_525 [] = {
|
|
{ VBI_SLICED_TELETEXT_B_525, 10, 20 },
|
|
{ VBI_SLICED_CAPTION_525, 21, 21 },
|
|
{ VBI_SLICED_TELETEXT_B_525, 272, 283 },
|
|
{ VBI_SLICED_CAPTION_525, 284, 284 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static const block cc_525 [] = {
|
|
{ VBI_SLICED_CAPTION_525, 21, 21 },
|
|
{ VBI_SLICED_CAPTION_525, 284, 284 },
|
|
BLOCK_END,
|
|
};
|
|
|
|
static void
|
|
test2 (const vbi_sampling_par *sp)
|
|
{
|
|
#if 2 == VBI_VERSION_MINOR
|
|
if (625 == sp->scanning) {
|
|
#else
|
|
if (sp->videostd_set & VBI_VIDEOSTD_SET_625_50) {
|
|
#endif
|
|
if (sp->sampling_rate >= 13500000) {
|
|
vbi_sampling_par sp1;
|
|
|
|
/* We cannot mix Teletext standards; bit rate and
|
|
FRC are too similar to reliable distinguish. */
|
|
test_vbi (sp, ttx_a, 1);
|
|
test_vbi (sp, ttx_c_625, 1);
|
|
|
|
/* Needs sampling beyond 0H + 63 us (?) */
|
|
#if 2 == VBI_VERSION_MINOR
|
|
if (sp->bytes_per_line
|
|
== 2048 * VBI_PIXFMT_BPP (sp->sampling_format))
|
|
test_vbi (sp, ttx_d_625, 1);
|
|
#else
|
|
if (sp->bytes_per_line == 2048
|
|
* vbi_pixfmt_bytes_per_pixel (sp->sample_format))
|
|
test_vbi (sp, ttx_d_625, 1);
|
|
#endif
|
|
|
|
test_vbi (sp, ttx_wss_cc_625, 1);
|
|
test_video (sp, ttx_wss_cc_625, 1);
|
|
|
|
/* For low_pass_bit_slicer test. */
|
|
test_vbi (sp, vps_wss_cc_625, 1);
|
|
|
|
if (!sp->interlaced) {
|
|
sp1 = *sp;
|
|
sp1.start[1] = 0;
|
|
sp1.count[1] = 0;
|
|
test_vbi (&sp1, hi_f1_625, 2);
|
|
}
|
|
} else if (sp->sampling_rate >= 5000000) {
|
|
test_vbi (sp, vps_wss_cc_625, 1);
|
|
test_video (sp, vps_wss_cc_625, 1);
|
|
} else {
|
|
/* WSS not possible below 5 MHz due to a cri_rate
|
|
check in bit_slicer_init(), but much less won't
|
|
work anyway. */
|
|
test_vbi (sp, cc_625, 1);
|
|
test_video (sp, cc_625, 1);
|
|
}
|
|
} else {
|
|
if (sp->sampling_rate >= 13500000) {
|
|
vbi_sampling_par sp1;
|
|
|
|
test_vbi (sp, ttx_c_525, 1);
|
|
test_vbi (sp, ttx_d_525, 1);
|
|
|
|
test_vbi (sp, hi_525, 1);
|
|
test_video (sp, hi_525, 1);
|
|
|
|
/* CC only for the low-amp CC test. */
|
|
test_vbi (sp, cc_525, 1);
|
|
|
|
if (!sp->interlaced) {
|
|
sp1 = *sp;
|
|
sp1.start[0] = 0;
|
|
sp1.count[0] = 0;
|
|
test_vbi (&sp1, hi_f2_525, 2);
|
|
}
|
|
} else {
|
|
test_vbi (sp, cc_525, 1);
|
|
test_video (sp, cc_525, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
test1 (const vbi_sampling_par *sp)
|
|
{
|
|
static const struct {
|
|
unsigned int sampling_rate;
|
|
unsigned int samples_per_line;
|
|
} res [] = {
|
|
/* bt8x8 PAL ~35.5 MHz / 2048
|
|
bt8x8 NTSC ~28.6 MHz / 2048
|
|
PAL 1:1 ~14.7 MHz / 768
|
|
ITU-R BT.601 13.5 MHz / 720
|
|
NTSC 1:1 ~12.3 MHz / 640 */
|
|
{ 35468950, 2048 },
|
|
{ 27000000, 1440 },
|
|
{ 13500000, 720 },
|
|
{ 3000000, 176 },
|
|
};
|
|
vbi_sampling_par sp2;
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < N_ELEMENTS (res); ++i) {
|
|
if (verbose)
|
|
fprintf (stderr, "%.2f MHz %u spl\n",
|
|
res[i].sampling_rate / 1e6,
|
|
res[i].samples_per_line);
|
|
|
|
sp2 = *sp;
|
|
sp2.sampling_rate = res[i].sampling_rate;
|
|
#if 2 == VBI_VERSION_MINOR
|
|
sp2.bytes_per_line = res[i].samples_per_line
|
|
* vbi_pixfmt_bytes_per_pixel (sp2.sampling_format);
|
|
#else
|
|
sp2.samples_per_line = res[i].samples_per_line;
|
|
sp2.bytes_per_line = res[i].samples_per_line
|
|
* vbi_pixfmt_bytes_per_pixel (sp2.sample_format);
|
|
#endif
|
|
|
|
sp2.offset = (int)(9.7e-6 * sp2.sampling_rate);
|
|
|
|
test2 (&sp2);
|
|
}
|
|
}
|
|
|
|
static void
|
|
test_services (void)
|
|
{
|
|
vbi_sampling_par sp;
|
|
vbi_service_set set;
|
|
|
|
memset (&sp, 0x55, sizeof (sp));
|
|
|
|
set = vbi_sampling_par_from_services (&sp,
|
|
/* &max_rate */ NULL,
|
|
VBI_VIDEOSTD_SET_625_50,
|
|
~0 & ~VBI_SLICED_VBI_625);
|
|
assert (set == (VBI_SLICED_TELETEXT_A |
|
|
VBI_SLICED_TELETEXT_B_625 |
|
|
VBI_SLICED_TELETEXT_C_625 |
|
|
VBI_SLICED_TELETEXT_D_625 |
|
|
VBI_SLICED_VPS |
|
|
VBI_SLICED_VPS_F2 |
|
|
VBI_SLICED_CAPTION_625 |
|
|
VBI_SLICED_WSS_625));
|
|
test2 (&sp);
|
|
|
|
set = vbi_sampling_par_from_services (&sp,
|
|
/* &max_rate */ NULL,
|
|
VBI_VIDEOSTD_SET_525_60,
|
|
~0 & ~VBI_SLICED_VBI_525);
|
|
assert (set == (VBI_SLICED_TELETEXT_B_525 |
|
|
VBI_SLICED_TELETEXT_C_525 |
|
|
VBI_SLICED_TELETEXT_D_525 |
|
|
VBI_SLICED_CAPTION_525 |
|
|
VBI_SLICED_2xCAPTION_525
|
|
/* Needs fix */
|
|
/* | VBI_SLICED_WSS_CPR1204 */ ));
|
|
test2 (&sp);
|
|
}
|
|
|
|
static void
|
|
test_line_order (vbi_bool synchronous)
|
|
{
|
|
vbi_sampling_par sp;
|
|
|
|
memset (&sp, 0x55, sizeof (sp));
|
|
|
|
#if 2 == VBI_VERSION_MINOR
|
|
sp.scanning = 625;
|
|
sp.sampling_format = VBI_PIXFMT_YUV420;
|
|
#else
|
|
sp.videostd_set = VBI_VIDEOSTD_SET_PAL_BG;
|
|
sp.sample_format = VBI_PIXFMT_YUV420;
|
|
#endif
|
|
sp.start[0] = 6;
|
|
sp.count[0] = 23 - 6 + 1;
|
|
sp.start[1] = 318;
|
|
sp.count[1] = 335 - 318 + 1;
|
|
sp.interlaced = FALSE;
|
|
sp.synchronous = synchronous;
|
|
|
|
test1 (&sp);
|
|
|
|
sp.interlaced = TRUE;
|
|
|
|
test1 (&sp);
|
|
|
|
#if 2 == VBI_VERSION_MINOR
|
|
sp.scanning = 525;
|
|
sp.sampling_format = VBI_PIXFMT_YUV420;
|
|
#else
|
|
sp.videostd_set = VBI_VIDEOSTD_SET_NTSC;
|
|
sp.sample_format = VBI_PIXFMT_YUV420;
|
|
#endif
|
|
sp.start[0] = 10;
|
|
sp.count[0] = 21 - 10 + 1;
|
|
sp.start[1] = 272;
|
|
sp.count[1] = 284 - 272 + 1;
|
|
sp.interlaced = FALSE;
|
|
sp.synchronous = synchronous;
|
|
|
|
test1 (&sp);
|
|
}
|
|
|
|
int
|
|
main (int argc,
|
|
char ** argv)
|
|
{
|
|
argv = argv;
|
|
|
|
verbose = (argc > 1);
|
|
|
|
test_services ();
|
|
|
|
test_line_order (/* synchronous */ TRUE);
|
|
test_line_order (/* synchronous */ FALSE);
|
|
|
|
/* More... */
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Local variables:
|
|
c-set-style: K&R
|
|
c-basic-offset: 8
|
|
End:
|
|
*/
|