/* * 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 #include #include #include #include #include /* optarg */ #include #ifdef HAVE_GETOPT_LONG # include #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); }