F5OEO-tstools/pes_defns.h

225 wiersze
9.7 KiB
C
Czysty Wina Historia

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.

/*
* Datastructures for reading PES packets from TS or PS files
*
* ***** 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 _pes_defns
#define _pes_defns
#include "compat.h"
#include "pidint_defns.h"
#include "ps_defns.h"
#include "ts_defns.h"
#include "tswrite_defns.h"
// ------------------------------------------------------------
// A PES packet comes with some useful associated data
struct PES_packet_data
{
byte *data; // The actual packet data
int32 data_len; // The length of the `data` array [1]
int32 length; // Its length
offset_t posn; // The offset of its start in the file [2]
int is_video; // Is this video data? (as opposed to audio)
// For convenience, it's useful to be able to get at the PES packet's
// "payload" (i.e., the ES data) as if it were a separate array. This
// is, of course, just an offset into `data`
byte *es_data;
int32 es_data_len;
// The PES packet *does* tell us if its data starts with an ES packet
// (i.e., if the 00 00 01 bytes come as the first bytes in the data),
// so that's worth remembering
int data_alignment_indicator;
// Some applications want to know if a particular packet contains
// a PTS or not
int has_PTS;
};
// [1] For PS data, data_len and length will always be the same.
// For TS data, length is set when the first TS packet of the
// PES packet is read, and data_len gradually increases to length
// as "chunks" of the PES packet are read in
// [2] For TS data, this is actually the offset of the first TS packet
// containing the PES packet
typedef struct PES_packet_data *PES_packet_data_p;
#define SIZEOF_PES_PACKET_DATA sizeof(struct PES_packet_data)
// ------------------------------------------------------------
// An expandable list of PID vs. PES packet data
struct peslist
{
u_int32 *pid; // An array of the PIDs
PES_packet_data_p *data; // An array of the corresponding PES data
int length; // How many there are
int size; // How big the arrays are
};
typedef struct peslist *peslist_p;
#define SIZEOF_PESLIST sizeof(struct peslist)
#define PESLIST_START_SIZE 2 // Guess at one audio, one video
#define PESLIST_INCREMENT 1 // And a very conservative extension policy
// ------------------------------------------------------------
// A PES "reader" datastructure is the interface through which one reads
// PES packets from a TS or PS file
struct PES_reader
{
int is_TS; // Is it is TS (as opposed to PS)?
// If it is TS, we read via a TS read-ahead buffer
TS_reader_p tsreader;
// If it is PS, we read via a PS read-ahead buffer
PS_reader_p psreader;
int give_info; // Should information messages be output?
int give_warning; // Should warning messages be output (to stderr)?
PES_packet_data_p packet; // The current PES packet
// When reading PS packets, `posn` is the position of the current (or last)
// PS or TS packet.
offset_t posn;
// For PS data, we need to know if it is H.264 (MPEG-4/AVC) or not
int is_h264; // for backwards compatibility
int video_type; // the actual (believed) video type
// For PS and TS, we can choose to ignore audio entirely
int video_only;
// For PS, if we're not ignoring audio, we either look for a specific
// audio stream id (specified by the user), or we will take the first
// we find that is not Dolby. This latter is indicated by audio_stream
// being set to 0
byte audio_stream_id; // If not, the stream id of the audio we want
// When reading TS data, we need the program information to make sense
// of what is going on
int got_program_data; // Do we know our program data yet?
pmt_p program_map; // The content of the (current/last) PMT
// And from that, we can work out our video and audio (if any) pids, etc.
u_int32 video_pid; // Zero if not yet known
u_int32 audio_pid; // Ditto
u_int32 pcr_pid; // A copy of the value from the PMT
u_int16 program_number; // Which program are we reading? (0=first)
u_int32 pmt_pid; // What's the PMT PID?
// PMTs may be split over several TS packets, so we need a buffer
// to build them in
byte *pmt_data; // The buffer (NULL when not in use)
int pmt_data_len; // The buffers length = the PMT section length + 3
int pmt_data_used; // How much of said data we've already got
// In order to write out TS data, we also need program information.
// Obviously, the simplest case is when reading TS and writing it out
// again, with the same settings. However, we also have to cope with
// reading in PS data (which has no TS program information), and writing
// out TS data with *different* program information.
// If we're reading TS data, the default is to use the program data we
// find therein. If `override_program_data` is TRUE, then we ignore that,
// and use the values given by the user instead.
int override_program_data;
// Regardless, the following are the values to use when writing TS data out:
u_int32 output_video_pid;
u_int32 output_audio_pid;
u_int32 output_pcr_pid;
u_int16 output_program_number;
u_int32 output_pmt_pid;
// If we're reading Dolby (AC-3) audio, then there are two choices for the
// stream type. DVB uses stream type 0x06, and ATSC uses stream type 0x81.
byte dolby_stream_type; // The Dolby stream type we read (if any)
byte output_dolby_stream_type;
int override_dolby_stream_type; // Override whatever we read
// Before we can write out TS data, we need some basic program information.
// This is read in automatically if the input is TS, and must be supplied
// by the user (via set_PES_reader_program_data) if the input is PS.
// When reading a TS file, more than one PES packet may be being built
// at the same time. At any time, the "next" read PES packet will be the
// first one to be completely read in
peslist_p packets; // The packets currently being read
// If we are reading TS, and a PES packet has a declared length of 0,
// then it can only be ended by the *next* PES packet of the same PID
// (or by EOF, of course). In this case, we want to return the newly
// ended PES packet, and the *next* read request should continue
// with the PES packet we hadn't yet finished with. However, it is
// technically possible (although unlikely) that the new (just started)
// PES packet will end in its first TS packet. In that case, we want
// to return *it* next time we try to read a TS packet. To facilitate
// that, we can remember it here...
PES_packet_data_p deferred;
// If we ended such a packet on EOF, it's moderately convenient to
// remember that we had found EOF, rather than try to bump into it again
int had_eof;
// When being used by a server, we want PES packets to be written out
// as a "side effect" of reading them in to analyse their contents.
// Thus we provide:
int write_PES_packets; // TRUE if to write them out to:
TS_writer_p tswriter; // this TS writer context
int program_freq; // how often to write PAT/PMT out
int program_index; // how long since we last did so
// Sometimes, for instance when going from fast forwards to normal playing,
// we've already output the (end of) the current PES packet by hand, and
// thus don't want the automated server mechanism to output it for us.
// It's thus useful to have a flag indicating this (which will be unset
// as soon as the current PES packet has, indeed, not been written out)
// Since this is (definitely) an internal detail, it must be set explicitly.
int dont_write_current_packet;
// For benchmarking purposes (of the recipient), it can be useful to be able
// to "pad out" the data we're sending, so that it is <n> times as big. If
// ``expand`` is greater than 0, then ``expand`` "dummy" PES packets (of the
// same size as the real one) will be output for each real PES packet (but
// with an irrelevant stream id).
int pes_padding;
// Debugging: if this is set, and the appropriate code is compiled into
// pes.c (see DEBUG_READ_PACKETS), then report on each PES packet read
// and written. Even if DEBUG_READ_PACKETS is not defined, some output
// will be produced.
int debug_read_packets;
};
typedef struct PES_reader *PES_reader_p;
#define SIZEOF_PES_READER sizeof(struct PES_reader)
// Given the PES packet data (i.e., the data starting 00 00 01 <stream_id>
// <packet_length>), decide if this PES packet is MPEG-1 (11172-1) or
// H.222.0 (13818-1)
#define IS_H222_PES(data) ((data[6] & 0xC0) == 0x80)
#endif // _pes_defns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab: