Coverage Report

Created: 2022-08-24 06:17

/src/x265/source/encoder/sei.h
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
* Copyright (C) 2013-2020 MulticoreWare, Inc
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
#include "nal.h"
31
#include "md5.h"
32
33
namespace X265_NS {
34
// private namespace
35
36
class SEI : public SyntaxElementWriter
37
{
38
public:
39
    /* SEI users call writeSEImessages() to marshal an SEI to a bitstream.
40
    * The writeSEImessages() method calls writeSEI() which encodes the header */
41
    void writeSEImessages(Bitstream& bs, const SPS& sps, NalUnitType nalUnitType, NALList& list, int isNested);
42
    void setSize(uint32_t size);
43
    static char* base64Decode(char encodedString[], int base64EncodeLength);
44
0
    virtual ~SEI() {}
45
protected:
46
    SEIPayloadType  m_payloadType;
47
    uint32_t        m_payloadSize;
48
    virtual void writeSEI(const SPS&) = 0;
49
    void writeByteAlign();
50
};
51
52
//seongnam.oh@samsung.com :: for the Creative Intent Meta Data Encoding
53
class SEIuserDataRegistered : public SEI
54
{
55
public:
56
    SEIuserDataRegistered()
57
0
    {
58
0
        m_payloadType = USER_DATA_REGISTERED_ITU_T_T35;
59
0
        m_payloadSize = 0;
60
0
    }
61
62
    uint8_t *m_userData;
63
64
    // daniel.vt@samsung.com :: for the Creative Intent Meta Data Encoding ( seongnam.oh@samsung.com )
65
    void writeSEI(const SPS&)
66
0
    {
67
0
        if (!m_userData)
68
0
            return;
69
70
0
        uint32_t i = 0;
71
0
        for (; i < m_payloadSize; ++i)
72
0
            WRITE_CODE(m_userData[i], 8, "creative_intent_metadata");
73
0
    }
74
};
75
76
static const uint32_t ISO_IEC_11578_LEN = 16;
77
78
class SEIuserDataUnregistered : public SEI
79
{
80
public:
81
    SEIuserDataUnregistered() : m_userData(NULL)
82
0
    {
83
0
        m_payloadType = USER_DATA_UNREGISTERED;
84
0
        m_payloadSize = 0;
85
0
    }
86
    static const uint8_t m_uuid_iso_iec_11578[ISO_IEC_11578_LEN];
87
    uint8_t *m_userData;
88
    void writeSEI(const SPS&)
89
0
    {
90
0
        for (uint32_t i = 0; i < ISO_IEC_11578_LEN; i++)
91
0
            WRITE_CODE(m_uuid_iso_iec_11578[i], 8, "sei.uuid_iso_iec_11578[i]");
92
0
        for (uint32_t i = 0; i < m_payloadSize; i++)
93
0
            WRITE_CODE(m_userData[i], 8, "user_data");
94
0
    }
95
};
96
97
class SEIMasteringDisplayColorVolume : public SEI
98
{
99
public:
100
    SEIMasteringDisplayColorVolume()
101
0
    {
102
0
        m_payloadType = MASTERING_DISPLAY_INFO;
103
0
        m_payloadSize = (8 * 2 + 2 * 4);
104
0
    }
105
    uint16_t displayPrimaryX[3];
106
    uint16_t displayPrimaryY[3];
107
    uint16_t whitePointX, whitePointY;
108
    uint32_t maxDisplayMasteringLuminance;
109
    uint32_t minDisplayMasteringLuminance;
110
    bool parse(const char* value)
111
0
    {
112
0
        return sscanf(value, "G(%hu,%hu)B(%hu,%hu)R(%hu,%hu)WP(%hu,%hu)L(%u,%u)",
113
0
                      &displayPrimaryX[0], &displayPrimaryY[0],
114
0
                      &displayPrimaryX[1], &displayPrimaryY[1],
115
0
                      &displayPrimaryX[2], &displayPrimaryY[2],
116
0
                      &whitePointX, &whitePointY,
117
0
                      &maxDisplayMasteringLuminance, &minDisplayMasteringLuminance) == 10;
118
0
    }
119
    void writeSEI(const SPS&)
120
0
    {
121
0
        for (uint32_t i = 0; i < 3; i++)
122
0
        {
123
0
            WRITE_CODE(displayPrimaryX[i], 16, "display_primaries_x[ c ]");
124
0
            WRITE_CODE(displayPrimaryY[i], 16, "display_primaries_y[ c ]");
125
0
        }
126
0
        WRITE_CODE(whitePointX, 16, "white_point_x");
127
0
        WRITE_CODE(whitePointY, 16, "white_point_y");
128
0
        WRITE_CODE(maxDisplayMasteringLuminance, 32, "max_display_mastering_luminance");
129
0
        WRITE_CODE(minDisplayMasteringLuminance, 32, "min_display_mastering_luminance");
130
0
    }
131
};
132
133
class SEIContentLightLevel : public SEI
134
{
135
public:
136
    SEIContentLightLevel()
137
0
    {
138
0
        m_payloadType = CONTENT_LIGHT_LEVEL_INFO;
139
0
        m_payloadSize = 4;
140
0
    }
141
    uint16_t max_content_light_level;
142
    uint16_t max_pic_average_light_level;
143
    void writeSEI(const SPS&)
144
0
    {
145
0
        WRITE_CODE(max_content_light_level,     16, "max_content_light_level");
146
0
        WRITE_CODE(max_pic_average_light_level, 16, "max_pic_average_light_level");
147
0
    }
148
};
149
150
class SEIDecodedPictureHash : public SEI
151
{
152
public:
153
    SEIDecodedPictureHash()
154
0
    {
155
0
        m_payloadType = DECODED_PICTURE_HASH;
156
0
        m_payloadSize = 0;
157
0
    }
158
    enum Method
159
    {
160
        MD5,
161
        CRC,
162
        CHECKSUM,
163
    } m_method;
164
165
    MD5Context m_state[3];
166
    uint32_t   m_crc[3];
167
    uint32_t   m_checksum[3];
168
    uint8_t    m_digest[3][16];
169
170
    void writeSEI(const SPS& sps)
171
0
    {
172
0
        int planes = (sps.chromaFormatIdc != X265_CSP_I400) ? 3 : 1;
173
0
        WRITE_CODE(m_method, 8, "hash_type");
174
0
        for (int yuvIdx = 0; yuvIdx < planes; yuvIdx++)
175
0
        {
176
0
            if (m_method == MD5)
177
0
            {
178
0
                for (uint32_t i = 0; i < 16; i++)
179
0
                    WRITE_CODE(m_digest[yuvIdx][i], 8, "picture_md5");
180
0
            }
181
0
            else if (m_method == CRC)
182
0
            {
183
0
                uint32_t val = (m_digest[yuvIdx][0] << 8) + m_digest[yuvIdx][1];
184
0
                WRITE_CODE(val, 16, "picture_crc");
185
0
            }
186
0
            else if (m_method == CHECKSUM)
187
0
            {
188
0
                uint32_t val = (m_digest[yuvIdx][0] << 24) + (m_digest[yuvIdx][1] << 16) + (m_digest[yuvIdx][2] << 8) + m_digest[yuvIdx][3];
189
0
                WRITE_CODE(val, 32, "picture_checksum");
190
0
            }
191
0
        }
192
0
    }
193
};
194
195
class SEIActiveParameterSets : public SEI
196
{
197
public:
198
    SEIActiveParameterSets()
199
0
    {
200
0
        m_payloadType = ACTIVE_PARAMETER_SETS;
201
0
        m_payloadSize = 0;
202
0
    }
203
    bool m_selfContainedCvsFlag;
204
    bool m_noParamSetUpdateFlag;
205
206
    void writeSEI(const SPS&)
207
0
    {
208
0
        WRITE_CODE(0, 4, "active_vps_id");
209
0
        WRITE_FLAG(m_selfContainedCvsFlag, "self_contained_cvs_flag");
210
0
        WRITE_FLAG(m_noParamSetUpdateFlag, "no_param_set_update_flag");
211
0
        WRITE_UVLC(0, "num_sps_ids_minus1");
212
0
        WRITE_UVLC(0, "active_seq_param_set_id");
213
0
        writeByteAlign();
214
0
    }
215
};
216
217
class SEIBufferingPeriod : public SEI
218
{
219
public:
220
    SEIBufferingPeriod()
221
        : m_cpbDelayOffset(0)
222
        , m_dpbDelayOffset(0)
223
        , m_concatenationFlag(0)
224
        , m_auCpbRemovalDelayDelta(1)
225
0
    {
226
0
        m_payloadType = BUFFERING_PERIOD;
227
0
        m_payloadSize = 0;
228
0
    }
229
    bool     m_cpbDelayOffset;
230
    bool     m_dpbDelayOffset;
231
    bool     m_concatenationFlag;
232
    uint32_t m_initialCpbRemovalDelay;
233
    uint32_t m_initialCpbRemovalDelayOffset;
234
    uint32_t m_auCpbRemovalDelayDelta;
235
236
    void writeSEI(const SPS& sps)
237
0
    {
238
0
        const HRDInfo& hrd = sps.vuiParameters.hrdParameters;
239
240
0
        WRITE_UVLC(0, "bp_seq_parameter_set_id");
241
0
        WRITE_FLAG(0, "rap_cpb_params_present_flag");
242
0
        WRITE_FLAG(m_concatenationFlag, "concatenation_flag");
243
0
        WRITE_CODE(m_auCpbRemovalDelayDelta - 1,   hrd.cpbRemovalDelayLength,       "au_cpb_removal_delay_delta_minus1");
244
0
        WRITE_CODE(m_initialCpbRemovalDelay,       hrd.initialCpbRemovalDelayLength,        "initial_cpb_removal_delay");
245
0
        WRITE_CODE(m_initialCpbRemovalDelayOffset, hrd.initialCpbRemovalDelayLength, "initial_cpb_removal_delay_offset");
246
247
0
        writeByteAlign();
248
0
    }
249
};
250
251
class SEIPictureTiming : public SEI
252
{
253
public:
254
    SEIPictureTiming()
255
0
    {
256
0
        m_payloadType = PICTURE_TIMING;
257
0
        m_payloadSize = 0;
258
0
    }
259
    uint32_t  m_picStruct;
260
    uint32_t  m_sourceScanType;
261
    bool      m_duplicateFlag;
262
263
    uint32_t  m_auCpbRemovalDelay;
264
    uint32_t  m_picDpbOutputDelay;
265
266
    void writeSEI(const SPS& sps)
267
0
    {
268
0
        const VUI *vui = &sps.vuiParameters;
269
0
        const HRDInfo *hrd = &vui->hrdParameters;
270
271
0
        if (vui->frameFieldInfoPresentFlag)
272
0
        {
273
0
            WRITE_CODE(m_picStruct, 4,          "pic_struct");
274
0
            WRITE_CODE(m_sourceScanType, 2,     "source_scan_type");
275
0
            WRITE_FLAG(m_duplicateFlag,         "duplicate_flag");
276
0
        }
277
278
0
        if (vui->hrdParametersPresentFlag)
279
0
        {
280
0
            WRITE_CODE(m_auCpbRemovalDelay - 1, hrd->cpbRemovalDelayLength, "au_cpb_removal_delay_minus1");
281
0
            WRITE_CODE(m_picDpbOutputDelay, hrd->dpbOutputDelayLength, "pic_dpb_output_delay");
282
            /* Removed sub-pic signaling June 2014 */
283
0
        }
284
0
        writeByteAlign();
285
0
    }
286
};
287
288
class SEIRecoveryPoint : public SEI
289
{
290
public:
291
    SEIRecoveryPoint()
292
0
    {
293
0
        m_payloadType = RECOVERY_POINT;
294
0
        m_payloadSize = 0;
295
0
    }
296
    int  m_recoveryPocCnt;
297
    bool m_exactMatchingFlag;
298
    bool m_brokenLinkFlag;
299
300
    void writeSEI(const SPS&)
301
0
    {
302
0
        WRITE_SVLC(m_recoveryPocCnt,    "recovery_poc_cnt");
303
0
        WRITE_FLAG(m_exactMatchingFlag, "exact_matching_flag");
304
0
        WRITE_FLAG(m_brokenLinkFlag,    "broken_link_flag");
305
0
        writeByteAlign();
306
0
    }
307
};
308
309
class SEIAlternativeTC : public SEI
310
{
311
public:
312
    int m_preferredTransferCharacteristics;
313
    SEIAlternativeTC()
314
0
    {
315
0
        m_payloadType = ALTERNATIVE_TRANSFER_CHARACTERISTICS;
316
0
        m_payloadSize = 0;
317
0
        m_preferredTransferCharacteristics = -1;
318
0
    }
319
320
    void writeSEI(const SPS&)
321
0
    {
322
0
        WRITE_CODE(m_preferredTransferCharacteristics, 8, "Preferred transfer characteristics");
323
0
    }
324
};
325
326
}
327
#endif // ifndef X265_SEI_H