kopia lustrzana https://github.com/F5OEO/tstools
145 wiersze
5.6 KiB
C
145 wiersze
5.6 KiB
C
|
/*
|
||
|
* Datastructures for handling H.264 elementary streams.
|
||
|
*
|
||
|
* ***** 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 _es_defns
|
||
|
#define _es_defns
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include "compat.h"
|
||
|
#include "pes_defns.h"
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// A "file" offset in an ES stream, suitable for seeking to
|
||
|
// For an ES based on a "bare" file, the `infile` value is all that is needed
|
||
|
// For an ES based on a PES, the file offset of the PES packet and the byte
|
||
|
// offset within that packet's ES data are needed.
|
||
|
struct _ES_offset
|
||
|
{
|
||
|
offset_t infile; // as used by lseek
|
||
|
int32 inpacket;
|
||
|
};
|
||
|
typedef struct _ES_offset ES_offset;
|
||
|
typedef struct _ES_offset *ES_offset_p;
|
||
|
#define SIZEOF_ES_OFFSET sizeof(struct _ES_offset)
|
||
|
|
||
|
// The number of bytes to "read ahead" when reading directly from an
|
||
|
// elementary stream
|
||
|
#define ES_READ_AHEAD_SIZE 1000
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// A datastructure to represent our input elementary stream (ES)
|
||
|
// (*output* elementary streams shouldn't need any particular housekeeping)
|
||
|
struct elementary_stream
|
||
|
{
|
||
|
int reading_ES; // TRUE if we're reading ES data direct, FALSE if PES
|
||
|
|
||
|
// If we're reading from an elementary data stream directly, then
|
||
|
// we use the input directly
|
||
|
int input;
|
||
|
// And maintain a buffer of "read ahead" bytes
|
||
|
byte read_ahead[ES_READ_AHEAD_SIZE];
|
||
|
offset_t read_ahead_posn; // location of this data in the file
|
||
|
int32 read_ahead_len; // actual number of bytes in the buffer
|
||
|
|
||
|
// And the next byte to be read is specified by its offset in said
|
||
|
// data stream. For "bare" ES data, the `infile` value is used to
|
||
|
// remember the next bytes actual position in the file, and for PES
|
||
|
// based ES data, the `inpacket` value is used to remember the next
|
||
|
// bytes offset in the current PES packet. In both cases, the "unused"
|
||
|
// quantity in the ES_offset is undefined.
|
||
|
// (this is, in fact, more used by tsserve than by anything else)
|
||
|
ES_offset posn_of_next_byte;
|
||
|
|
||
|
// If we're reading from PES packets (from either a PS or TS file),
|
||
|
// then we need to remember our PES reader
|
||
|
PES_reader_p reader;
|
||
|
|
||
|
byte *data; // Where we're reading our bytes from
|
||
|
byte *data_end; // How to tell we've read them all
|
||
|
byte *data_ptr; // And which byte we're interested in
|
||
|
|
||
|
offset_t last_packet_posn; // Where the last PES packet was in the file
|
||
|
int32 last_packet_es_data_len; // And its number of ES bytes
|
||
|
|
||
|
// Regardless, our triple byte memory is the same
|
||
|
byte cur_byte; // The current (last read) byte
|
||
|
byte prev1_byte; // The previous byte
|
||
|
byte prev2_byte; // The byte before *that*
|
||
|
};
|
||
|
typedef struct elementary_stream *ES_p;
|
||
|
#define SIZEOF_ES sizeof(struct elementary_stream)
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// And a representation of a single unit from the elementary stream
|
||
|
// (whether an MPEG-2 (H.262) item, or an MPEG-4/AVC (H.264) NAL unit)
|
||
|
// - basically, the thing that starts with a 00 00 01 prefix, and continues
|
||
|
// to end of file or before the next 00 00 01 prefix (so note that it
|
||
|
// contains any "trailing" 00 bytes).
|
||
|
//
|
||
|
// The normal way to acquire such a datastructure is via `build_ES_unit()`,
|
||
|
// or `find_and_build_next_ES_unit()`. If instead you want to use the
|
||
|
// address of a `struct ES_unit`, it is imperative that it be set up
|
||
|
// correctly with `setup_ES_unit()` before it is passed to any of the
|
||
|
// functions that use it, otherwise the contents will not be valid (and,
|
||
|
// particularly, the "data" pointer will reference random memory).
|
||
|
struct ES_unit
|
||
|
{
|
||
|
ES_offset start_posn; // The start of the current data unit
|
||
|
byte *data; // Its data, including the leading 00 00 01
|
||
|
u_int32 data_len; // Its length
|
||
|
u_int32 data_size; // The total buffer size
|
||
|
|
||
|
byte start_code; // The byte after the 00 00 01 prefix
|
||
|
|
||
|
// Something of a hack - if we were reading PES, did any of the PES packets
|
||
|
// we read to make this ES unit contain a PTS?
|
||
|
byte PES_had_PTS;
|
||
|
};
|
||
|
typedef struct ES_unit *ES_unit_p;
|
||
|
#define SIZEOF_ES_UNIT sizeof(struct ES_unit)
|
||
|
|
||
|
// Start and increment sizes for the es_unit/data array.
|
||
|
#define ES_UNIT_DATA_START_SIZE 1000 // was 500
|
||
|
#define ES_UNIT_DATA_INCREMENT 500 // was 100
|
||
|
|
||
|
// ------------------------------------------------------------
|
||
|
// An expandable list of ES units
|
||
|
struct ES_unit_list
|
||
|
{
|
||
|
struct ES_unit *array; // The current array of ES units
|
||
|
int length; // How many there are
|
||
|
int size; // How big the array is
|
||
|
};
|
||
|
typedef struct ES_unit_list *ES_unit_list_p;
|
||
|
#define SIZEOF_ES_UNIT_LIST sizeof(struct ES_unit_list)
|
||
|
|
||
|
#define ES_UNIT_LIST_START_SIZE 20
|
||
|
#define ES_UNIT_LIST_INCREMENT 20
|
||
|
|
||
|
#endif // _es_defns
|