forked from kynesim/tstools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pes_defns.h
235 lines (206 loc) · 10.2 KB
/
pes_defns.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
* 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_t data_len; // The length of the `data` array [1]
int32_t 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_t 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
{
uint32_t *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.
uint32_t video_pid; // Zero if not yet known
uint32_t audio_pid; // Ditto
uint32_t pcr_pid; // A copy of the value from the PMT
uint16_t program_number; // Which program are we reading? (0=first)
uint32_t 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:
uint32_t output_video_pid;
uint32_t output_audio_pid;
uint32_t output_pcr_pid;
uint16_t output_program_number;
uint32_t 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;
// If the original data is TS, and we want to send *all* of said data
// to the server, it is sensible to write the *TS packets* as a side
// effect of reading, rather than the PES packets. Thus we also have
int write_TS_packets;
// Obviously, one assumes that we are not going to be doing both at
// the same time (since they write through the same tswriter interface)
// In either case, sometimes it is useful to suppress writing packets
// out for a while
int suppress_writing;
// 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: