kopia lustrzana https://github.com/F5OEO/tstools
358 wiersze
14 KiB
C
358 wiersze
14 KiB
C
/*
|
||
* Support for writing out TS packets, to file, or over TCP/IP or UDP
|
||
*
|
||
* When writing asynchronously, provides automated producer/consumer
|
||
* behaviour via a circular buffer, optionally taking timing from the
|
||
* TS PCR entries.
|
||
*
|
||
* ***** BEGIN LICENSE BLOCK *****
|
||
* Version: MPL 1.1
|
||
*
|
||
* The contents of this file are subject to the Mozilla Public License Version
|
||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||
* the License. You may obtain a copy of the License at
|
||
* http://www.mozilla.org/MPL/
|
||
*
|
||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||
* for the specific language governing rights and limitations under the
|
||
* License.
|
||
*
|
||
* The Original Code is the MPEG TS, PS and ES tools.
|
||
*
|
||
* The Initial Developer of the Original Code is Amino Communications Ltd.
|
||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||
* the Initial Developer. All Rights Reserved.
|
||
*
|
||
* Contributor(s):
|
||
* Amino Communications Ltd, Swavesey, Cambridge UK
|
||
*
|
||
* ***** END LICENSE BLOCK *****
|
||
*/
|
||
|
||
#ifndef _tswrite_fns
|
||
#define _tswrite_fns
|
||
|
||
#include "tswrite_defns.h"
|
||
|
||
/*
|
||
* Open a file for TS output.
|
||
*
|
||
* - `how` is how to open the file or connect to the host
|
||
* - `name` is the name of the file or host to open/connect to
|
||
* (this is ignored if `how` is TS_W_STDOUT)
|
||
* - if `how` is TS_W_UDP, and `name` is a multicast address,
|
||
* then `multicast_if` may be the IP address of the network
|
||
* address to use, or NULL if the default interface should
|
||
* be used.
|
||
* - if it is a socket (i.e., if `how` is TS_W_TCP or TS_W_UDP),
|
||
* then `port` is the port to use, otherwise this is ignored
|
||
* - `quiet` is true if only error messages should be printed
|
||
* - `tswriter` is the new context to use for writing TS output,
|
||
* which should be closed using `tswrite_close`.
|
||
*
|
||
* For TS_W_STDOUT, there is no need to open anything.
|
||
*
|
||
* For TS_W_FILE, ``open(name,O_CREAT|O_WRONLY|O_TRUNC|O_BINARY,00777)``
|
||
* is used - i.e., the file is opened so that anyone may read/write/execute
|
||
* it. If ``O_BINARY`` is not defined (e.g., on Linux), then it is
|
||
* omitted.
|
||
*
|
||
* For TS_W_TCP and TS_W_UDP, the ``connect_socket`` function is called,
|
||
* which uses ``socket`` and ``connect``.
|
||
*
|
||
* In all cases (even when using TS_W_STDOUT), the `tswriter` should be
|
||
* closed using `tswrite_stdout`.
|
||
*
|
||
* For TS_W_UDP, the ``tswrite_startt_buffering`` function must be called
|
||
* before any output is written via the `tswriter`. For other forms of output,
|
||
* this is optional.
|
||
*
|
||
* Returns 0 if all goes well, 1 if something went wrong.
|
||
*/
|
||
extern int tswrite_open(TS_WRITER_TYPE how,
|
||
char *name,
|
||
char *multicast_if,
|
||
int port,
|
||
int quiet,
|
||
TS_writer_p *tswriter);
|
||
/*
|
||
* Open a network connection for TS output.
|
||
*
|
||
* This is a convenience wrapper around `tswrite_open`.
|
||
*
|
||
* - `name` is the name of the host to connect to
|
||
* - `port` is the port to connect to
|
||
* - `use_tcp` is TRUE if TCP/IP should be use, FALSE if UDP should be used
|
||
* - `quiet` is true if only error messages should be printed
|
||
* - `tswriter` is the new context to use for writing TS output,
|
||
* which should be closed using `tswrite_close`.
|
||
*
|
||
* In all cases, the `tswriter` should be closed using `tswrite_stdout`.
|
||
*
|
||
* For TS_W_UDP, the ``tswrite_start_buffering`` function must be called
|
||
* before any output is written via the `tswriter`. For other forms of output,
|
||
* this is optional.
|
||
*
|
||
* Returns 0 if all goes well, 1 if something went wrong.
|
||
*/
|
||
extern int tswrite_open_connection(int use_tcp,
|
||
char *name,
|
||
int port,
|
||
int quiet,
|
||
TS_writer_p *tswriter);
|
||
/*
|
||
* Open a file for TS output.
|
||
*
|
||
* This is a convenience wrapper around `tswrite_open`.
|
||
*
|
||
* - `name` is the name of the file to open, or NULL if stdout should be used
|
||
* - `quiet` is true if only error messages should be printed
|
||
* - `tswriter` is the new context to use for writing TS output,
|
||
* which should be closed using `tswrite_close`.
|
||
*
|
||
* In all cases (even when using TS_W_STDOUT), the `tswriter` should be
|
||
* closed using `tswrite_stdout`.
|
||
*
|
||
* Returns 0 if all goes well, 1 if something went wrong.
|
||
*/
|
||
extern int tswrite_open_file(char *name,
|
||
int quiet,
|
||
TS_writer_p *tswriter);
|
||
/*
|
||
* Wait for a client to connect and then both write TS data to it and
|
||
* listen for command from it. Uses TCP/IP.
|
||
*
|
||
* - `server_socket` is the socket on which we will listen for a connection
|
||
* - `quiet` is true if only error messages should be printed
|
||
* - `tswriter` is the new context to use for writing TS output,
|
||
* which should be closed using `tswrite_close`.
|
||
*
|
||
* Returns 0 if all goes well, 1 if something went wrong.
|
||
*/
|
||
extern int tswrite_wait_for_client(int server_socket,
|
||
int quiet,
|
||
TS_writer_p *tswriter);
|
||
/*
|
||
* Set up internal buffering for TS output. This is necessary for UDP
|
||
* output, and optional otherwise.
|
||
*
|
||
* Builds the internal circular buffer and other datastructures, and
|
||
* forks a child proces to send data over the socket.
|
||
*
|
||
* (This is *intended* for use when outputting via a socket, but there
|
||
* is nothing actually stopping it from being used to output to a file.
|
||
* This is unlikely to be useful for other than testing purposes, however.)
|
||
*
|
||
* See also `tswrite_start_buffering_from_context`, which uses the `context`
|
||
* datastructure that is prepared by `tswrite_process_args`.
|
||
*
|
||
* - `tswriter` is the TS output context returned by `tswrite_open`
|
||
* - `circ_buf_size` is the number of buffer entries (plus one) we would
|
||
* like in the underlying circular buffer.
|
||
* - `TS_in_packet` is the number of TS packets to allow in each network
|
||
* packet.
|
||
* - `maxnowait` is the maximum number of packets to send to the target
|
||
* host with no wait between packets
|
||
* - `waitfor` is the number of microseconds to wait for thereafter
|
||
* - `byterate` is the (initial) rate at which we'd like to output our data
|
||
* - `use_pcrs` is TRUE if PCRs in the data stream are to be used for
|
||
* timing output (the normal case), otherwise the specified byte rate
|
||
* will be used directly.
|
||
* - `prime_size` is how much to prime the circular buffer output timer
|
||
* - `prime_speedup` is the percentage of "normal speed" to use for the priming
|
||
* rate. This should normally be set to 100 (i.e., no effect).
|
||
* - `pcr_scale` determines how much to "accelerate" each PCR - see the
|
||
* notes elsewhere on how this works.
|
||
*
|
||
* Returns 0 if all went well, 1 if something went wrong.
|
||
*/
|
||
|
||
extern int tswrite_start_buffering(TS_writer_p tswriter,
|
||
int circ_buf_size,
|
||
int TS_in_packet,
|
||
int maxnowait,
|
||
int waitfor,
|
||
int byterate,
|
||
tswrite_pcr_mode pcr_mode,
|
||
int prime_size,
|
||
int prime_speedup,
|
||
double pcr_scale,
|
||
const tswrite_pkt_hdr_type_t hdr_type);
|
||
|
||
/*
|
||
* Set up internal buffering for TS output. This is necessary for UDP output,
|
||
* and optional otherwise.
|
||
*
|
||
* This alternative takes the `context` datastructure that is prepared
|
||
* by `tswrite_process_args`.
|
||
*
|
||
* - `tswriter` is the TS output context returned by `tswrite_open`
|
||
* - `context` contains the necessary information, as given by the user
|
||
*
|
||
* Returns 0 if all went well, 1 if something went wrong.
|
||
*/
|
||
extern int tswrite_start_buffering_from_context(TS_writer_p tswriter,
|
||
TS_context_p context);
|
||
/*
|
||
* Indicate to a TS output context that `input` is to be used as
|
||
* command input.
|
||
*
|
||
* This function may only be used if output is via TCP/IP.
|
||
*
|
||
* - `tswriter` is the TS output context returned by `tswrite_open`
|
||
* - `input` is the socket (or, on Linux/BSD, file descriptor) on which
|
||
* to listen for commands.
|
||
*
|
||
* Note that this should either be ``tswriter->where.socket`` or
|
||
* STDIN_FILENO - no other values are currently supported (particularly
|
||
* since no attempt is made to close this socket when things are finished,
|
||
* which doesn't matter for the given values).
|
||
*
|
||
* This function:
|
||
*
|
||
* - makes the socket on which data will be written non-blocking
|
||
* (i.e., if the socket is not ready to be written to, it will not
|
||
* accept input and block until it can be used, which means that it
|
||
* becomes our responsibility to ask if the socket is ready for output)
|
||
* - makes tswrite_write "look" on the `input` to see if a (single
|
||
* character) command has been given, and if it has, put it into
|
||
* the `tswriter` datastructure for use
|
||
*
|
||
* The command state is set to 'p'ause - i.e., as if the client had sent
|
||
* a COMMAND_PAUSE command.
|
||
*
|
||
* Returns 0 if all went well, 1 if something went wrong.
|
||
*/
|
||
extern int tswrite_start_input(TS_writer_p tswriter,
|
||
SOCKET input);
|
||
/*
|
||
* Set/unset "atomic" status - i.e., whether a command may be interrupted
|
||
* by the next command.
|
||
*
|
||
* Most commands (normal play, fast forwards, etc.) should be interrupted
|
||
* by a new command. However, some (the skip forwards and backwards commands)
|
||
* make sense only if they will always complete. This function allows that
|
||
* state to be toggled.
|
||
*/
|
||
extern void tswrite_set_command_atomic(TS_writer_p tswriter,
|
||
int atomic);
|
||
/*
|
||
* Ask a TS writer if changed input is available.
|
||
*
|
||
* If the TS writer is enabled for command input, then if the command
|
||
* currently being executed has declared itself "atomic" (i.e., not able to be
|
||
* interrupted), it returns FALSE, otherwise it returns TRUE if the command
|
||
* character has changed.
|
||
*/
|
||
extern int tswrite_command_changed(TS_writer_p tswriter);
|
||
/*
|
||
* Close a file or socket opened using `tswrite_open`, and if necessary,
|
||
* send the child process used for output buffering an end-of-file
|
||
* indicator, and wait for it to finish.
|
||
*
|
||
* - `tswriter` is the TS output context returned by `tswrite_open`
|
||
* - if `quiet` is true, then waiting for the child to exit should
|
||
* not be reported on (i.e., only errors should produce output)
|
||
*
|
||
* Returns 0 if all goes well, 1 if something went wrong.
|
||
*/
|
||
extern int tswrite_close(TS_writer_p tswriter,
|
||
int quiet);
|
||
|
||
/*
|
||
* Wait for a new command after 'p'ausing.
|
||
*
|
||
* - `tswriter` is the TS output context returned by `tswrite_open`
|
||
*
|
||
* Returns 0 if all went well, 1 if something went wrong.
|
||
*/
|
||
extern int wait_for_command(TS_writer_p tswriter);
|
||
|
||
/*
|
||
* Write a Transport Stream packet out via the TS writer.
|
||
*
|
||
* - `tswriter` is the TS output context returned by `tswrite_open`
|
||
* - `packet` is the TS packet
|
||
* - if the packets payload_unit_start_indicator is set, then
|
||
* `pid` is the PID for this packet, `got_pcr` is TRUE if it
|
||
* contains a PCR in its adaptation field, and `pcr` contains
|
||
* said PCR. These values are only used when outputting via
|
||
* buffered output.
|
||
*
|
||
* Returns 0 if all goes well, 1 if something went wrong, and EOF if command
|
||
* input is enabled (only allowed for TCP/IP output) and the 'q'uit command
|
||
* has been given (in which case, no further commands will be read, and no
|
||
* more output will be written, by any subsequent calls of this function).
|
||
*/
|
||
extern int tswrite_write(TS_writer_p tswriter,
|
||
byte packet[TS_PACKET_SIZE],
|
||
uint32_t pid,
|
||
int got_pcr,
|
||
uint64_t pcr);
|
||
|
||
extern int tswrite_discontinuity(const TS_writer_p tswriter);
|
||
|
||
/*
|
||
* Write a usage string (to standard output) describing the tuning
|
||
* options processed by tswrite_process_args.
|
||
*/
|
||
extern void tswrite_help_tuning(void);
|
||
/*
|
||
* Write a usage string (to standard output) describing the testing
|
||
* options processed by tswrite_process_args.
|
||
*/
|
||
extern void tswrite_help_testing(void);
|
||
/*
|
||
* Write a usage string (to standard output) describing the
|
||
* debugging options processed by tswrite_process_args.
|
||
*/
|
||
extern void tswrite_help_debug(void);
|
||
/*
|
||
* Report on the values within our argument context.
|
||
*
|
||
* Also reports on the various global/debug values.
|
||
*
|
||
* Note that it is up to the caller to ensure that they *use* all
|
||
* the values reported on here!
|
||
*/
|
||
extern void tswrite_report_args(TS_context_p context);
|
||
/*
|
||
* Various command line switches that are useful for tswrite are really
|
||
* only interpretable by tswrite itself. Thus we provide a function that
|
||
* will process such switches.
|
||
*
|
||
* This function extracts appropriate switches from `argv`, and returns it
|
||
* altered appropriately.
|
||
*
|
||
* - `prefix` is a prefix for any error messages - typically the
|
||
* short name of the program running.
|
||
* - `argc` and `argv` are as passed to `main`. After
|
||
* this function has finished, any arguments that it has processed will have
|
||
* had their `argv` array elements changed to point to the string
|
||
* "<processed>" (this is defined as the string TSWRITE_PROCESSED in the
|
||
* tswrite.h header file).
|
||
* - values are set in `context` to indicate the user's requests,
|
||
* and also any appropriate defaults.
|
||
*
|
||
* Note that `tswrite_print_usage` may be used to print out a description of
|
||
* the switches processed by this function.
|
||
*
|
||
* Returns 0 if all goes well, 1 if there was an error. Note that not
|
||
* specifying an output file or host counts as an error.
|
||
*/
|
||
extern int tswrite_process_args(char *prefix,
|
||
int argc,
|
||
char *argv[],
|
||
TS_context_p context);
|
||
|
||
|
||
#endif // _tswrite_fns
|
||
|
||
// Local Variables:
|
||
// tab-width: 8
|
||
// indent-tabs-mode: nil
|
||
// c-basic-offset: 2
|
||
// End:
|
||
// vim: set tabstop=8 shiftwidth=2 expandtab:
|