F5OEO-tstools/ps_fns.h

359 wiersze
13 KiB
C

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

/*
* Functions for working with H.222 Program Stream packets - in particular,
* for reading PES packets.
*
* ***** 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 _ps_fns
#define _ps_fns
#include "compat.h"
#include "h222_defns.h"
#include "tswrite_defns.h"
#include "ps_defns.h"
// ============================================================
// Program stream reading functions
// ============================================================
/*
* Build a program stream context attached to an input file. This handles
* read-ahead buffering for the PS.
*
* - `input` is the file stream to read from.
* - If `quiet`, then don't report on ignored bytes at the start of the file
* - `ps` is the new PS context
*
* Returns 0 if all goes well, 1 otherwise.
*/
extern int build_PS_reader(int input,
int quiet,
PS_reader_p *ps);
/*
* Tidy up the PS read-ahead context after we've finished with it.
*
* Specifically:
*
* - free the datastructure
* - set `ps` to NULL
*
* Does not close the associated file.
*/
extern void free_PS_reader(PS_reader_p *ps);
/*
* Open a PS file for reading.
*
* - `name` is the name of the file
* - If `quiet`, then don't report on ignored bytes at the start of the file
* - `ps` is the new PS context
*
* Returns 0 if all goes well, 1 otherwise.
*/
extern int open_PS_file(char *name,
int quiet,
PS_reader_p *ps);
/*
* Close a PS file, and free the reader context
*
* Returns 0 if all goes well, 1 otherwise.
*/
extern int close_PS_file(PS_reader_p *ps);
/*
* Given a program stream, attempt to determine if it holds H.262 or H.264
* data.
*
* Leaves the PS rewound to its "start".
*
* NOTE: It is probably better to use determine_PS_video_type().
*
* - `ps` is the program stream to check (assumed just to have been
* opened/built). This cannot be standard input, as it must be
* seekable.
* - `is_h264` is the result
*
* Returns 0 if all goes well, 1 if there was an error (including the
* stream not appearing to be either).
*/
extern int determine_if_PS_is_h264(PS_reader_p ps,
int *is_h264);
/*
* Given a program stream, attempt to determine what type of video data it
* contains.
*
* Leaves the PS rewound to its "start".
*
* - `ps` is the program stream to check (assumed just to have been
* opened/built). This cannot be standard input, as it must be
* seekable.
* - `video_type` is the result. Calls determine_PES_video_type().
*
* Returns 0 if all goes well, 1 if there was an error (including the
* stream not appearing to be either).
*/
extern int determine_PS_video_type(PS_reader_p ps,
int *video_type);
/*
* Seek within the PS file.
*
* Note that if the intent is to *rewind* to the start of the PS data,
* then `rewind_program_stream` should be used instead, as offset 0 is
* not necessarily the same as the start of the program stream.
*
* - `ps` is the PS read-ahead context
* - `posn` is the file offset to seek to
*
* Returns 0 if all goes well, 1 if something goes wrong
*/
extern int seek_using_PS_reader(PS_reader_p ps,
offset_t posn);
/*
* Rewind the PS context to the remembered "start of data"
*
* Returns 0 if all goes well, 1 if something goes wrong
*/
extern int rewind_program_stream(PS_reader_p ps);
/*
* Print out a stream id in a manner consistent with the PS usages
* of the stream id values.
*/
extern void print_stream_id(int is_msg,
byte stream_id);
/*
* Look for the start (the first 4 bytes) of the next program stream packet.
*
* Assumes that (for some reason) alignment has been lost, and thus it is
* necessary to scan forwards to find the next 00 00 01 prefix.
*
* Otherwise equivalent to a call of `read_PS_packet_start`.
*
* - `ps` is the PS read-ahead context we're reading from
* - if `verbose`, then we want to explain what we're doing
* - if `max` is non-zero, then it is the maximum number of bytes
* to scan before giving up.
* - `posn` is the file offset of the start of the packet
* - `stream_id` is the identifying byte, after the 00 00 01 prefix. Note
* that this is set correctly if MPEG_program_end_code was read, and is
* 0 if an error occurred.
*
* Returns:
* * 0 if it succeeds,
* * EOF if EOF is read, or an MPEG_program_end_code is read, or
* * 1 if some error (including the first 3 bytes not being 00 00 01) occurs.
*/
extern int find_PS_packet_start(PS_reader_p ps,
int verbose,
uint32_t max,
offset_t *posn,
byte *stream_id);
/*
* Look for the next PS pack header.
*
* Equivalent to calling `find_PS_packet_start` until `stream_id` is 0xBA
* (in other words, equivalent to having read the pack header start with
* `read_PS_packet_start`).
*
* If you want to call `read_PS_packet_start` to read this pack header start
* in again, then call ``seek_using_PS_reader(ps,posn)`` to reposition ready
* to read it.
*
* - `ps` is the PS read-ahead context we're reading from
* - if `verbose`, then the 00 00 01 XX sequences found will be logged
* to stderr, indicating the progress of our search
* - if `max` is non-zero, then it is the maximum number of bytes
* to scan before giving up.
* - `posn` is the file offset of the start of the packet found
*
* Returns:
* * 0 if it succeeds,
* * EOF if EOF is read, or an MPEG_program_end_code is read, or
* * 1 if some error (including the first 3 bytes not being 00 00 01) occurs.
*/
extern int find_PS_pack_header_start(PS_reader_p ps,
int verbose,
uint32_t max,
offset_t *posn);
/*
* Read in (the rest of) a PS packet according to its length.
*
* Suitable for use reading PS PES packets and PS system header packets.
*
* NOTE that the `data` buffer in the `packet` is realloc'ed by this
* function. It is thus important to ensure that the `packet` datastructure
* contains a NULL pointer for said buffer before the first call of this
* function.
*
* - `ps` is the PS read-ahead context we're reading from
* - `stream_id` identifies what sort of packet it is
* - `packet` is the packet we're reading the PES packet into.
*
* Returns 0 if it succeeds, 1 if some error occurs.
*/
extern int read_PS_packet_body(PS_reader_p ps,
byte stream_id,
PS_packet_p packet);
/*
* Read in the body of the pack header (but *not* the system header packets
* therein).
*
* - `ps` is the PS read-ahead context we're reading from
* - `hdr` is the packet we've read
*
* Returns 0 if it succeeds, or 1 if some error occurs.
*/
extern int read_PS_pack_header_body(PS_reader_p ps,
PS_pack_header_p hdr);
/*
* Clear the contents of a PS packet datastructure. Frees the internal
* `data` array.
*/
extern void clear_PS_packet(PS_packet_p packet);
/*
* Tidy up and free a PS packet datastructure after we've finished with it.
*
* Empties the PS packet datastructure, frees it, and sets `unit` to NULL.
*
* If `unit` is already NULL, does nothing.
*/
extern void free_PS_packet(PS_packet_p *packet);
/*
* Read in the start (the first 4 bytes) of the next program stream packet.
*
* If the bytes read don't appear to be valid (i.e., they do not start with
* the 00 00 01 prefix), then the next pack header will be sought and read in.
*
* Note that sequences of 00 bytes before the 00 00 01 will be ignored.
*
* - `ps` is the PS read-ahead context we're reading from
* - if `verbose`, then we want to explain what we're doing
* - `posn` is the file offset of the start of the packet
* - `stream_id` is the identifying byte, after the 00 00 01 prefix. Note
* that this is set correctly if MPEG_program_end_code was read, and is
* 0 if an error occurred or reading was ended because `max` packets had
* been read.
*
* Returns:
* * 0 if it succeeds,
* * EOF if EOF is read, or an MPEG_program_end_code is read,
* * 2 if the bytes read are not 00 00 01 `stream_id`, or
* * 1 if some other error occurs.
*/
extern int read_PS_packet_start(PS_reader_p ps,
int verbose,
offset_t *posn,
byte *stream_id);
/*
* Inspect the given PS packet, and determine if it contains AC3 or DTS audio data.
*
* - `packet` is the packet's data, already established as private_data_1
* - `is_dvd` is true if the data should be interpreted as DVD data
* - if `verbose`, report on the details of what we find out
* - `substream_index` returns the substream's index, taken from the low
* nibble of the substream id, and adjusted to start at 0. This will be
* a value in the range 0-7 for DTS, AC3 and LPCM, and in the range 0-1F
* (0-31) for subpictures.
* - for AC3, `bsmod` and `acmod` return the appropriate quantities,
* otherwise they are 0.
*
* Returns one of the SUBSTREAM_* values.
*/
extern int identify_private1_data(struct PS_packet *packet,
int is_dvd,
int verbose,
int *substream_index,
byte *bsmod,
byte *acmod);
// ============================================================
// PS to TS functions
// ============================================================
/*
* Read program stream and write transport stream
*
* - `ps` is the program stream
* - `output` is the transport stream
* - `pad_start` is the number of filler TS packets to start the output
* with.
* - `program_repeat` is how often (after how many PS packs) to repeat
* the program information (PAT/PMT)
* - `video_type` indicates what type of video is being transferred. It should
* be VIDEO_H264, VIDEO_H262, etc.
* - `is_dvd` should be true if this input represents DVD data; i.e., with
* private_stream_1 used for AC-3/DTS/etc., and with substream headers
* therein.
* - `video_stream` indicates which video stream we want - i.e., the stream
* with id 0xE0 + <video_stream>. -1 means the first encountered.
* - `audio_stream` indicates which audio stream we want. If `want_ac3_audio`
* is false, then this will be the stream with id 0xC0 + <audio_stream>,
* or -1 for the first audio stream encountered.
* - if `want_ac3_audio` is true, then if `is_dvd` is true, then we want
* audio from private_stream_1 (0xBD) with substream id <audio_stream>,
* otherwise we ignore `audio_stream` and assume that all data in
* private_stream_1 is the audio we want.
* - `dolby_is_dvb` should be true if Dolby (AC-3) audio (if selected) should
* be output using the DVB stream type 0x06, false if using the ATSC stream
* type 0x81. This is ignored if the audio being output is not Dolby.
* - `pmt_pid` is the PID of the PMT to write
* - `pcr_pid` is the PID of the TS unit containing the PCR
* - `video_pid` is the PID for the video we write
* - `keep_audio` is true if the audio stream should be output, false if
* it should be ignored
* - `audio_pid` is the PID for the audio we write
* - if `max` is non-zero, then we want to stop reading after we've read
* `max` packs
* - if `verbose` then we want to output diagnostic information
* - if `quiet` then we want to be as quiet as we can
*
* Returns 0 if all went well, 1 if something went wrong.
*/
extern int ps_to_ts(PS_reader_p ps,
TS_writer_p output,
int pad_start,
int program_repeat,
int video_type,
int is_dvd,
int video_stream,
int audio_stream,
int want_ac3_audio,
int dolby_is_dvb,
uint32_t pmt_pid,
uint32_t pcr_pid,
uint32_t video_pid,
int keep_audio,
uint32_t audio_pid,
int max,
int verbose,
int quiet);
#endif // _ps_fns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab: