| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 | 11 |
| 12 #include <stdlib.h> | 12 #include <stdlib.h> |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 #include "vpx/vpx_decoder.h" | 14 #include "vpx/vpx_decoder.h" |
| 15 #include "vpx/vp8dx.h" | 15 #include "vpx/vp8dx.h" |
| 16 #include "vpx/internal/vpx_codec_internal.h" | 16 #include "vpx/internal/vpx_codec_internal.h" |
| 17 #include "vpx_version.h" | 17 #include "vpx_version.h" |
| 18 #include "common/onyxd.h" | 18 #include "common/onyxd.h" |
| 19 #include "decoder/onyxd_int.h" | 19 #include "decoder/onyxd_int.h" |
| 20 | 20 |
| 21 #define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) | 21 #define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) |
| 22 #define VP8_CAP_ERROR_CONCEALMENT (CONFIG_ERROR_CONCEALMENT ? \ |
| 23 VPX_CODEC_CAP_ERROR_CONCEALMENT : 0) |
| 22 | 24 |
| 23 typedef vpx_codec_stream_info_t vp8_stream_info_t; | 25 typedef vpx_codec_stream_info_t vp8_stream_info_t; |
| 24 | 26 |
| 25 /* Structures for handling memory allocations */ | 27 /* Structures for handling memory allocations */ |
| 26 typedef enum | 28 typedef enum |
| 27 { | 29 { |
| 28 VP8_SEG_ALG_PRIV = 256, | 30 VP8_SEG_ALG_PRIV = 256, |
| 29 VP8_SEG_MAX | 31 VP8_SEG_MAX |
| 30 } mem_seg_id_t; | 32 } mem_seg_id_t; |
| 31 #define NELEMENTS(x) ((int)(sizeof(x)/sizeof(x[0]))) | 33 #define NELEMENTS(x) ((int)(sizeof(x)/sizeof(x[0]))) |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 vpx_codec_err_t res; | 294 vpx_codec_err_t res; |
| 293 | 295 |
| 294 if ((res = error->error_code)) | 296 if ((res = error->error_code)) |
| 295 ctx->base.err_detail = error->has_detail | 297 ctx->base.err_detail = error->has_detail |
| 296 ? error->detail | 298 ? error->detail |
| 297 : NULL; | 299 : NULL; |
| 298 | 300 |
| 299 return res; | 301 return res; |
| 300 } | 302 } |
| 301 | 303 |
| 304 static void yuvconfig2image(vpx_image_t *img, |
| 305 const YV12_BUFFER_CONFIG *yv12, |
| 306 void *user_priv) |
| 307 { |
| 308 /** vpx_img_wrap() doesn't allow specifying independent strides for |
| 309 * the Y, U, and V planes, nor other alignment adjustments that |
| 310 * might be representable by a YV12_BUFFER_CONFIG, so we just |
| 311 * initialize all the fields.*/ |
| 312 img->fmt = yv12->clrtype == REG_YUV ? |
| 313 VPX_IMG_FMT_I420 : VPX_IMG_FMT_VPXI420; |
| 314 img->w = yv12->y_stride; |
| 315 img->h = (yv12->y_height + 2 * VP8BORDERINPIXELS + 15) & ~15; |
| 316 img->d_w = yv12->y_width; |
| 317 img->d_h = yv12->y_height; |
| 318 img->x_chroma_shift = 1; |
| 319 img->y_chroma_shift = 1; |
| 320 img->planes[VPX_PLANE_Y] = yv12->y_buffer; |
| 321 img->planes[VPX_PLANE_U] = yv12->u_buffer; |
| 322 img->planes[VPX_PLANE_V] = yv12->v_buffer; |
| 323 img->planes[VPX_PLANE_ALPHA] = NULL; |
| 324 img->stride[VPX_PLANE_Y] = yv12->y_stride; |
| 325 img->stride[VPX_PLANE_U] = yv12->uv_stride; |
| 326 img->stride[VPX_PLANE_V] = yv12->uv_stride; |
| 327 img->stride[VPX_PLANE_ALPHA] = yv12->y_stride; |
| 328 img->bps = 12; |
| 329 img->user_priv = user_priv; |
| 330 img->img_data = yv12->buffer_alloc; |
| 331 img->img_data_owner = 0; |
| 332 img->self_allocd = 0; |
| 333 } |
| 302 | 334 |
| 303 static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, | 335 static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, |
| 304 const uint8_t *data, | 336 const uint8_t *data, |
| 305 unsigned int data_sz, | 337 unsigned int data_sz, |
| 306 void *user_priv, | 338 void *user_priv, |
| 307 long deadline) | 339 long deadline) |
| 308 { | 340 { |
| 309 vpx_codec_err_t res = VPX_CODEC_OK; | 341 vpx_codec_err_t res = VPX_CODEC_OK; |
| 310 | 342 |
| 311 ctx->img_avail = 0; | 343 ctx->img_avail = 0; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 VP8D_CONFIG oxcf; | 389 VP8D_CONFIG oxcf; |
| 358 VP8D_PTR optr; | 390 VP8D_PTR optr; |
| 359 | 391 |
| 360 vp8dx_initialize(); | 392 vp8dx_initialize(); |
| 361 | 393 |
| 362 oxcf.Width = ctx->si.w; | 394 oxcf.Width = ctx->si.w; |
| 363 oxcf.Height = ctx->si.h; | 395 oxcf.Height = ctx->si.h; |
| 364 oxcf.Version = 9; | 396 oxcf.Version = 9; |
| 365 oxcf.postprocess = 0; | 397 oxcf.postprocess = 0; |
| 366 oxcf.max_threads = ctx->cfg.threads; | 398 oxcf.max_threads = ctx->cfg.threads; |
| 399 oxcf.error_concealment = |
| 400 (ctx->base.init_flags & VPX_CODEC_USE_ERROR_CONCEALMENT); |
| 401 oxcf.input_partition = |
| 402 (ctx->base.init_flags & VPX_CODEC_USE_INPUT_PARTITION); |
| 367 | 403 |
| 368 optr = vp8dx_create_decompressor(&oxcf); | 404 optr = vp8dx_create_decompressor(&oxcf); |
| 369 | 405 |
| 370 /* If postprocessing was enabled by the application and a | 406 /* If postprocessing was enabled by the application and a |
| 371 * configuration has not been provided, default it. | 407 * configuration has not been provided, default it. |
| 372 */ | 408 */ |
| 373 if (!ctx->postproc_cfg_set | 409 if (!ctx->postproc_cfg_set |
| 374 && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) | 410 && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) |
| 375 { | 411 { |
| 376 ctx->postproc_cfg.post_proc_flag = | 412 ctx->postproc_cfg.post_proc_flag = |
| 377 VP8_DEBLOCK | VP8_DEMACROBLOCK; | 413 VP8_DEBLOCK | VP8_DEMACROBLOCK; |
| 378 ctx->postproc_cfg.deblocking_level = 4; | 414 ctx->postproc_cfg.deblocking_level = 4; |
| 379 ctx->postproc_cfg.noise_level = 0; | 415 ctx->postproc_cfg.noise_level = 0; |
| 380 } | 416 } |
| 381 | 417 |
| 382 if (!optr) | 418 if (!optr) |
| 383 res = VPX_CODEC_ERROR; | 419 res = VPX_CODEC_ERROR; |
| 384 else | 420 else |
| 385 ctx->pbi = optr; | 421 ctx->pbi = optr; |
| 386 } | 422 } |
| 387 | 423 |
| 388 ctx->decoder_init = 1; | 424 ctx->decoder_init = 1; |
| 389 } | 425 } |
| 390 | 426 |
| 391 if (!res && ctx->pbi) | 427 if (!res && ctx->pbi) |
| 392 { | 428 { |
| 393 YV12_BUFFER_CONFIG sd; | 429 YV12_BUFFER_CONFIG sd; |
| 394 INT64 time_stamp = 0, time_end_stamp = 0; | 430 int64_t time_stamp = 0, time_end_stamp = 0; |
| 395 vp8_ppflags_t flags = {0}; | 431 vp8_ppflags_t flags = {0}; |
| 396 | 432 |
| 397 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) | 433 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) |
| 398 { | 434 { |
| 399 flags.post_proc_flag= ctx->postproc_cfg.post_proc_flag | 435 flags.post_proc_flag= ctx->postproc_cfg.post_proc_flag |
| 400 #if CONFIG_POSTPROC_VISUALIZER | 436 #if CONFIG_POSTPROC_VISUALIZER |
| 401 | 437 |
| 402 | ((ctx->dbg_color_ref_frame_flag != 0) ? VP8D_D
EBUG_CLR_FRM_REF_BLKS : 0) | 438 | ((ctx->dbg_color_ref_frame_flag != 0) ? VP8D_D
EBUG_CLR_FRM_REF_BLKS : 0) |
| 403 | ((ctx->dbg_color_mb_modes_flag != 0) ? VP8D_DE
BUG_CLR_BLK_MODES : 0) | 439 | ((ctx->dbg_color_mb_modes_flag != 0) ? VP8D_DE
BUG_CLR_BLK_MODES : 0) |
| 404 | ((ctx->dbg_color_b_modes_flag != 0) ? VP8D_DEB
UG_CLR_BLK_MODES : 0) | 440 | ((ctx->dbg_color_b_modes_flag != 0) ? VP8D_DEB
UG_CLR_BLK_MODES : 0) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 416 } | 452 } |
| 417 | 453 |
| 418 if (vp8dx_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) | 454 if (vp8dx_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) |
| 419 { | 455 { |
| 420 VP8D_COMP *pbi = (VP8D_COMP *)ctx->pbi; | 456 VP8D_COMP *pbi = (VP8D_COMP *)ctx->pbi; |
| 421 res = update_error_state(ctx, &pbi->common.error); | 457 res = update_error_state(ctx, &pbi->common.error); |
| 422 } | 458 } |
| 423 | 459 |
| 424 if (!res && 0 == vp8dx_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_e
nd_stamp, &flags)) | 460 if (!res && 0 == vp8dx_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_e
nd_stamp, &flags)) |
| 425 { | 461 { |
| 426 /* Align width/height */ | 462 yuvconfig2image(&ctx->img, &sd, user_priv); |
| 427 unsigned int a_w = (sd.y_width + 15) & ~15; | |
| 428 unsigned int a_h = (sd.y_height + 15) & ~15; | |
| 429 | |
| 430 vpx_img_wrap(&ctx->img, VPX_IMG_FMT_I420, | |
| 431 a_w + 2 * VP8BORDERINPIXELS, | |
| 432 a_h + 2 * VP8BORDERINPIXELS, | |
| 433 1, | |
| 434 sd.buffer_alloc); | |
| 435 vpx_img_set_rect(&ctx->img, | |
| 436 VP8BORDERINPIXELS, VP8BORDERINPIXELS, | |
| 437 sd.y_width, sd.y_height); | |
| 438 ctx->img.user_priv = user_priv; | |
| 439 ctx->img_avail = 1; | 463 ctx->img_avail = 1; |
| 440 | |
| 441 } | 464 } |
| 442 } | 465 } |
| 443 | 466 |
| 444 return res; | 467 return res; |
| 445 } | 468 } |
| 446 | 469 |
| 447 static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t *ctx, | 470 static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t *ctx, |
| 448 vpx_codec_iter_t *iter) | 471 vpx_codec_iter_t *iter) |
| 449 { | 472 { |
| 450 vpx_image_t *img = NULL; | 473 vpx_image_t *img = NULL; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 | 600 |
| 578 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); | 601 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); |
| 579 | 602 |
| 580 if (data) | 603 if (data) |
| 581 { | 604 { |
| 582 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; | 605 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; |
| 583 YV12_BUFFER_CONFIG sd; | 606 YV12_BUFFER_CONFIG sd; |
| 584 | 607 |
| 585 image2yuvconfig(&frame->img, &sd); | 608 image2yuvconfig(&frame->img, &sd); |
| 586 | 609 |
| 587 vp8dx_set_reference(ctx->pbi, frame->frame_type, &sd); | 610 return vp8dx_set_reference(ctx->pbi, frame->frame_type, &sd); |
| 588 return VPX_CODEC_OK; | |
| 589 } | 611 } |
| 590 else | 612 else |
| 591 return VPX_CODEC_INVALID_PARAM; | 613 return VPX_CODEC_INVALID_PARAM; |
| 592 | 614 |
| 593 } | 615 } |
| 594 | 616 |
| 595 static vpx_codec_err_t vp8_get_reference(vpx_codec_alg_priv_t *ctx, | 617 static vpx_codec_err_t vp8_get_reference(vpx_codec_alg_priv_t *ctx, |
| 596 int ctr_id, | 618 int ctr_id, |
| 597 va_list args) | 619 va_list args) |
| 598 { | 620 { |
| 599 | 621 |
| 600 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); | 622 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); |
| 601 | 623 |
| 602 if (data) | 624 if (data) |
| 603 { | 625 { |
| 604 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; | 626 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; |
| 605 YV12_BUFFER_CONFIG sd; | 627 YV12_BUFFER_CONFIG sd; |
| 606 | 628 |
| 607 image2yuvconfig(&frame->img, &sd); | 629 image2yuvconfig(&frame->img, &sd); |
| 608 | 630 |
| 609 vp8dx_get_reference(ctx->pbi, frame->frame_type, &sd); | 631 return vp8dx_get_reference(ctx->pbi, frame->frame_type, &sd); |
| 610 return VPX_CODEC_OK; | |
| 611 } | 632 } |
| 612 else | 633 else |
| 613 return VPX_CODEC_INVALID_PARAM; | 634 return VPX_CODEC_INVALID_PARAM; |
| 614 | 635 |
| 615 } | 636 } |
| 616 | 637 |
| 617 static vpx_codec_err_t vp8_set_postproc(vpx_codec_alg_priv_t *ctx, | 638 static vpx_codec_err_t vp8_set_postproc(vpx_codec_alg_priv_t *ctx, |
| 618 int ctr_id, | 639 int ctr_id, |
| 619 va_list args) | 640 va_list args) |
| 620 { | 641 { |
| 642 #if CONFIG_POSTPROC |
| 621 vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *); | 643 vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *); |
| 622 #if CONFIG_POSTPROC | |
| 623 | 644 |
| 624 if (data) | 645 if (data) |
| 625 { | 646 { |
| 626 ctx->postproc_cfg_set = 1; | 647 ctx->postproc_cfg_set = 1; |
| 627 ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data); | 648 ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data); |
| 628 return VPX_CODEC_OK; | 649 return VPX_CODEC_OK; |
| 629 } | 650 } |
| 630 else | 651 else |
| 631 return VPX_CODEC_INVALID_PARAM; | 652 return VPX_CODEC_INVALID_PARAM; |
| 632 | 653 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 }; | 733 }; |
| 713 | 734 |
| 714 | 735 |
| 715 #ifndef VERSION_STRING | 736 #ifndef VERSION_STRING |
| 716 #define VERSION_STRING | 737 #define VERSION_STRING |
| 717 #endif | 738 #endif |
| 718 CODEC_INTERFACE(vpx_codec_vp8_dx) = | 739 CODEC_INTERFACE(vpx_codec_vp8_dx) = |
| 719 { | 740 { |
| 720 "WebM Project VP8 Decoder" VERSION_STRING, | 741 "WebM Project VP8 Decoder" VERSION_STRING, |
| 721 VPX_CODEC_INTERNAL_ABI_VERSION, | 742 VPX_CODEC_INTERNAL_ABI_VERSION, |
| 722 VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC, | 743 VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT | |
| 744 VPX_CODEC_CAP_INPUT_PARTITION, |
| 723 /* vpx_codec_caps_t caps; */ | 745 /* vpx_codec_caps_t caps; */ |
| 724 vp8_init, /* vpx_codec_init_fn_t init; */ | 746 vp8_init, /* vpx_codec_init_fn_t init; */ |
| 725 vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */ | 747 vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */ |
| 726 vp8_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ | 748 vp8_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ |
| 727 vp8_xma_get_mmap, /* vpx_codec_get_mmap_fn_t get_mmap; */ | 749 vp8_xma_get_mmap, /* vpx_codec_get_mmap_fn_t get_mmap; */ |
| 728 vp8_xma_set_mmap, /* vpx_codec_set_mmap_fn_t set_mmap; */ | 750 vp8_xma_set_mmap, /* vpx_codec_set_mmap_fn_t set_mmap; */ |
| 729 { | 751 { |
| 730 vp8_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */ | 752 vp8_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */ |
| 731 vp8_get_si, /* vpx_codec_get_si_fn_t get_si; */ | 753 vp8_get_si, /* vpx_codec_get_si_fn_t get_si; */ |
| 732 vp8_decode, /* vpx_codec_decode_fn_t decode; */ | 754 vp8_decode, /* vpx_codec_decode_fn_t decode; */ |
| 733 vp8_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */ | 755 vp8_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */ |
| 734 }, | 756 }, |
| 735 { /* encoder functions */ | 757 { /* encoder functions */ |
| 736 NOT_IMPLEMENTED, | 758 NOT_IMPLEMENTED, |
| 737 NOT_IMPLEMENTED, | 759 NOT_IMPLEMENTED, |
| 738 NOT_IMPLEMENTED, | 760 NOT_IMPLEMENTED, |
| 739 NOT_IMPLEMENTED, | 761 NOT_IMPLEMENTED, |
| 740 NOT_IMPLEMENTED, | 762 NOT_IMPLEMENTED, |
| 741 NOT_IMPLEMENTED | 763 NOT_IMPLEMENTED |
| 742 } | 764 } |
| 743 }; | 765 }; |
| 744 | 766 |
| 745 /* | 767 /* |
| 746 * BEGIN BACKWARDS COMPATIBILITY SHIM. | 768 * BEGIN BACKWARDS COMPATIBILITY SHIM. |
| 747 */ | 769 */ |
| 748 vpx_codec_iface_t vpx_codec_vp8_algo = | 770 vpx_codec_iface_t vpx_codec_vp8_algo = |
| 749 { | 771 { |
| 750 "WebM Project VP8 Decoder (Deprecated API)" VERSION_STRING, | 772 "WebM Project VP8 Decoder (Deprecated API)" VERSION_STRING, |
| 751 VPX_CODEC_INTERNAL_ABI_VERSION, | 773 VPX_CODEC_INTERNAL_ABI_VERSION, |
| 752 VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC, | 774 VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT, |
| 753 /* vpx_codec_caps_t caps; */ | 775 /* vpx_codec_caps_t caps; */ |
| 754 vp8_init, /* vpx_codec_init_fn_t init; */ | 776 vp8_init, /* vpx_codec_init_fn_t init; */ |
| 755 vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */ | 777 vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */ |
| 756 vp8_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ | 778 vp8_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ |
| 757 vp8_xma_get_mmap, /* vpx_codec_get_mmap_fn_t get_mmap; */ | 779 vp8_xma_get_mmap, /* vpx_codec_get_mmap_fn_t get_mmap; */ |
| 758 vp8_xma_set_mmap, /* vpx_codec_set_mmap_fn_t set_mmap; */ | 780 vp8_xma_set_mmap, /* vpx_codec_set_mmap_fn_t set_mmap; */ |
| 759 { | 781 { |
| 760 vp8_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */ | 782 vp8_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */ |
| 761 vp8_get_si, /* vpx_codec_get_si_fn_t get_si; */ | 783 vp8_get_si, /* vpx_codec_get_si_fn_t get_si; */ |
| 762 vp8_decode, /* vpx_codec_decode_fn_t decode; */ | 784 vp8_decode, /* vpx_codec_decode_fn_t decode; */ |
| 763 vp8_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */ | 785 vp8_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */ |
| 764 }, | 786 }, |
| 765 { /* encoder functions */ | 787 { /* encoder functions */ |
| 766 NOT_IMPLEMENTED, | 788 NOT_IMPLEMENTED, |
| 767 NOT_IMPLEMENTED, | 789 NOT_IMPLEMENTED, |
| 768 NOT_IMPLEMENTED, | 790 NOT_IMPLEMENTED, |
| 769 NOT_IMPLEMENTED, | 791 NOT_IMPLEMENTED, |
| 770 NOT_IMPLEMENTED, | 792 NOT_IMPLEMENTED, |
| 771 NOT_IMPLEMENTED | 793 NOT_IMPLEMENTED |
| 772 } | 794 } |
| 773 }; | 795 }; |
| OLD | NEW |