1 /* 2 * Datastructures for reading PES packets from TS or PS files 3 * 4 * ***** BEGIN LICENSE BLOCK ***** 5 * Version: MPL 1.1 6 * 7 * The contents of this file are subject to the Mozilla Public License Version 8 * 1.1 (the "License"); you may not use this file except in compliance with 9 * the License. You may obtain a copy of the License at 10 * http://www.mozilla.org/MPL/ 11 * 12 * Software distributed under the License is distributed on an "AS IS" basis, 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 14 * for the specific language governing rights and limitations under the 15 * License. 16 * 17 * The Original Code is the MPEG TS, PS and ES tools. 18 * 19 * The Initial Developer of the Original Code is Amino Communications Ltd. 20 * Portions created by the Initial Developer are Copyright (C) 2008 21 * the Initial Developer. All Rights Reserved. 22 * 23 * Contributor(s): 24 * Amino Communications Ltd, Swavesey, Cambridge UK 25 * 26 * ***** END LICENSE BLOCK ***** 27 */ 28 29 #ifndef _pes_defns 30 #define _pes_defns 31 32 #include "compat.h" 33 #include "pidint_defns.h" 34 #include "ps_defns.h" 35 #include "ts_defns.h" 36 #include "tswrite_defns.h" 37 38 // ------------------------------------------------------------ 39 // A PES packet comes with some useful associated data 40 struct PES_packet_data 41 { 42 byte *data; // The actual packet data 43 int32_t data_len; // The length of the `data` array [1] 44 int32_t length; // Its length 45 offset_t posn; // The offset of its start in the file [2] 46 int is_video; // Is this video data? (as opposed to audio) 47 48 // For convenience, it's useful to be able to get at the PES packet's 49 // "payload" (i.e., the ES data) as if it were a separate array. This 50 // is, of course, just an offset into `data` 51 byte *es_data; 52 int32_t es_data_len; 53 // The PES packet *does* tell us if its data starts with an ES packet 54 // (i.e., if the 00 00 01 bytes come as the first bytes in the data), 55 // so that's worth remembering 56 int data_alignment_indicator; 57 58 // Some applications want to know if a particular packet contains 59 // a PTS or not 60 int has_PTS; 61 }; 62 // [1] For PS data, data_len and length will always be the same. 63 // For TS data, length is set when the first TS packet of the 64 // PES packet is read, and data_len gradually increases to length 65 // as "chunks" of the PES packet are read in 66 // [2] For TS data, this is actually the offset of the first TS packet 67 // containing the PES packet 68 typedef struct PES_packet_data *PES_packet_data_p; 69 #define SIZEOF_PES_PACKET_DATA sizeof(struct PES_packet_data) 70 71 // ------------------------------------------------------------ 72 // An expandable list of PID vs. PES packet data 73 struct peslist 74 { 75 uint32_t *pid; // An array of the PIDs 76 PES_packet_data_p *data; // An array of the corresponding PES data 77 int length; // How many there are 78 int size; // How big the arrays are 79 }; 80 typedef struct peslist *peslist_p; 81 #define SIZEOF_PESLIST sizeof(struct peslist) 82 83 #define PESLIST_START_SIZE 2 // Guess at one audio, one video 84 #define PESLIST_INCREMENT 1 // And a very conservative extension policy 85 86 // ------------------------------------------------------------ 87 // A PES "reader" datastructure is the interface through which one reads 88 // PES packets from a TS or PS file 89 struct PES_reader 90 { 91 int is_TS; // Is it is TS (as opposed to PS)? 92 93 // If it is TS, we read via a TS read-ahead buffer 94 TS_reader_p tsreader; 95 // If it is PS, we read via a PS read-ahead buffer 96 PS_reader_p psreader; 97 98 int give_info; // Should information messages be output? 99 int give_warning; // Should warning messages be output (to stderr)? 100 101 PES_packet_data_p packet; // The current PES packet 102 103 // When reading PS packets, `posn` is the position of the current (or last) 104 // PS or TS packet. 105 offset_t posn; 106 107 // For PS data, we need to know if it is H.264 (MPEG-4/AVC) or not 108 int is_h264; // for backwards compatibility 109 int video_type; // the actual (believed) video type 110 111 // For PS and TS, we can choose to ignore audio entirely 112 int video_only; 113 // For PS, if we're not ignoring audio, we either look for a specific 114 // audio stream id (specified by the user), or we will take the first 115 // we find that is not Dolby. This latter is indicated by audio_stream 116 // being set to 0 117 byte audio_stream_id; // If not, the stream id of the audio we want 118 119 // When reading TS data, we need the program information to make sense 120 // of what is going on 121 int got_program_data; // Do we know our program data yet? 122 pmt_p program_map; // The content of the (current/last) PMT 123 // And from that, we can work out our video and audio (if any) pids, etc. 124 uint32_t video_pid; // Zero if not yet known 125 uint32_t audio_pid; // Ditto 126 uint32_t pcr_pid; // A copy of the value from the PMT 127 uint16_t program_number; // Which program are we reading? (0=first) 128 uint32_t pmt_pid; // What's the PMT PID? 129 130 // PMTs may be split over several TS packets, so we need a buffer 131 // to build them in 132 byte *pmt_data; // The buffer (NULL when not in use) 133 int pmt_data_len; // The buffers length = the PMT section length + 3 134 int pmt_data_used; // How much of said data we've already got 135 136 // In order to write out TS data, we also need program information. 137 // Obviously, the simplest case is when reading TS and writing it out 138 // again, with the same settings. However, we also have to cope with 139 // reading in PS data (which has no TS program information), and writing 140 // out TS data with *different* program information. 141 // If we're reading TS data, the default is to use the program data we 142 // find therein. If `override_program_data` is TRUE, then we ignore that, 143 // and use the values given by the user instead. 144 int override_program_data; 145 // Regardless, the following are the values to use when writing TS data out: 146 uint32_t output_video_pid; 147 uint32_t output_audio_pid; 148 uint32_t output_pcr_pid; 149 uint16_t output_program_number; 150 uint32_t output_pmt_pid; 151 152 // If we're reading Dolby (AC-3) audio, then there are two choices for the 153 // stream type. DVB uses stream type 0x06, and ATSC uses stream type 0x81. 154 byte dolby_stream_type; // The Dolby stream type we read (if any) 155 byte output_dolby_stream_type; 156 int override_dolby_stream_type; // Override whatever we read 157 158 // Before we can write out TS data, we need some basic program information. 159 // This is read in automatically if the input is TS, and must be supplied 160 // by the user (via set_PES_reader_program_data) if the input is PS. 161 162 // When reading a TS file, more than one PES packet may be being built 163 // at the same time. At any time, the "next" read PES packet will be the 164 // first one to be completely read in 165 peslist_p packets; // The packets currently being read 166 167 // If we are reading TS, and a PES packet has a declared length of 0, 168 // then it can only be ended by the *next* PES packet of the same PID 169 // (or by EOF, of course). In this case, we want to return the newly 170 // ended PES packet, and the *next* read request should continue 171 // with the PES packet we hadn't yet finished with. However, it is 172 // technically possible (although unlikely) that the new (just started) 173 // PES packet will end in its first TS packet. In that case, we want 174 // to return *it* next time we try to read a TS packet. To facilitate 175 // that, we can remember it here... 176 PES_packet_data_p deferred; 177 178 // If we ended such a packet on EOF, it's moderately convenient to 179 // remember that we had found EOF, rather than try to bump into it again 180 int had_eof; 181 182 // When being used by a server, we want PES packets to be written out 183 // as a "side effect" of reading them in to analyse their contents. 184 // Thus we provide: 185 int write_PES_packets; // TRUE if to write them out to: 186 TS_writer_p tswriter; // this TS writer context 187 int program_freq; // how often to write PAT/PMT out 188 int program_index; // how long since we last did so 189 // Sometimes, for instance when going from fast forwards to normal playing, 190 // we've already output the (end of) the current PES packet by hand, and 191 // thus don't want the automated server mechanism to output it for us. 192 // It's thus useful to have a flag indicating this (which will be unset 193 // as soon as the current PES packet has, indeed, not been written out) 194 // Since this is (definitely) an internal detail, it must be set explicitly. 195 int dont_write_current_packet; 196 // For benchmarking purposes (of the recipient), it can be useful to be able 197 // to "pad out" the data we're sending, so that it is <n> times as big. If 198 // ``expand`` is greater than 0, then ``expand`` "dummy" PES packets (of the 199 // same size as the real one) will be output for each real PES packet (but 200 // with an irrelevant stream id). 201 int pes_padding; 202 203 // If the original data is TS, and we want to send *all* of said data 204 // to the server, it is sensible to write the *TS packets* as a side 205 // effect of reading, rather than the PES packets. Thus we also have 206 int write_TS_packets; 207 // Obviously, one assumes that we are not going to be doing both at 208 // the same time (since they write through the same tswriter interface) 209 210 // In either case, sometimes it is useful to suppress writing packets 211 // out for a while 212 int suppress_writing; 213 214 // Debugging: if this is set, and the appropriate code is compiled into 215 // pes.c (see DEBUG_READ_PACKETS), then report on each PES packet read 216 // and written. Even if DEBUG_READ_PACKETS is not defined, some output 217 // will be produced. 218 int debug_read_packets; 219 }; 220 typedef struct PES_reader *PES_reader_p; 221 #define SIZEOF_PES_READER sizeof(struct PES_reader) 222 223 // Given the PES packet data (i.e., the data starting 00 00 01 <stream_id> 224 // <packet_length>), decide if this PES packet is MPEG-1 (11172-1) or 225 // H.222.0 (13818-1) 226 #define IS_H222_PES(data) ((data[6] & 0xC0) == 0x80) 227 228 #endif // _pes_defns 229 230 // Local Variables: 231 // tab-width: 8 232 // indent-tabs-mode: nil 233 // c-basic-offset: 2 234 // End: 235 // vim: set tabstop=8 shiftwidth=2 expandtab: 236