forked from kynesim/tstools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
h262_defns.h
255 lines (225 loc) · 10.9 KB
/
h262_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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
/*
* Datastructures for reading H.262 (MPEG-2) 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 _h262_defns
#define _h262_defns
#include <stdio.h>
#include "compat.h"
#include "es_defns.h"
#include "ts_defns.h"
// Since reverse_data refers to h262 and acces_unit datastructures, and
// *they* refer to reverse_data, we need to break the circular referencing
// at some point
typedef struct h262_context *h262_context_p;
struct reverse_data;
// ------------------------------------------------------------
// An MPEG "item", the set of bytes that starts with a start code prefix.
struct _h262_item
{
struct ES_unit unit; // The actual data
// MPEG2 specific data
byte picture_coding_type; // only defined if unit.start_code == 0
};
typedef struct _h262_item *h262_item_p;
#define SIZEOF_H262_ITEM sizeof(struct _h262_item)
// ------------------------------------------------------------
// An H.262 "picture". This might be a picture or a sequence header (and
// its associated items).
struct _h262_picture
{
// The main thing we need is a list of the items that make up this picture
ES_unit_list_p list;
// An H.262 "picture" might be a "proper" picture, a sequence header,
// or (just) a sequence end item. It's useful to be able to identify
// the two more common cases easily
int is_picture;
int is_sequence_header;
// Data defined for a picture. When a picture is composed of the data
// from two fields, then these will be the values taken from the first
// field "picture".
byte picture_coding_type; // I, P or B
byte picture_structure; // top/bottom field or frame
uint16_t temporal_reference; // presentation order within a group
byte afd; // its "Active Format Description" value
// (NB: with 0xF0 bits set at top of byte)
byte is_real_afd; // was it a *real* AFD?
int was_two_fields; // TRUE if it's a frame merged from two fields
// Data defined for a sequence header/extension
// Note that H.262 requires that data given in one sequence extension
// shall be the same as that in all the others in the stream. Thus, in
// particular, we know that if fields are allowed by one sequence
// extension, they will be allowed by all.
byte progressive_sequence; // frames or frames and fields allowed?
// Data defined for both
// (in a frame, this is the value from the previous section header)
byte aspect_ratio_info; // its aspect ratio code
};
typedef struct _h262_picture *h262_picture_p;
#define SIZEOF_H262_PICTURE sizeof(struct _h262_picture)
// ------------------------------------------------------------
// Produce a nice string for the start code. `b` must be a byte.
#define H262_START_CODE_STR(b) \
((b)==0x00?"picture": \
(b)>=0x01 && b<=0xAF?"slice": \
(b)==0xB0?"reserved": \
(b)==0xB1?"reserved": \
(b)==0xB2?"user data": \
(b)==0xB3?"sequence header": \
(b)==0xB4?"sequence error": \
(b)==0xB5?"extension start": \
(b)==0xB6?"reserved": \
(b)==0xB7?"sequence end": \
(b)==0xB8?"group start": \
(b)>=0xB9?"system start":"???")
#define is_h262_picture_item(item) ((item)->unit.start_code==0x00)
#define is_h262_slice_item(item) ((item)->unit.start_code>=0x01 && \
(item)->unit.start_code<=0xAF)
#define is_h262_user_data_item(item) ((item)->unit.start_code==0xB2)
#define is_h262_seq_header_item(item) ((item)->unit.start_code==0xB3)
#define is_h262_seq_end_item(item) ((item)->unit.start_code==0xB7)
#define is_h262_group_start_item(item) ((item)->unit.start_code==0xB8)
#define is_h262_extension_start_item(item) ((item)->unit.start_code==0xB5)
#define H262_PICTURE_CODING_STR(s) \
((s)==0?"Forbidden": \
(s)==1?"I": \
(s)==2?"P": \
(s)==3?"B": \
(s)==4?"D":"Reserved")
// The following two macros can be used on H.262 items *or* pictures
#define is_I_picture(picture) ((picture)->picture_coding_type==1)
#define is_P_picture(picture) ((picture)->picture_coding_type==2)
#define H262_PICTURE_STRUCTURE_STR(s) \
((s)==0?"Reserved": \
(s)==1?"Top Field": \
(s)==2?"Bottom Field": \
(s)==3?"Frame":"???")
#define is_h262_field_picture(picture) ((picture)->is_picture && \
((picture)->picture_structure == 1 ||\
(picture)->picture_structure == 2))
#define is_h262_AFD_user_data_item(item) \
((item)->unit.start_code == 0xB2 && \
(item)->unit.data_len > 8 && \
(item)->unit.data[4] == 0x44 && \
(item)->unit.data[5] == 0x54 && \
(item)->unit.data[6] == 0x47 && \
(item)->unit.data[7] == 0x31)
#define UNSET_AFD_BYTE 0xF8 // i.e., '1111 1000'
// String values taken from ATSC Digital Television Standard, Rev C,
// (A/53C) 12 May 2004, which will hopefully be correct for DVB as well...
#define AFD_STR(afd) \
((afd)==0xF2?"ATSC: box 16:9 (top)": \
(afd)==0xF3?"ATSC: box 14:9 (top)": \
(afd)==0xF4?"ATSC: box > 16:9 (center)": \
(afd)==0xF8?"Active format as coded frame": \
(afd)==0xF9?"4:3 (centre)": \
(afd)==0xFA?"16:9 (centre)": \
(afd)==0xFB?"14:9 (centre)": \
(afd)==0xFC?"reserved": \
(afd)==0xFD?"4:3 (with shoot & protect 14:9 centre)": \
(afd)==0xFE?"16:9 (with shoot & protect 14:9 centre)": \
(afd)==0xFF?"16:9 (with shoot & protect 4:3 centre)":"reserved")
#define SHORT_AFD_STR(afd) \
((afd)==0xF2?"ATSC: box 16:9 (top)": \
(afd)==0xF3?"ATSC: box 14:9 (top)": \
(afd)==0xF4?"ATSC: box > 16:9 (center)": \
(afd)==0xF8?"As coded frame": \
(afd)==0xF9?"4:3 (centre)": \
(afd)==0xFA?"16:9 (centre)": \
(afd)==0xFB?"14:9 (centre)": \
(afd)==0xFC?"reserved": \
(afd)==0xFD?"4:3 (14:9)": \
(afd)==0xFE?"16:9 (14:9)": \
(afd)==0xFF?"16:9 (4:3)":"reserved")
// The standard does not define value FF, so I'm choosing it as an "unset"
// value, so that I get sensible diagnostics when a picture is reported
// on before a section header has been read
#define H262_UNSET_ASPECT_RATIO_INFO 0xFF
#define H262_ASPECT_RATIO_INFO_STR(rat) ((rat)==0xFF?"Unset": \
(rat)==0?"Forbidden aspect ratio": \
(rat)==1?"Square": \
(rat)==2?"4:3": \
(rat)==3?"16:9": \
"Reserved aspect ratio")
// ------------------------------------------------------------
// Context for looping over the H.262 items and pictures in an elementary
// stream
struct h262_context
{
ES_p es;
// We count all of the pictures as we read them (this is useful
// when we are building up reverse_data arrays). If functions
// move around in the data stream, we assume that they will
// (re)set this to a sensible value.
// The index of the first picture read is 1, and this value is
// incremented by each call of `get_next_h262_picture` (note that
// for this purpose, sequence headers are *not* considered pictures)
uint32_t picture_index; // The index of the last picture read
// We detect the end of an H.262 picture (or sequence header) by
// reading the first item that cannot be part of it. We then need
// to remember that item for *next* time we try to read a picture.
h262_item_p last_item;
// What was the aspect ratio code from the last sequence header?
byte last_aspect_ratio_info;
// When we are reading MPEG-2, we may encounter AFD (Active Format
// Definiton) user data. This sets the aspect ratio of the following
// picture(s), possibly overriding information present in a preceding
// sequence header. It should only be present for I pictures, really,
// but we remember it for all pictures.
// Once an AFD value has been set, it stands until another value is read.
// This all becomes important when reversing, which see.
// Anyway, in order to set the AFD on pictures which don't have it
// explicitly, we obviously need to remember the last value found.
// For simplicity of use, we remember the whole byte it came in,
// including the 0xF0 reserved bits at the top of the byte.
// Note that '1000' (8) is the "unset" value.
byte last_afd;
// When we are reading an H.262 picture back in, for reversing purposes, or
// reading frames for filtering, it is useful to *insist* that an AFD be
// found for the picture. Thus, if `add_fake_afd` is TRUE, a dummy AFD,
// containing the value in `last_afd`, will be inserted into the picture's
// ES unit `list` (of course, if the picture contains a *real* AFD, this is
// not necessary). Beware that the ES unit inserted won't stand up to close
// observation, as its start position (for instance) will clearly be
// wrong...
// (this is manipulated by the reversing and filtering code - it is not
// intended for use for any other purpose)
int add_fake_afd;
// If we are collecting reversing information, then we keep a reference
// to the reverse data here
struct reverse_data * reverse_data;
// In the same context, we need to remember how long it is since the
// last sequence header
byte count_since_seq_hdr;
};
#define SIZEOF_H262_CONTEXT sizeof(struct h262_context)
#endif // _h262_defns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab: