1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <media/v4l2-event.h> 7 #include <media/v4l2-mem2mem.h> 8 9 #include "iris_buffer.h" 10 #include "iris_common.h" 11 #include "iris_ctrls.h" 12 #include "iris_instance.h" 13 #include "iris_power.h" 14 #include "iris_vdec.h" 15 #include "iris_vpu_buffer.h" 16 17 #define DEFAULT_CODEC_ALIGNMENT 16 18 19 int iris_vdec_inst_init(struct iris_inst *inst) 20 { 21 struct iris_core *core = inst->core; 22 struct v4l2_format *f; 23 24 inst->fmt_src = kzalloc_obj(*inst->fmt_src); 25 inst->fmt_dst = kzalloc_obj(*inst->fmt_dst); 26 27 inst->fw_min_count = 0; 28 29 f = inst->fmt_src; 30 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 31 f->fmt.pix_mp.width = DEFAULT_WIDTH; 32 f->fmt.pix_mp.height = DEFAULT_HEIGHT; 33 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; 34 inst->codec = f->fmt.pix_mp.pixelformat; 35 f->fmt.pix_mp.num_planes = 1; 36 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 37 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 38 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 39 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 40 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 41 42 f = inst->fmt_dst; 43 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 44 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 45 f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128); 46 f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32); 47 f->fmt.pix_mp.num_planes = 1; 48 f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128); 49 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 50 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 51 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 52 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 53 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 54 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 55 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 56 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 57 inst->frame_rate = MAXIMUM_FPS; 58 59 memcpy(&inst->fw_caps[0], &core->inst_fw_caps_dec[0], 60 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap)); 61 62 return iris_ctrls_init(inst); 63 } 64 65 static const u32 iris_vdec_formats_cap[] = { 66 [IRIS_FMT_NV12] = V4L2_PIX_FMT_NV12, 67 [IRIS_FMT_QC08C] = V4L2_PIX_FMT_QC08C, 68 [IRIS_FMT_TP10] = V4L2_PIX_FMT_P010, 69 [IRIS_FMT_QC10C] = V4L2_PIX_FMT_QC10C, 70 }; 71 72 static bool check_format(struct iris_inst *inst, u32 pixfmt, u32 type) 73 { 74 unsigned int size, i; 75 const u32 *fmt; 76 77 switch (type) { 78 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 79 fmt = inst->core->iris_platform_data->inst_iris_fmts; 80 size = inst->core->iris_platform_data->inst_iris_fmts_size; 81 break; 82 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 83 fmt = iris_vdec_formats_cap; 84 size = ARRAY_SIZE(iris_vdec_formats_cap); 85 break; 86 default: 87 return false; 88 } 89 90 for (i = 0; i < size; i++) { 91 if (fmt[i] == pixfmt) 92 break; 93 } 94 95 if (i == size) 96 return false; 97 98 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 99 if (iris_fmt_is_8bit(pixfmt) && 100 inst->fw_caps[BIT_DEPTH].value == BIT_DEPTH_10) 101 return false; 102 103 if (iris_fmt_is_10bit(pixfmt) && 104 inst->fw_caps[BIT_DEPTH].value != BIT_DEPTH_10) 105 return false; 106 } 107 108 return true; 109 } 110 111 static u32 find_format_by_index(struct iris_inst *inst, u32 index, u32 type) 112 { 113 unsigned int size; 114 const u32 *fmt; 115 116 switch (type) { 117 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 118 fmt = inst->core->iris_platform_data->inst_iris_fmts; 119 size = inst->core->iris_platform_data->inst_iris_fmts_size; 120 break; 121 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 122 fmt = iris_vdec_formats_cap; 123 size = ARRAY_SIZE(iris_vdec_formats_cap); 124 break; 125 default: 126 return 0; 127 } 128 129 if (index >= size) 130 return 0; 131 132 return fmt[index]; 133 } 134 135 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) 136 { 137 u32 fmt; 138 139 switch (f->type) { 140 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 141 fmt = find_format_by_index(inst, f->index, f->type); 142 if (!fmt) 143 return -EINVAL; 144 145 f->pixelformat = fmt; 146 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION; 147 break; 148 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 149 fmt = find_format_by_index(inst, f->index, f->type); 150 if (!fmt) 151 return -EINVAL; 152 f->pixelformat = fmt; 153 break; 154 default: 155 return -EINVAL; 156 } 157 158 return 0; 159 } 160 161 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) 162 { 163 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 164 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 165 struct v4l2_format *f_inst; 166 struct vb2_queue *src_q; 167 bool supported; 168 169 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 170 supported = check_format(inst, pixmp->pixelformat, f->type); 171 switch (f->type) { 172 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 173 if (!supported) { 174 f_inst = inst->fmt_src; 175 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 176 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 177 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 178 } 179 break; 180 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 181 if (!supported) { 182 f_inst = inst->fmt_dst; 183 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 184 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 185 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 186 } 187 188 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 189 if (vb2_is_streaming(src_q)) { 190 f_inst = inst->fmt_src; 191 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 192 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 193 } 194 break; 195 default: 196 return -EINVAL; 197 } 198 199 if (pixmp->field == V4L2_FIELD_ANY) 200 pixmp->field = V4L2_FIELD_NONE; 201 202 pixmp->num_planes = 1; 203 204 return 0; 205 } 206 207 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) 208 { 209 struct v4l2_format *fmt, *output_fmt; 210 struct vb2_queue *q; 211 u32 codec_align; 212 213 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); 214 215 if (vb2_is_busy(q)) 216 return -EBUSY; 217 218 /* Width and height are optional, so fall back to a valid placeholder 219 * resolution until the real one is decoded from the bitstream. 220 */ 221 if (f->fmt.pix_mp.width == 0 && f->fmt.pix_mp.height == 0) { 222 f->fmt.pix_mp.width = DEFAULT_WIDTH; 223 f->fmt.pix_mp.height = DEFAULT_HEIGHT; 224 } 225 226 iris_vdec_try_fmt(inst, f); 227 228 switch (f->type) { 229 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 230 if (!check_format(inst, f->fmt.pix_mp.pixelformat, f->type)) 231 return -EINVAL; 232 233 fmt = inst->fmt_src; 234 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 235 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 236 inst->codec = fmt->fmt.pix_mp.pixelformat; 237 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 238 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); 239 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); 240 fmt->fmt.pix_mp.num_planes = 1; 241 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 242 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 243 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 244 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 245 246 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 247 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 248 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 249 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 250 251 output_fmt = inst->fmt_dst; 252 output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 253 output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 254 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 255 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 256 257 /* Update capture format based on new ip w/h */ 258 output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 259 output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 260 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 261 inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT); 262 263 inst->crop.left = 0; 264 inst->crop.top = 0; 265 inst->crop.width = f->fmt.pix_mp.width; 266 inst->crop.height = f->fmt.pix_mp.height; 267 break; 268 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 269 if (!check_format(inst, f->fmt.pix_mp.pixelformat, f->type)) 270 return -EINVAL; 271 272 fmt = inst->fmt_dst; 273 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 274 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 275 fmt->fmt.pix_mp.num_planes = 1; 276 switch (f->fmt.pix_mp.pixelformat) { 277 case V4L2_PIX_FMT_P010: 278 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 279 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 280 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 281 ALIGN(f->fmt.pix_mp.width * 2, 256); 282 break; 283 case V4L2_PIX_FMT_QC10C: 284 fmt->fmt.pix_mp.width = roundup(f->fmt.pix_mp.width, 192); 285 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16); 286 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 287 ALIGN(f->fmt.pix_mp.width * 4 / 3, 256); 288 break; 289 case V4L2_PIX_FMT_NV12: 290 case V4L2_PIX_FMT_QC08C: 291 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 292 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 293 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 294 ALIGN(f->fmt.pix_mp.width, 128); 295 break; 296 } 297 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 298 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 299 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 300 301 inst->crop.top = 0; 302 inst->crop.left = 0; 303 inst->crop.width = f->fmt.pix_mp.width; 304 inst->crop.height = f->fmt.pix_mp.height; 305 break; 306 default: 307 return -EINVAL; 308 } 309 memcpy(f, fmt, sizeof(*fmt)); 310 311 return 0; 312 } 313 314 int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat) 315 { 316 bool supported; 317 318 supported = check_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 319 if (!supported) 320 supported = check_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 321 322 return supported ? 0 : -EINVAL; 323 } 324 325 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub) 326 { 327 int ret = 0; 328 329 switch (sub->type) { 330 case V4L2_EVENT_EOS: 331 ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL); 332 break; 333 case V4L2_EVENT_SOURCE_CHANGE: 334 ret = v4l2_src_change_event_subscribe(&inst->fh, sub); 335 break; 336 case V4L2_EVENT_CTRL: 337 ret = v4l2_ctrl_subscribe_event(&inst->fh, sub); 338 break; 339 default: 340 return -EINVAL; 341 } 342 343 return ret; 344 } 345 346 void iris_vdec_src_change(struct iris_inst *inst) 347 { 348 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 349 struct v4l2_event event = {0}; 350 struct vb2_queue *src_q; 351 352 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 353 if (!vb2_is_streaming(src_q)) 354 return; 355 356 event.type = V4L2_EVENT_SOURCE_CHANGE; 357 event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION; 358 v4l2_event_queue_fh(&inst->fh, &event); 359 } 360 361 int iris_vdec_streamon_input(struct iris_inst *inst) 362 { 363 int ret; 364 365 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 366 if (ret) 367 return ret; 368 369 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_PERSIST); 370 if (ret) 371 return ret; 372 373 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 374 375 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 376 if (ret) 377 return ret; 378 379 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 380 if (ret) 381 return ret; 382 383 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 384 if (ret) 385 return ret; 386 387 inst->frame_counter = 0; 388 389 return iris_process_streamon_input(inst); 390 } 391 392 int iris_vdec_streamon_output(struct iris_inst *inst) 393 { 394 const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; 395 int ret; 396 397 ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 398 if (ret) 399 return ret; 400 401 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 402 403 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 404 if (ret) 405 return ret; 406 407 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 408 if (ret) 409 return ret; 410 411 ret = iris_process_streamon_output(inst); 412 if (ret) 413 goto error; 414 415 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 416 if (ret) 417 goto error; 418 419 return ret; 420 421 error: 422 iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 423 424 return ret; 425 } 426 427 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) 428 { 429 struct iris_buffer *buf = to_iris_buffer(vbuf); 430 struct vb2_buffer *vb2 = &vbuf->vb2_buf; 431 u64 cur_buf_ns, delta_ns; 432 struct vb2_queue *q; 433 int ret; 434 435 ret = iris_vb2_buffer_to_driver(vb2, buf); 436 if (ret) 437 return ret; 438 439 if (buf->type == BUF_INPUT) 440 iris_set_ts_metadata(inst, vbuf); 441 442 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type); 443 if (!vb2_is_streaming(q)) { 444 buf->attr |= BUF_ATTR_DEFERRED; 445 return 0; 446 } 447 448 if (buf->type == BUF_INPUT) { 449 cur_buf_ns = ktime_get_ns(); 450 451 if (!inst->frame_counter) 452 inst->last_buf_ns = cur_buf_ns; 453 454 inst->frame_counter++; 455 delta_ns = cur_buf_ns - inst->last_buf_ns; 456 457 if (delta_ns >= NSEC_PER_SEC) { 458 inst->frame_rate = clamp_t(u32, inst->frame_counter, DEFAULT_FPS, 459 MAXIMUM_FPS); 460 inst->frame_counter = 0; 461 } 462 } 463 464 iris_scale_power(inst); 465 466 return iris_queue_buffer(inst, buf); 467 } 468 469 int iris_vdec_start_cmd(struct iris_inst *inst) 470 { 471 const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; 472 enum iris_inst_sub_state clear_sub_state = 0; 473 struct vb2_queue *dst_vq; 474 int ret; 475 476 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 477 478 if (inst->sub_state & IRIS_INST_SUB_DRC && 479 inst->sub_state & IRIS_INST_SUB_DRC_LAST) { 480 vb2_clear_last_buffer_dequeued(dst_vq); 481 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 482 483 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 484 ret = hfi_ops->session_resume_drc(inst, 485 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 486 if (ret) 487 return ret; 488 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 489 } 490 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 491 ret = hfi_ops->session_resume_drc(inst, 492 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 493 if (ret) 494 return ret; 495 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 496 } 497 } else if (inst->sub_state & IRIS_INST_SUB_DRAIN && 498 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) { 499 vb2_clear_last_buffer_dequeued(dst_vq); 500 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 501 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 502 if (hfi_ops->session_resume_drain) { 503 ret = 504 hfi_ops->session_resume_drain(inst, 505 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 506 if (ret) 507 return ret; 508 } 509 510 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 511 } 512 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 513 if (hfi_ops->session_resume_drain) { 514 ret = 515 hfi_ops->session_resume_drain(inst, 516 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 517 if (ret) 518 return ret; 519 } 520 521 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 522 } 523 } else { 524 dev_err(inst->core->dev, "start called before receiving last_flag\n"); 525 iris_inst_change_state(inst, IRIS_INST_ERROR); 526 return -EBUSY; 527 } 528 529 return iris_inst_change_sub_state(inst, clear_sub_state, 0); 530 } 531 532 int iris_vdec_stop_cmd(struct iris_inst *inst) 533 { 534 const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; 535 int ret; 536 537 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 538 if (ret) 539 return ret; 540 541 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN); 542 } 543