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 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
|
/*
* Functions 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_fns
#define _pes_fns
#include "pes_defns.h"
#include "es_defns.h"
/*
* Free a PES packet datastructure
*
* - `data` is the PES packet datastructure, which will be freed,
* and returned as NULL.
*/
extern void free_PES_packet_data(PES_packet_data_p *data);
/*
* Look at the start of a file to determine if it appears to be transport
* stream. Rewinds the file when it is finished.
*
* The file is assumed to be Transport Stream if it starts with 0x47 as
* the first byte, and 0x47 recurs at 188 byte intervals (in other words,
* it appears to start with several TS packets).
*
* - `input` is the file to check
* - `is_TS` is TRUE if it looks like TS, as described above.
*
* Returns 0 if all goes well, 1 if there was an error.
*/
extern int determine_if_TS_file(int input,
int *is_TS);
/*
* Build a PES reader datastructure for PS data
*
* - `ps` is the Program Stream to read the PES data from
* - `give_info` is TRUE if information about program data, etc., should be
* output (to stdout).
* - `give_warnings` is TRUE if warnings (starting with "!!!") should be
* output (to stderr), FALSE if they should be suppressed.
* - `reader` is the resulting PES reader
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int build_PS_PES_reader(PS_reader_p ps,
int give_info,
int give_warnings,
PES_reader_p *reader);
/*
* Build a PES reader datastructure for TS data
*
* - `tsreader` is the Transport Stream to read the PES data from
* - `give_info` is TRUE if information about program data, etc., should be
* output (to stdout).
* - `give_warnings` is TRUE if warnings (starting with "!!!") should be
* output (to stderr), FALSE if they should be suppressed.
* - `program_number` is only used for TS data, and identifies which program
* to read. If this is 0 then the first program encountered in the first PAT
* will be read.
* - `reader` is the resulting PES reader
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int build_TS_PES_reader(TS_reader_p tsreader,
int give_info,
int give_warnings,
uint16_t program_number,
PES_reader_p *reader);
/*
* Build a PES reader datastructure
*
* - `input` is the file to read the PES data from
* - `is_TS` should be TRUE if the data is TS, FALSE if it is PS
* - `give_info` is TRUE if information about program data, etc., should be
* output (to stdout).
* - `give_warnings` is TRUE if warnings (starting with "!!!") should be
* output (to stderr), FALSE if they should be suppressed.
* - `program_number` is only used for TS data, and identifies which program
* to read. If this is 0 then the first program encountered in the first PAT
* will be read.
* - `reader` is the resulting PES reader
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int build_PES_reader(int input,
int is_TS,
int give_info,
int give_warnings,
uint16_t program_number,
PES_reader_p *reader);
/*
* Open a Transport Stream file for PES packet reading
*
* - `filename` is the name of the file to open.
* - `program_number` identifies which program to read. If this is 0
* then the first program encountered in the first PAT will be read.
* - `give_info` is TRUE if information about program data, etc., should be
* output (to stdout). If information messages are requested, and the
* program number is given as 0, the actual program number chosen will
* be reported as well.
* - `give_warnings` is TRUE if warnings (starting with "!!!") should be
* output (to stderr), FALSE if they should be suppressed.
* - `reader` is the PES reader context corresponding to the newly
* opened file.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int open_PES_reader_for_TS(char *filename,
uint16_t program_number,
int give_info,
int give_warnings,
PES_reader_p *reader);
/*
* Open a Program Stream file for PES packet reading
*
* - `filename` is the name of the file to open.
* - `give_info` is TRUE if information about program data, etc., should be
* output (to stdout).
* - `give_warnings` is TRUE if warnings (starting with "!!!") should be
* output (to stderr), FALSE if they should be suppressed.
* - `reader` is the PES reader context corresponding to the newly
* opened file.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int open_PES_reader_for_PS(char *filename,
int give_info,
int give_warnings,
PES_reader_p *reader);
/*
* Open a Program Stream or Transport Stream file for PES packet reading
*
* - `filename` is the name of the file to open.
* - `give_info` is TRUE if information about program data, etc., should be
* output (to stdout).
* - `give_warnings` is TRUE if warnings (starting with "!!!") should be
* output (to stderr), FALSE if they should be suppressed.
* - `reader` is the PES reader context corresponding to the newly
* opened file.
*
* If the file is Transport Stream, then this is equivalent to a call
* of::
*
* err = open_PES_reader_for_TS(filename,0,give_info,give_warnings,&reader);
*
* i.e., the first program found is the program that will be read.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int open_PES_reader(char *filename,
int give_info,
int give_warnings,
PES_reader_p *reader);
/*
* Tell the PES reader whether we only want video data
*
* - `video_only` should be TRUE if audio is to be ignored, FALSE
* if audio should be retained.
*
* By default, the PES reader returns video data and a single audio
* stream (taken from the first audio stream encountered).
*/
extern void set_PES_reader_video_only(PES_reader_p reader,
int video_only);
/*
* Tell the PES reader which audio stream we want.
*
* By default, the PES reader returns video data and a single audio
* stream (taken from the first audio stream encountered).
*
* - `reader` is the PES reader context
* - `stream_number` is the number of the audio stream to read, from
* 0 to 31 (0x1F).
*
* This call only has effect if the input data is PS.
*
* Returns 0 if all went well, or 1 if there was an error (specifically,
* that `stream_number` was not in the range 0-31).
*/
extern int set_PES_reader_audio_stream(PES_reader_p reader,
int stream_number);
/*
* Tell the PES reader to get its audio stream from private stream 1
* (this is the stream that is conventionally used for Dolby in DVD data).
*
* By default, the PES reader returns video data and a single audio
* stream (taken from the first audio stream encountered).
*
* - `reader` is the PES reader context
*
* This call only has effect if the input data is PS.
*/
extern void set_PES_reader_audio_private1(PES_reader_p reader);
/*
* Tell the PES reader to "pretend" it has read a PAT and PMT with
* the given program information.
*
* This is intended for use in setting up sensible values when reading
* PS data (which does not contain such information). It will silently
* do nothing for TS data.
*
* Note that calling it more than once is allowed - it will happily
* overwrite any previous values.
*
* - `reader` is the PES reader context
* - `program_number` is the program number to assume. If this is 0,
* then 1 will be used.
* - `pmt_pid` is the PID for the PMT we've pretended to read.
* - `video_pid` is the PID to assume for the video data
* - `audio_pid` is the PID to assume for the audio data (if any)
* - `pcr_pid` is the PID to assume for the PCR data - this will often
* be the same as the `video_pid`
*/
extern void set_PES_reader_program_data(PES_reader_p reader,
uint16_t program_number,
uint32_t pmt_pid,
uint32_t video_pid,
uint32_t audio_pid,
uint32_t pcr_pid);
/*
* Tell the PES reader that the PS data it is reading is MPEG-4/AVC,
* as opposed to MPEG-1/MPEG-2.
*/
extern void set_PES_reader_h264(PES_reader_p reader);
/*
* Tell the PES reader that the PS data it is reading is of
* type `video_type` (which is assumed to be a legitimate value
* such as VIDEO_H264, etc.)
*/
extern void set_PES_reader_video_type(PES_reader_p reader,
int video_type);
/*
* Tell the PES reader whether to output any Dolby (AC-3) audio data
* it may read using the DVB stream type (0x06) or the ATSC stream
* type (0x81).
*
* If it is reading TS data, then the default is to use whatever stream type
* the Dolby audio was read with.
*
* If it is reading PS data, then the default is to assume DVB data.
*
* This call only has effect if Dolby audio data is actually selected.
*/
extern void set_PES_reader_dolby_stream_type(PES_reader_p reader,
int is_dvb);
/*
* Reposition the PES reader to an earlier packet
*
* It is the caller's responsibility to choose a sensible `posn` to seek to.
*
* Note that using this to reposition in a PES reader does not affect any
* "higher" reading context using this PES reader - specifically, if data
* is being read via an ES reader, then calling this function directly
* will result in the ES reader losing its positional information.
*
* In this case, `seek_ES` should be called.
*
* - `reader` is the PES reader context
* - `posn` is a packet position obtained from an earlier PES packet
* datastructure (this should *not* be a random offset in the input
* file, as that will not in general work).
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int set_PES_reader_position(PES_reader_p reader,
offset_t posn);
/*
* Free a PES reader, and the relevant datastructures. Does not close
* the underlying file.
*
* - `reader` is the PES reader context. This will be freed, and
* returned as NULL.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int free_PES_reader(PES_reader_p *reader);
/*
* Close a PES reader, and free the relevant datastructures.
*
* - `reader` is the PES reader context. This will be freed, and
* returned as NULL.
*
* Returns 0 if all goes well, 1 if something goes wrong with closing the
* file (although in that case, the `reader` will still have been freed).
*/
extern int close_PES_reader(PES_reader_p *reader);
/*
* Return the next PES packet from the input file
*
* - `reader` is a PES reader context
*
* Returns 0 if all goes well, EOF if end of file is read, and 1 if
* something goes wrong.
*/
extern int read_next_PES_packet(PES_reader_p reader);
/*
* Given an MPEG-1 PES packet, determine the offset of the ES data.
*
* - `data` is the PES packet data, starting "00 00 01 <stream_id>
* <packet_length>"
* - `data_len` is the actual length of the data therein
*
* Returns the required offset (i.e., packet[offset] is the first byte
* of the ES data within the PES packet).
*/
extern int calc_mpeg1_pes_offset(byte *data, int data_len);
/*
* Read in the next PES packet that contains ES data we are interested in
* Ignores non-video packets.
*
* - `reader` is a PES reader context
*
* Returns 0 if all goes well, EOF if end of file is read, and 1 if
* something goes wrong.
*/
extern int read_next_PES_ES_packet(PES_reader_p reader);
/*
* If the given PES packet data contains a PTS field, return it
*
* - `data` is the data for this PES packet
* - `data_len` is its length
* - `got_pts` is TRUE if a PTS field was found, in which case
* - `pts` is that PTS value
*
* Returns 0 if all went well, 1 if an error occurs.
*/
extern int find_PTS_in_PES(byte data[],
int32_t data_len,
int *got_pts,
uint64_t *pts);
/*
* If the given PES packet data contains a DTS field, return it
*
* - `data` is the data for this PES packet
* - `data_len` is its length
* - `got_dts` is TRUE if a DTS field was found, in which case
* - `dts` is that DTS value
*
* Returns 0 if all went well, 1 if an error occurs.
*/
extern int find_DTS_in_PES(byte data[],
int32_t data_len,
int *got_dts,
uint64_t *dts);
/*
* If the given PES packet data contains a PTS and/or DTS field, return it
*
* - `data` is the data for this PES packet
* - `data_len` is its length
* - `got_pts` is TRUE if a PTS field was found, in which case
* - `pts` is that PTS value
* - `got_dts` is TRUE if a DTS field was found, in which case
* - `dts` is that DTS value
*
* Returns 0 if all went well, 1 if an error occurs.
*/
extern int find_PTS_DTS_in_PES(byte data[],
int32_t data_len,
int *got_pts,
uint64_t *pts,
int *got_dts,
uint64_t *dts);
/*
* If the given PES packet data contains an ESCR field, return it
*
* - `data` is the data for this PES packet
* - `data_len` is its length
* - `got_escr` is TRUE if an ESCR field was found, in which case
* - `escr` is that ESCR value
*
* Returns 0 if all went well, 1 if an error occurs.
*/
extern int find_ESCR_in_PES(byte data[],
int32_t data_len,
int *got_escr,
uint64_t *escr);
/*
* Decode a PTS or DTS value.
*
* - `bytes` is the 5 bytes containing the encoded PTS or DTS value
* - `required_guard` should be 2 for a PTS alone, 3 for a PTS before
* a DTS, or 1 for a DTS after a PTS
* - `value` is the PTS or DTS value as decoded
*
* Returns 0 if the PTS/DTS value is decoded successfully, 1 if an error occurs
*/
extern int decode_pts_dts(byte data[],
int required_guard,
uint64_t *value);
/*
* Encode a PTS or DTS.
*
* - `data` is the array of 5 bytes into which to encode the PTS/DTS
* - `guard_bits` are the required guard bits: 2 for a PTS alone, 3 for
* a PTS before a DTS, or 1 for a DTS after a PTS
* - `value` is the PTS or DTS value to be encoded
*/
extern void encode_pts_dts(byte data[],
int guard_bits,
uint64_t value);
/*
* Does the given PES packet contain a PTS?
*
* - `packet` is the PES packet datastructure
*
* Returns TRUE if it does, FALSE if it does not (or is in error)
*/
extern int PES_packet_has_PTS(PES_packet_data_p packet);
/*
* Report on the content of a PES packet - specifically, its header data.
*
* - `prefix` is a string to put before each line of output
* - `data` is the packet data, and `data_len` its length
* - `show_data` should be TRUE if the start of the data for each packet should
* be shown
*
* Returns 0 if all went well, 1 if an error occurs.
*/
extern int report_PES_data_array(char *prefix,
byte *data,
int data_len,
int show_data);
/*
* Report on the content of a PES packet.
*
* This gives a longer form of report than report_PES_data_array(), and
* can also present substream data for audio stream_types.
*
* - `stream_type` is the stream type of the data, or -1 if it is not
* known (i.e., if this packet is from PS data).
* - `payload` is the packet data.
* - `payload_len` is the actual length of the payload (for a TS packet,
* this will generally be less than the PES packet's length).
* - if `show_data_len` is non-0 then the data for the PES packet will
* also be shown, up to that length
*
* Returns 0 if all went well, 1 if something went wrong.
*/
extern void report_PES_data_array2(int stream_type,
byte *payload,
int payload_len,
int show_data_len);
// ============================================================
// Server support
// ============================================================
/*
* Packets can be written out to a client via a TS writer, as a
* "side effect" of reading them. The original mechanism was to
* write out PES packets (as TS) as they are read. This will work
* for PS or TS data, and writes out only those PES packets that
* have been read for video or audio data.
*
* An alternative, which will only work for TS input data, is
* to write out TS packets as they are read. This will write all
* TS packets to the client.
*
* - `reader` is our PES reader context
* - `tswriter` is the TS writer
* - if `write_PES`, then write PES packets out as they are read from
* the input, otherwise write TS packets.
* - `program_freq` is how often to write out program data (PAT/PMT)
* if we are writing PES data (if we are writing TS data, then the
* program data will be in the original TS packets)
*/
extern void set_server_output(PES_reader_p reader,
TS_writer_p tswriter,
int write_PES,
int program_freq);
/*
* Start packets being written out to a TS writer (again).
*
* If packets were already being written out, this does nothing.
*
* If set_server_output() has not been called to define a TS writer
* context, this will have no effect.
*
* If `reader` is NULL, nothing is done.
*/
extern void start_server_output(PES_reader_p reader);
/*
* Stop packets being written out to a TS writer.
*
* If packets were already not being written out, this does nothing.
*
* If set_server_output() has not been called to define a TS writer
* context, this will have no effect.
*
* If `reader` is NULL, nothing is done.
*/
extern void stop_server_output(PES_reader_p reader);
/*
* When outputting PES packets in "normal play" mode, add ``extra`` PES
* packets (of the same size as each real packet) to the output. This
* makes the amount of data output be about ``extra``+1 times the amount
* read (the discrepancy is due to any program data being written).
*
* This "expansion" or "padding" of the data can be useful for benchmarking
* the recipient, as the extra data (which has an irrelevant stream id)
* will be ignored by the video processor, but not by preceding systems.
*
* This does nothing if TS packets are being output directly.
*
* - `reader` is our PES reader context
* - `extra` is how many extra packets to output per "real" packet.
*/
extern void set_server_padding(PES_reader_p reader,
int extra);
/*
* Write out TS program data based on the information we have within the given
* PES reader context (as amended by any calls of
* `set_PES_reader_program_data`).
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int write_program_data(PES_reader_p reader,
TS_writer_p output);
#endif // _pes_fns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab:
|