1 /* 2 * Datastructures for handling H.264 elementary streams. 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 _es_defns 30 #define _es_defns 31 32 #include <stdio.h> 33 #include "compat.h" 34 #include "pes_defns.h" 35 36 // ------------------------------------------------------------ 37 // A "file" offset in an ES stream, suitable for seeking to 38 // For an ES based on a "bare" file, the `infile` value is all that is needed 39 // For an ES based on a PES, the file offset of the PES packet and the byte 40 // offset within that packet's ES data are needed. 41 struct _ES_offset 42 { 43 offset_t infile; // as used by lseek 44 int32_t inpacket; 45 }; 46 typedef struct _ES_offset ES_offset; 47 typedef struct _ES_offset *ES_offset_p; 48 #define SIZEOF_ES_OFFSET sizeof(struct _ES_offset) 49 50 // The number of bytes to "read ahead" when reading directly from an 51 // elementary stream 52 #define ES_READ_AHEAD_SIZE 1000 53 54 // ------------------------------------------------------------ 55 // A datastructure to represent our input elementary stream (ES) 56 // (*output* elementary streams shouldn't need any particular housekeeping) 57 struct elementary_stream 58 { 59 int reading_ES; // TRUE if we're reading ES data direct, FALSE if PES 60 61 // If we're reading from an elementary data stream directly, then 62 // we use the input directly 63 int input; 64 // And maintain a buffer of "read ahead" bytes 65 byte read_ahead[ES_READ_AHEAD_SIZE]; 66 offset_t read_ahead_posn; // location of this data in the file 67 int32_t read_ahead_len; // actual number of bytes in the buffer 68 69 // And the next byte to be read is specified by its offset in said 70 // data stream. For "bare" ES data, the `infile` value is used to 71 // remember the next bytes actual position in the file, and for PES 72 // based ES data, the `inpacket` value is used to remember the next 73 // bytes offset in the current PES packet. In both cases, the "unused" 74 // quantity in the ES_offset is undefined. 75 // (this is, in fact, more used by tsserve than by anything else) 76 ES_offset posn_of_next_byte; 77 78 // If we're reading from PES packets (from either a PS or TS file), 79 // then we need to remember our PES reader 80 PES_reader_p reader; 81 82 byte *data; // Where we're reading our bytes from 83 byte *data_end; // How to tell we've read them all 84 byte *data_ptr; // And which byte we're interested in 85 86 offset_t last_packet_posn; // Where the last PES packet was in the file 87 int32_t last_packet_es_data_len; // And its number of ES bytes 88 89 // Regardless, our triple byte memory is the same 90 byte cur_byte; // The current (last read) byte 91 byte prev1_byte; // The previous byte 92 byte prev2_byte; // The byte before *that* 93 }; 94 typedef struct elementary_stream *ES_p; 95 #define SIZEOF_ES sizeof(struct elementary_stream) 96 97 // ------------------------------------------------------------ 98 // And a representation of a single unit from the elementary stream 99 // (whether an MPEG-2 (H.262) item, or an MPEG-4/AVC (H.264) NAL unit) 100 // - basically, the thing that starts with a 00 00 01 prefix, and continues 101 // to end of file or before the next 00 00 01 prefix (so note that it 102 // contains any "trailing" 00 bytes). 103 // 104 // The normal way to acquire such a datastructure is via `build_ES_unit()`, 105 // or `find_and_build_next_ES_unit()`. If instead you want to use the 106 // address of a `struct ES_unit`, it is imperative that it be set up 107 // correctly with `setup_ES_unit()` before it is passed to any of the 108 // functions that use it, otherwise the contents will not be valid (and, 109 // particularly, the "data" pointer will reference random memory). 110 struct ES_unit 111 { 112 ES_offset start_posn; // The start of the current data unit 113 byte *data; // Its data, including the leading 00 00 01 114 uint32_t data_len; // Its length 115 uint32_t data_size; // The total buffer size 116 117 byte start_code; // The byte after the 00 00 01 prefix 118 119 // Something of a hack - if we were reading PES, did any of the PES packets 120 // we read to make this ES unit contain a PTS? 121 byte PES_had_PTS; 122 }; 123 typedef struct ES_unit *ES_unit_p; 124 #define SIZEOF_ES_UNIT sizeof(struct ES_unit) 125 126 // Start and increment sizes for the es_unit/data array. 127 #define ES_UNIT_DATA_START_SIZE 1000 // was 500 128 #define ES_UNIT_DATA_INCREMENT 500 // was 100 129 130 // ------------------------------------------------------------ 131 // An expandable list of ES units 132 struct ES_unit_list 133 { 134 struct ES_unit *array; // The current array of ES units 135 int length; // How many there are 136 int size; // How big the array is 137 }; 138 typedef struct ES_unit_list *ES_unit_list_p; 139 #define SIZEOF_ES_UNIT_LIST sizeof(struct ES_unit_list) 140 141 #define ES_UNIT_LIST_START_SIZE 20 142 #define ES_UNIT_LIST_INCREMENT 20 143 144 #endif // _es_defns 145 146 // Local Variables: 147 // tab-width: 8 148 // indent-tabs-mode: nil 149 // c-basic-offset: 2 150 // End: 151 // vim: set tabstop=8 shiftwidth=2 expandtab: 152