Imported Upstream version 1.4
[deb_x265.git] / source / encoder / sei.h
CommitLineData
72b9787e
JB
1/*****************************************************************************
2* Copyright (C) 2013 x265 project
3*
4* Authors: Steve Borho <steve@borho.org>
5*
6* This program is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* (at your option) any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software
18* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
19*
20* This program is also available under a commercial proprietary license.
21* For more information, contact us at license @ x265.com.
22*****************************************************************************/
23
24#ifndef X265_SEI_H
25#define X265_SEI_H
26
27#include "common.h"
28#include "bitstream.h"
29#include "slice.h"
30
31namespace x265 {
32// private namespace
33
34class SEI : public SyntaxElementWriter
35{
36public:
37
38 /* SEI users call write() to marshal an SEI to a bitstream. SEI
39 * subclasses may implement write() or accept the default write()
40 * method which calls writeSEI() with a bitcounter to determine
41 * the size, then it encodes the header and calls writeSEI a
42 * second time for the real encode. */
43 virtual void write(Bitstream& bs, const SPS& sps);
44
45 virtual ~SEI() {}
46
47protected:
48
49 enum PayloadType
50 {
51 BUFFERING_PERIOD = 0,
52 PICTURE_TIMING = 1,
53 PAN_SCAN_RECT = 2,
54 FILLER_PAYLOAD = 3,
55 USER_DATA_REGISTERED_ITU_T_T35 = 4,
56 USER_DATA_UNREGISTERED = 5,
57 RECOVERY_POINT = 6,
58 SCENE_INFO = 9,
59 FULL_FRAME_SNAPSHOT = 15,
60 PROGRESSIVE_REFINEMENT_SEGMENT_START = 16,
61 PROGRESSIVE_REFINEMENT_SEGMENT_END = 17,
62 FILM_GRAIN_CHARACTERISTICS = 19,
63 POST_FILTER_HINT = 22,
64 TONE_MAPPING_INFO = 23,
65 FRAME_PACKING = 45,
66 DISPLAY_ORIENTATION = 47,
67 SOP_DESCRIPTION = 128,
68 ACTIVE_PARAMETER_SETS = 129,
69 DECODING_UNIT_INFO = 130,
70 TEMPORAL_LEVEL0_INDEX = 131,
71 DECODED_PICTURE_HASH = 132,
72 SCALABLE_NESTING = 133,
73 REGION_REFRESH_INFO = 134,
74 };
75
76 virtual PayloadType payloadType() const = 0;
77
78 virtual void writeSEI(const SPS&) { X265_CHECK(0, "empty writeSEI method called\n"); }
79
80 void writeByteAlign();
81};
82
83class SEIuserDataUnregistered : public SEI
84{
85public:
86
87 PayloadType payloadType() const { return USER_DATA_UNREGISTERED; }
88
89 SEIuserDataUnregistered() : m_userData(NULL) {}
90
91 static const uint8_t m_uuid_iso_iec_11578[16];
92 uint32_t m_userDataLength;
93 uint8_t *m_userData;
94
95 void write(Bitstream& bs, const SPS&)
96 {
97 m_bitIf = &bs;
98
99 WRITE_CODE(USER_DATA_UNREGISTERED, 8, "payload_type");
100
101 uint32_t payloadSize = 16 + m_userDataLength;
102 for (; payloadSize >= 0xff; payloadSize -= 0xff)
103 WRITE_CODE(0xff, 8, "payload_size");
104 WRITE_CODE(payloadSize, 8, "payload_size");
105
106 for (uint32_t i = 0; i < 16; i++)
107 WRITE_CODE(m_uuid_iso_iec_11578[i], 8, "sei.uuid_iso_iec_11578[i]");
108
109 for (uint32_t i = 0; i < m_userDataLength; i++)
110 WRITE_CODE(m_userData[i], 8, "user_data");
111 }
112};
113
114class SEIDecodedPictureHash : public SEI
115{
116public:
117
118 PayloadType payloadType() const { return DECODED_PICTURE_HASH; }
119
120 enum Method
121 {
122 MD5,
123 CRC,
124 CHECKSUM,
125 } m_method;
126
127 uint8_t m_digest[3][16];
128
129 void write(Bitstream& bs, const SPS&)
130 {
131 m_bitIf = &bs;
132
133 WRITE_CODE(DECODED_PICTURE_HASH, 8, "payload_type");
134
135 switch (m_method)
136 {
137 case MD5:
138 WRITE_CODE(1 + 16 * 3, 8, "payload_size");
139 WRITE_CODE(MD5, 8, "hash_type");
140 break;
141 case CRC:
142 WRITE_CODE(1 + 2 * 3, 8, "payload_size");
143 WRITE_CODE(CRC, 8, "hash_type");
144 break;
145 case CHECKSUM:
146 WRITE_CODE(1 + 4 * 3, 8, "payload_size");
147 WRITE_CODE(CHECKSUM, 8, "hash_type");
148 break;
149 }
150
151 for (int yuvIdx = 0; yuvIdx < 3; yuvIdx++)
152 {
153 if (m_method == MD5)
154 {
155 for (uint32_t i = 0; i < 16; i++)
156 WRITE_CODE(m_digest[yuvIdx][i], 8, "picture_md5");
157 }
158 else if (m_method == CRC)
159 {
160 uint32_t val = (m_digest[yuvIdx][0] << 8) + m_digest[yuvIdx][1];
161 WRITE_CODE(val, 16, "picture_crc");
162 }
163 else if (m_method == CHECKSUM)
164 {
165 uint32_t val = (m_digest[yuvIdx][0] << 24) + (m_digest[yuvIdx][1] << 16) + (m_digest[yuvIdx][2] << 8) + m_digest[yuvIdx][3];
166 WRITE_CODE(val, 32, "picture_checksum");
167 }
168 }
169 }
170};
171
172class SEIActiveParameterSets : public SEI
173{
174public:
175
176 PayloadType payloadType() const { return ACTIVE_PARAMETER_SETS; }
177
178 bool m_selfContainedCvsFlag;
179 bool m_noParamSetUpdateFlag;
180
181 void writeSEI(const SPS&)
182 {
183 WRITE_CODE(0, 4, "active_vps_id");
184 WRITE_FLAG(m_selfContainedCvsFlag, "self_contained_cvs_flag");
185 WRITE_FLAG(m_noParamSetUpdateFlag, "no_param_set_update_flag");
186 WRITE_UVLC(0, "num_sps_ids_minus1");
187 WRITE_UVLC(0, "active_seq_param_set_id");
188 writeByteAlign();
189 }
190};
191
192class SEIBufferingPeriod : public SEI
193{
194public:
195
196 PayloadType payloadType() const { return BUFFERING_PERIOD; }
197
198 SEIBufferingPeriod()
199 : m_cpbDelayOffset(0)
200 , m_dpbDelayOffset(0)
201 , m_auCpbRemovalDelayDelta(1)
202 {
203 }
204
205 bool m_cpbDelayOffset;
206 bool m_dpbDelayOffset;
207 uint32_t m_initialCpbRemovalDelay;
208 uint32_t m_initialCpbRemovalDelayOffset;
209 uint32_t m_auCpbRemovalDelayDelta;
210
211 void writeSEI(const SPS& sps)
212 {
213 const HRDInfo& hrd = sps.vuiParameters.hrdParameters;
214
215 WRITE_UVLC(0, "bp_seq_parameter_set_id");
216 WRITE_FLAG(0, "rap_cpb_params_present_flag");
217 WRITE_FLAG(0, "concatenation_flag");
218 WRITE_CODE(m_auCpbRemovalDelayDelta - 1, hrd.cpbRemovalDelayLength, "au_cpb_removal_delay_delta_minus1");
219 WRITE_CODE(m_initialCpbRemovalDelay, hrd.initialCpbRemovalDelayLength, "initial_cpb_removal_delay");
220 WRITE_CODE(m_initialCpbRemovalDelayOffset, hrd.initialCpbRemovalDelayLength, "initial_cpb_removal_delay_offset");
221
222 writeByteAlign();
223 }
224};
225
226class SEIPictureTiming : public SEI
227{
228public:
229
230 PayloadType payloadType() const { return PICTURE_TIMING; }
231
232 uint32_t m_picStruct;
233 uint32_t m_sourceScanType;
234 bool m_duplicateFlag;
235
236 uint32_t m_auCpbRemovalDelay;
237 uint32_t m_picDpbOutputDelay;
238
239 void writeSEI(const SPS& sps)
240 {
241 const VUI *vui = &sps.vuiParameters;
242 const HRDInfo *hrd = &vui->hrdParameters;
243
244 if (vui->frameFieldInfoPresentFlag)
245 {
246 WRITE_CODE(m_picStruct, 4, "pic_struct");
247 WRITE_CODE(m_sourceScanType, 2, "source_scan_type");
248 WRITE_FLAG(m_duplicateFlag, "duplicate_flag");
249 }
250
251 if (vui->hrdParametersPresentFlag)
252 {
253 WRITE_CODE(m_auCpbRemovalDelay - 1, hrd->cpbRemovalDelayLength, "au_cpb_removal_delay_minus1");
254 WRITE_CODE(m_picDpbOutputDelay, hrd->dpbOutputDelayLength, "pic_dpb_output_delay");
255 /* Removed sub-pic signaling June 2014 */
256 }
257 writeByteAlign();
258 }
259};
260
261class SEIRecoveryPoint : public SEI
262{
263public:
264
265 PayloadType payloadType() const { return RECOVERY_POINT; }
266
267 int m_recoveryPocCnt;
268 bool m_exactMatchingFlag;
269 bool m_brokenLinkFlag;
270
271 void writeSEI(const SPS&)
272 {
273 WRITE_SVLC(m_recoveryPocCnt, "recovery_poc_cnt");
274 WRITE_FLAG(m_exactMatchingFlag, "exact_matching_flag");
275 WRITE_FLAG(m_brokenLinkFlag, "broken_link_flag");
276 writeByteAlign();
277 }
278};
279}
280
281#endif // ifndef X265_SEI_H