1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_cistatic int FUNC(filler_payload) 20cabdff1aSopenharmony_ci (CodedBitstreamContext *ctx, RWContext *rw, 21cabdff1aSopenharmony_ci SEIRawFillerPayload *current, SEIMessageState *state) 22cabdff1aSopenharmony_ci{ 23cabdff1aSopenharmony_ci int err, i; 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci HEADER("Filler Payload"); 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#ifdef READ 28cabdff1aSopenharmony_ci current->payload_size = state->payload_size; 29cabdff1aSopenharmony_ci#endif 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci for (i = 0; i < current->payload_size; i++) 32cabdff1aSopenharmony_ci fixed(8, ff_byte, 0xff); 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_ci return 0; 35cabdff1aSopenharmony_ci} 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_cistatic int FUNC(user_data_registered) 38cabdff1aSopenharmony_ci (CodedBitstreamContext *ctx, RWContext *rw, 39cabdff1aSopenharmony_ci SEIRawUserDataRegistered *current, SEIMessageState *state) 40cabdff1aSopenharmony_ci{ 41cabdff1aSopenharmony_ci int err, i, j; 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci HEADER("User Data Registered ITU-T T.35"); 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci u(8, itu_t_t35_country_code, 0x00, 0xff); 46cabdff1aSopenharmony_ci if (current->itu_t_t35_country_code != 0xff) 47cabdff1aSopenharmony_ci i = 1; 48cabdff1aSopenharmony_ci else { 49cabdff1aSopenharmony_ci u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); 50cabdff1aSopenharmony_ci i = 2; 51cabdff1aSopenharmony_ci } 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ci#ifdef READ 54cabdff1aSopenharmony_ci if (state->payload_size < i) { 55cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, 56cabdff1aSopenharmony_ci "Invalid SEI user data registered payload.\n"); 57cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 58cabdff1aSopenharmony_ci } 59cabdff1aSopenharmony_ci current->data_length = state->payload_size - i; 60cabdff1aSopenharmony_ci#endif 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci allocate(current->data, current->data_length); 63cabdff1aSopenharmony_ci for (j = 0; j < current->data_length; j++) 64cabdff1aSopenharmony_ci xu(8, itu_t_t35_payload_byte[], current->data[j], 0x00, 0xff, 1, i + j); 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci return 0; 67cabdff1aSopenharmony_ci} 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_cistatic int FUNC(user_data_unregistered) 70cabdff1aSopenharmony_ci (CodedBitstreamContext *ctx, RWContext *rw, 71cabdff1aSopenharmony_ci SEIRawUserDataUnregistered *current, SEIMessageState *state) 72cabdff1aSopenharmony_ci{ 73cabdff1aSopenharmony_ci int err, i; 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci HEADER("User Data Unregistered"); 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci#ifdef READ 78cabdff1aSopenharmony_ci if (state->payload_size < 16) { 79cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, 80cabdff1aSopenharmony_ci "Invalid SEI user data unregistered payload.\n"); 81cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 82cabdff1aSopenharmony_ci } 83cabdff1aSopenharmony_ci current->data_length = state->payload_size - 16; 84cabdff1aSopenharmony_ci#endif 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) 87cabdff1aSopenharmony_ci us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci allocate(current->data, current->data_length); 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci for (i = 0; i < current->data_length; i++) 92cabdff1aSopenharmony_ci xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci return 0; 95cabdff1aSopenharmony_ci} 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_cistatic int FUNC(mastering_display_colour_volume) 98cabdff1aSopenharmony_ci (CodedBitstreamContext *ctx, RWContext *rw, 99cabdff1aSopenharmony_ci SEIRawMasteringDisplayColourVolume *current, SEIMessageState *state) 100cabdff1aSopenharmony_ci{ 101cabdff1aSopenharmony_ci int err, c; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci HEADER("Mastering Display Colour Volume"); 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_ci for (c = 0; c < 3; c++) { 106cabdff1aSopenharmony_ci ubs(16, display_primaries_x[c], 1, c); 107cabdff1aSopenharmony_ci ubs(16, display_primaries_y[c], 1, c); 108cabdff1aSopenharmony_ci } 109cabdff1aSopenharmony_ci 110cabdff1aSopenharmony_ci ub(16, white_point_x); 111cabdff1aSopenharmony_ci ub(16, white_point_y); 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ci ub(32, max_display_mastering_luminance); 114cabdff1aSopenharmony_ci ub(32, min_display_mastering_luminance); 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci return 0; 117cabdff1aSopenharmony_ci} 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_cistatic int FUNC(content_light_level_info) 120cabdff1aSopenharmony_ci (CodedBitstreamContext *ctx, RWContext *rw, 121cabdff1aSopenharmony_ci SEIRawContentLightLevelInfo *current, SEIMessageState *state) 122cabdff1aSopenharmony_ci{ 123cabdff1aSopenharmony_ci int err; 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ci HEADER("Content Light Level Information"); 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci ub(16, max_content_light_level); 128cabdff1aSopenharmony_ci ub(16, max_pic_average_light_level); 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci return 0; 131cabdff1aSopenharmony_ci} 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_cistatic int FUNC(alternative_transfer_characteristics) 134cabdff1aSopenharmony_ci (CodedBitstreamContext *ctx, RWContext *rw, 135cabdff1aSopenharmony_ci SEIRawAlternativeTransferCharacteristics *current, 136cabdff1aSopenharmony_ci SEIMessageState *state) 137cabdff1aSopenharmony_ci{ 138cabdff1aSopenharmony_ci int err; 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_ci HEADER("Alternative Transfer Characteristics"); 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci ub(8, preferred_transfer_characteristics); 143cabdff1aSopenharmony_ci 144cabdff1aSopenharmony_ci return 0; 145cabdff1aSopenharmony_ci} 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_cistatic int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, 148cabdff1aSopenharmony_ci SEIRawMessage *current) 149cabdff1aSopenharmony_ci{ 150cabdff1aSopenharmony_ci const SEIMessageTypeDescriptor *desc; 151cabdff1aSopenharmony_ci int err, i; 152cabdff1aSopenharmony_ci 153cabdff1aSopenharmony_ci desc = ff_cbs_sei_find_type(ctx, current->payload_type); 154cabdff1aSopenharmony_ci if (desc) { 155cabdff1aSopenharmony_ci SEIMessageState state = { 156cabdff1aSopenharmony_ci .payload_type = current->payload_type, 157cabdff1aSopenharmony_ci .payload_size = current->payload_size, 158cabdff1aSopenharmony_ci .extension_present = current->extension_bit_length > 0, 159cabdff1aSopenharmony_ci }; 160cabdff1aSopenharmony_ci int start_position, current_position, bits_written; 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci#ifdef READ 163cabdff1aSopenharmony_ci CHECK(ff_cbs_sei_alloc_message_payload(current, desc)); 164cabdff1aSopenharmony_ci#endif 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci start_position = bit_position(rw); 167cabdff1aSopenharmony_ci 168cabdff1aSopenharmony_ci CHECK(desc->READWRITE(ctx, rw, current->payload, &state)); 169cabdff1aSopenharmony_ci 170cabdff1aSopenharmony_ci current_position = bit_position(rw); 171cabdff1aSopenharmony_ci bits_written = current_position - start_position; 172cabdff1aSopenharmony_ci 173cabdff1aSopenharmony_ci if (byte_alignment(rw) || state.extension_present || 174cabdff1aSopenharmony_ci bits_written < 8 * current->payload_size) { 175cabdff1aSopenharmony_ci size_t bits_left; 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_ci#ifdef READ 178cabdff1aSopenharmony_ci GetBitContext tmp = *rw; 179cabdff1aSopenharmony_ci int trailing_bits, trailing_zero_bits; 180cabdff1aSopenharmony_ci 181cabdff1aSopenharmony_ci bits_left = 8 * current->payload_size - bits_written; 182cabdff1aSopenharmony_ci if (bits_left > 8) 183cabdff1aSopenharmony_ci skip_bits_long(&tmp, bits_left - 8); 184cabdff1aSopenharmony_ci trailing_bits = get_bits(&tmp, FFMIN(bits_left, 8)); 185cabdff1aSopenharmony_ci if (trailing_bits == 0) { 186cabdff1aSopenharmony_ci // The trailing bits must contain a bit_equal_to_one, so 187cabdff1aSopenharmony_ci // they can't all be zero. 188cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci trailing_zero_bits = ff_ctz(trailing_bits); 191cabdff1aSopenharmony_ci current->extension_bit_length = 192cabdff1aSopenharmony_ci bits_left - 1 - trailing_zero_bits; 193cabdff1aSopenharmony_ci#endif 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci if (current->extension_bit_length > 0) { 196cabdff1aSopenharmony_ci allocate(current->extension_data, 197cabdff1aSopenharmony_ci (current->extension_bit_length + 7) / 8); 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_ci bits_left = current->extension_bit_length; 200cabdff1aSopenharmony_ci for (i = 0; bits_left > 0; i++) { 201cabdff1aSopenharmony_ci int length = FFMIN(bits_left, 8); 202cabdff1aSopenharmony_ci xu(length, reserved_payload_extension_data, 203cabdff1aSopenharmony_ci current->extension_data[i], 204cabdff1aSopenharmony_ci 0, MAX_UINT_BITS(length), 0); 205cabdff1aSopenharmony_ci bits_left -= length; 206cabdff1aSopenharmony_ci } 207cabdff1aSopenharmony_ci } 208cabdff1aSopenharmony_ci 209cabdff1aSopenharmony_ci fixed(1, bit_equal_to_one, 1); 210cabdff1aSopenharmony_ci while (byte_alignment(rw)) 211cabdff1aSopenharmony_ci fixed(1, bit_equal_to_zero, 0); 212cabdff1aSopenharmony_ci } 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_ci#ifdef WRITE 215cabdff1aSopenharmony_ci current->payload_size = (put_bits_count(rw) - start_position) / 8; 216cabdff1aSopenharmony_ci#endif 217cabdff1aSopenharmony_ci } else { 218cabdff1aSopenharmony_ci uint8_t *data; 219cabdff1aSopenharmony_ci 220cabdff1aSopenharmony_ci allocate(current->payload, current->payload_size); 221cabdff1aSopenharmony_ci data = current->payload; 222cabdff1aSopenharmony_ci 223cabdff1aSopenharmony_ci for (i = 0; i < current->payload_size; i++) 224cabdff1aSopenharmony_ci xu(8, payload_byte[i], data[i], 0, 255, 1, i); 225cabdff1aSopenharmony_ci } 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci return 0; 228cabdff1aSopenharmony_ci} 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_cistatic int FUNC(message_list)(CodedBitstreamContext *ctx, RWContext *rw, 231cabdff1aSopenharmony_ci SEIRawMessageList *current, int prefix) 232cabdff1aSopenharmony_ci{ 233cabdff1aSopenharmony_ci SEIRawMessage *message; 234cabdff1aSopenharmony_ci int err, k; 235cabdff1aSopenharmony_ci 236cabdff1aSopenharmony_ci#ifdef READ 237cabdff1aSopenharmony_ci for (k = 0;; k++) { 238cabdff1aSopenharmony_ci uint32_t payload_type = 0; 239cabdff1aSopenharmony_ci uint32_t payload_size = 0; 240cabdff1aSopenharmony_ci uint32_t tmp; 241cabdff1aSopenharmony_ci GetBitContext payload_gbc; 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci while (show_bits(rw, 8) == 0xff) { 244cabdff1aSopenharmony_ci fixed(8, ff_byte, 0xff); 245cabdff1aSopenharmony_ci payload_type += 255; 246cabdff1aSopenharmony_ci } 247cabdff1aSopenharmony_ci xu(8, last_payload_type_byte, tmp, 0, 254, 0); 248cabdff1aSopenharmony_ci payload_type += tmp; 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci while (show_bits(rw, 8) == 0xff) { 251cabdff1aSopenharmony_ci fixed(8, ff_byte, 0xff); 252cabdff1aSopenharmony_ci payload_size += 255; 253cabdff1aSopenharmony_ci } 254cabdff1aSopenharmony_ci xu(8, last_payload_size_byte, tmp, 0, 254, 0); 255cabdff1aSopenharmony_ci payload_size += tmp; 256cabdff1aSopenharmony_ci 257cabdff1aSopenharmony_ci // There must be space remaining for both the payload and 258cabdff1aSopenharmony_ci // the trailing bits on the SEI NAL unit. 259cabdff1aSopenharmony_ci if (payload_size + 1 > get_bits_left(rw) / 8) { 260cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, 261cabdff1aSopenharmony_ci "Invalid SEI message: payload_size too large " 262cabdff1aSopenharmony_ci "(%"PRIu32" bytes).\n", payload_size); 263cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 264cabdff1aSopenharmony_ci } 265cabdff1aSopenharmony_ci CHECK(init_get_bits(&payload_gbc, rw->buffer, 266cabdff1aSopenharmony_ci get_bits_count(rw) + 8 * payload_size)); 267cabdff1aSopenharmony_ci skip_bits_long(&payload_gbc, get_bits_count(rw)); 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_ci CHECK(ff_cbs_sei_list_add(current)); 270cabdff1aSopenharmony_ci message = ¤t->messages[k]; 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci message->payload_type = payload_type; 273cabdff1aSopenharmony_ci message->payload_size = payload_size; 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci CHECK(FUNC(message)(ctx, &payload_gbc, message)); 276cabdff1aSopenharmony_ci 277cabdff1aSopenharmony_ci skip_bits_long(rw, 8 * payload_size); 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci if (!cbs_h2645_read_more_rbsp_data(rw)) 280cabdff1aSopenharmony_ci break; 281cabdff1aSopenharmony_ci } 282cabdff1aSopenharmony_ci#else 283cabdff1aSopenharmony_ci for (k = 0; k < current->nb_messages; k++) { 284cabdff1aSopenharmony_ci PutBitContext start_state; 285cabdff1aSopenharmony_ci uint32_t tmp; 286cabdff1aSopenharmony_ci int trace, i; 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_ci message = ¤t->messages[k]; 289cabdff1aSopenharmony_ci 290cabdff1aSopenharmony_ci // We write the payload twice in order to find the size. Trace 291cabdff1aSopenharmony_ci // output is switched off for the first write. 292cabdff1aSopenharmony_ci trace = ctx->trace_enable; 293cabdff1aSopenharmony_ci ctx->trace_enable = 0; 294cabdff1aSopenharmony_ci 295cabdff1aSopenharmony_ci start_state = *rw; 296cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 297cabdff1aSopenharmony_ci *rw = start_state; 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci tmp = message->payload_type; 300cabdff1aSopenharmony_ci while (tmp >= 255) { 301cabdff1aSopenharmony_ci fixed(8, ff_byte, 0xff); 302cabdff1aSopenharmony_ci tmp -= 255; 303cabdff1aSopenharmony_ci } 304cabdff1aSopenharmony_ci xu(8, last_payload_type_byte, tmp, 0, 254, 0); 305cabdff1aSopenharmony_ci 306cabdff1aSopenharmony_ci tmp = message->payload_size; 307cabdff1aSopenharmony_ci while (tmp >= 255) { 308cabdff1aSopenharmony_ci fixed(8, ff_byte, 0xff); 309cabdff1aSopenharmony_ci tmp -= 255; 310cabdff1aSopenharmony_ci } 311cabdff1aSopenharmony_ci xu(8, last_payload_size_byte, tmp, 0, 254, 0); 312cabdff1aSopenharmony_ci 313cabdff1aSopenharmony_ci err = FUNC(message)(ctx, rw, message); 314cabdff1aSopenharmony_ci ctx->trace_enable = trace; 315cabdff1aSopenharmony_ci if (err < 0) 316cabdff1aSopenharmony_ci return err; 317cabdff1aSopenharmony_ci } 318cabdff1aSopenharmony_ci } 319cabdff1aSopenharmony_ci#endif 320cabdff1aSopenharmony_ci 321cabdff1aSopenharmony_ci return 0; 322cabdff1aSopenharmony_ci} 323