316 lines
7.8 KiB
C
Executable File
316 lines
7.8 KiB
C
Executable File
/*
|
|
* zvbi-sliced2pes -- Sliced VBI file converter
|
|
*
|
|
* 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: sliced2pes.c,v 1.15 2008/03/01 07:36:24 mschimek Exp $ */
|
|
|
|
/* For libzvbi version 0.2.x / 0.3.x. */
|
|
|
|
#undef NDEBUG
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <locale.h>
|
|
#include <limits.h>
|
|
#include <unistd.h> /* optarg */
|
|
#include <assert.h>
|
|
#ifdef HAVE_GETOPT_LONG
|
|
# include <getopt.h>
|
|
#endif
|
|
|
|
#include "src/version.h"
|
|
#if 2 == VBI_VERSION_MINOR
|
|
# include "src/dvb_mux.h"
|
|
#elif 3 == VBI_VERSION_MINOR
|
|
# include "src/zvbi.h"
|
|
#else
|
|
# error VBI_VERSION_MINOR == ?
|
|
#endif
|
|
|
|
#include "sliced.h"
|
|
|
|
#undef _
|
|
#define _(x) x /* i18n TODO */
|
|
|
|
/* Will be installed one day. */
|
|
#define PROGRAM_NAME "sliced2pes"
|
|
|
|
static const char * option_in_file_name;
|
|
static enum file_format option_in_file_format;
|
|
static unsigned int option_in_ts_pid;
|
|
|
|
static const char * option_out_file_name;
|
|
static enum file_format option_out_file_format;
|
|
static unsigned int option_out_ts_pid;
|
|
|
|
static unsigned long option_data_identifier;
|
|
static unsigned long option_min_pes_packet_size;
|
|
static unsigned long option_max_pes_packet_size;
|
|
|
|
static struct stream * rst;
|
|
static struct stream * wst;
|
|
|
|
static vbi_bool
|
|
output_frame (const vbi_sliced * sliced,
|
|
unsigned int n_lines,
|
|
const uint8_t * raw,
|
|
const vbi_sampling_par *sp,
|
|
double sample_time,
|
|
int64_t stream_time)
|
|
{
|
|
raw = raw; /* unused */
|
|
sp = sp;
|
|
|
|
write_stream_sliced (wst, sliced, n_lines,
|
|
/* raw */ NULL,
|
|
/* sp */ NULL,
|
|
sample_time, stream_time);
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
get_mux_defaults (void)
|
|
{
|
|
vbi_dvb_mux *mx;
|
|
|
|
mx = vbi_dvb_pes_mux_new (/* callback */ NULL,
|
|
/* user_data */ NULL);
|
|
if (NULL == mx)
|
|
no_mem_exit ();
|
|
|
|
option_data_identifier =
|
|
vbi_dvb_mux_get_data_identifier (mx);
|
|
|
|
option_min_pes_packet_size =
|
|
vbi_dvb_mux_get_min_pes_packet_size (mx);
|
|
|
|
option_max_pes_packet_size =
|
|
vbi_dvb_mux_get_max_pes_packet_size (mx);
|
|
|
|
vbi_dvb_mux_delete (mx);
|
|
}
|
|
|
|
static void
|
|
usage (FILE * fp)
|
|
{
|
|
get_mux_defaults ();
|
|
|
|
fprintf (fp, _("\
|
|
%s %s -- VBI stream converter\n\n\
|
|
Copyright (C) 2004, 2007 Michael H. Schimek\n\
|
|
This program is licensed under GPLv2 or later. NO WARRANTIES.\n\n\
|
|
Usage: %s [options] < sliced VBI data > PES or TS stream\n\
|
|
-h | --help | --usage Print this message and exit\n\
|
|
-q | --quiet Suppress progress and error messages\n\
|
|
-v | --verbose Increase verbosity\n\
|
|
-V | --version Print the program version and exit\n\
|
|
Input options:\n\
|
|
-i | --input name Read the VBI data from this file instead\n\
|
|
of standard input\n\
|
|
-P | --pes | --pes-input Source is a DVB PES stream\n\
|
|
-T | --ts | --ts-input pid Source is a DVB TS stream\n\
|
|
Output options:\n\
|
|
-d | --data-identifier n 0x10 ... 0x1F for compatibility with\n\
|
|
ETS 300 472 compliant decoders, or\n\
|
|
0x99 ... 0x9B as defined in EN 301 775\n\
|
|
(default 0x%02lx)\n\
|
|
-m | --max | --max-packet-size n Maximum PES packet size (%lu bytes)\n\
|
|
-n | --min | --min-packet-size n Minimum PES packet size (%lu bytes)\n\
|
|
-o | --output name Write the VBI data to this file instead\n\
|
|
of standard output\n\
|
|
-p | --pes-output Generate a DVB PES stream\n\
|
|
-t | --ts-output pid Generate a DVB TS stream with this PID\n\
|
|
"),
|
|
PROGRAM_NAME, VERSION, program_invocation_name,
|
|
option_data_identifier,
|
|
option_max_pes_packet_size,
|
|
option_min_pes_packet_size);
|
|
}
|
|
|
|
static const char
|
|
short_options [] = "d:hi:m:n:o:pqt:vPT:V";
|
|
|
|
#ifdef HAVE_GETOPT_LONG
|
|
static const struct option
|
|
long_options [] = {
|
|
{ "data-identifier", required_argument, NULL, 'd' },
|
|
{ "help", no_argument, NULL, 'h' },
|
|
{ "usage", no_argument, NULL, 'h' },
|
|
{ "input", required_argument, NULL, 'i' },
|
|
{ "max-packet-size", required_argument, NULL, 'm' },
|
|
{ "min-packet-size", required_argument, NULL, 'n' },
|
|
{ "output", required_argument, NULL, 'o' },
|
|
{ "pes-output", no_argument, NULL, 'p' },
|
|
{ "quiet", no_argument, NULL, 'q' },
|
|
{ "ts-output", required_argument, NULL, 't' },
|
|
{ "verbose", no_argument, NULL, 'v' },
|
|
{ "pes-input", no_argument, NULL, 'P' },
|
|
{ "ts-input", required_argument, NULL, 'T' },
|
|
{ "version", no_argument, NULL, 'V' },
|
|
{ NULL, 0, 0, 0 }
|
|
};
|
|
#else
|
|
# define getopt_long(ac, av, s, l, i) getopt(ac, av, s)
|
|
#endif
|
|
|
|
static int option_index;
|
|
|
|
static void
|
|
parse_option_data_identifier (void)
|
|
{
|
|
const char *s = optarg;
|
|
char *end;
|
|
|
|
assert (NULL != optarg);
|
|
|
|
option_data_identifier = strtoul (s, &end, 0);
|
|
|
|
if (option_data_identifier > 0xFF) {
|
|
error_exit (_("Invalid data identifier 0x%02lx."),
|
|
option_data_identifier);
|
|
}
|
|
}
|
|
|
|
int
|
|
main (int argc,
|
|
char ** argv)
|
|
{
|
|
init_helpers (argc, argv);
|
|
|
|
get_mux_defaults ();
|
|
|
|
option_in_file_format = FILE_FORMAT_SLICED;
|
|
option_out_file_format = FILE_FORMAT_DVB_PES;
|
|
|
|
for (;;) {
|
|
int c;
|
|
|
|
c = getopt_long (argc, argv, short_options,
|
|
long_options, &option_index);
|
|
if (-1 == c)
|
|
break;
|
|
|
|
switch (c) {
|
|
case 0: /* getopt_long() flag */
|
|
break;
|
|
|
|
case 'd':
|
|
parse_option_data_identifier ();
|
|
break;
|
|
|
|
case 'h':
|
|
usage (stdout);
|
|
exit (EXIT_SUCCESS);
|
|
|
|
case 'i':
|
|
assert (NULL != optarg);
|
|
option_in_file_name = optarg;
|
|
break;
|
|
|
|
case 'm':
|
|
assert (NULL != optarg);
|
|
option_max_pes_packet_size =
|
|
strtoul (optarg, NULL, 0);
|
|
if (option_max_pes_packet_size > UINT_MAX)
|
|
option_max_pes_packet_size = UINT_MAX;
|
|
break;
|
|
|
|
case 'n':
|
|
assert (NULL != optarg);
|
|
option_min_pes_packet_size =
|
|
strtoul (optarg, NULL, 0);
|
|
if (option_min_pes_packet_size > UINT_MAX)
|
|
option_min_pes_packet_size = UINT_MAX;
|
|
break;
|
|
|
|
case 'o':
|
|
assert (NULL != optarg);
|
|
option_out_file_name = optarg;
|
|
break;
|
|
|
|
case 'p':
|
|
option_out_file_format = FILE_FORMAT_DVB_PES;
|
|
break;
|
|
|
|
case 'q':
|
|
parse_option_quiet ();
|
|
break;
|
|
|
|
case 't':
|
|
option_out_ts_pid = parse_option_ts ();
|
|
option_out_file_format = FILE_FORMAT_DVB_TS;
|
|
break;
|
|
|
|
case 'v':
|
|
parse_option_verbose ();
|
|
break;
|
|
|
|
case 'P':
|
|
option_in_file_format = FILE_FORMAT_DVB_PES;
|
|
break;
|
|
|
|
case 'T':
|
|
option_in_ts_pid = parse_option_ts ();
|
|
option_in_file_format = FILE_FORMAT_DVB_TS;
|
|
break;
|
|
|
|
case 'V':
|
|
printf (PROGRAM_NAME " " VERSION "\n");
|
|
exit (EXIT_SUCCESS);
|
|
|
|
default:
|
|
usage (stderr);
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
wst = write_stream_new (option_out_file_name,
|
|
option_out_file_format,
|
|
option_out_ts_pid,
|
|
/* system */ 625);
|
|
|
|
write_stream_set_data_identifier (wst, option_data_identifier);
|
|
write_stream_set_pes_packet_size (wst,
|
|
option_min_pes_packet_size,
|
|
option_max_pes_packet_size);
|
|
|
|
rst = read_stream_new (option_in_file_name,
|
|
option_in_file_format,
|
|
option_in_ts_pid,
|
|
output_frame);
|
|
|
|
stream_loop (rst);
|
|
|
|
stream_delete (rst);
|
|
rst = NULL;
|
|
|
|
stream_delete (wst);
|
|
wst = NULL;
|
|
|
|
error_msg (_("End of stream."));
|
|
|
|
exit (EXIT_SUCCESS);
|
|
}
|